/* netmap_pipe_krings_delete. * * There are two cases: * * 1) state is * * usr1 --> e1 --> e2 * * and we are e1 (e2 is not registered, so krings_delete cannot be * called on it); * * 2) state is * * usr1 --> e1 e2 <-- usr2 * * and we are either e1 or e2. * * In the former case we have to also delete the krings of e2; * in the latter case we do nothing (note that our krings * have already been hidden in the unregister callback). */ static void netmap_pipe_krings_delete(struct netmap_adapter *na) { struct netmap_pipe_adapter *pna = (struct netmap_pipe_adapter *)na; struct netmap_adapter *ona; /* na of the other end */ int i; if (!pna->peer_ref) { ND("%p: case 2, kept alive by peer", na); return; } /* case 1) above */ ND("%p: case 1, deleting everyhing", na); netmap_krings_delete(na); /* also zeroes tx_rings etc. */ /* restore the ring to be deleted on the peer */ ona = &pna->peer->up; if (ona->tx_rings == NULL) { /* already deleted, we must be on an * cleanup-after-error path */ return; } for (i = 0; i < ona->num_tx_rings + 1; i++) ona->tx_rings[i].ring = ona->tx_rings[i].save_ring; for (i = 0; i < ona->num_rx_rings + 1; i++) ona->rx_rings[i].ring = ona->rx_rings[i].save_ring; netmap_mem_rings_delete(ona); netmap_krings_delete(ona); }
/* nm_krings_delete callback for monitors */ static void netmap_monitor_krings_delete(struct netmap_adapter *na) { netmap_krings_delete(na); }
/* netmap_pipe_krings_delete. * * There are two cases: * * 1) state is * * usr1 --> e1 --> e2 * * and we are e1. We have to create both sets * of krings. * * 2) state is * * usr1 --> e1 --> e2 * * and we are e2. e1 is certainly registered and our * krings already exist, but they may be hidden. */ static int netmap_pipe_krings_create(struct netmap_adapter *na) { struct netmap_pipe_adapter *pna = (struct netmap_pipe_adapter *)na; struct netmap_adapter *ona = &pna->peer->up; int error = 0; if (pna->peer_ref) { int i; /* case 1) above */ D("%p: case 1, create everything", na); error = netmap_krings_create(na, 0); if (error) goto err; /* we also create all the rings, since we need to * update the save_ring pointers. * netmap_mem_rings_create (called by our caller) * will not create the rings again */ error = netmap_mem_rings_create(na); if (error) goto del_krings1; /* update our hidden ring pointers */ for (i = 0; i < na->num_tx_rings + 1; i++) na->tx_rings[i].save_ring = na->tx_rings[i].ring; for (i = 0; i < na->num_rx_rings + 1; i++) na->rx_rings[i].save_ring = na->rx_rings[i].ring; /* now, create krings and rings of the other end */ error = netmap_krings_create(ona, 0); if (error) goto del_rings1; error = netmap_mem_rings_create(ona); if (error) goto del_krings2; for (i = 0; i < ona->num_tx_rings + 1; i++) ona->tx_rings[i].save_ring = ona->tx_rings[i].ring; for (i = 0; i < ona->num_rx_rings + 1; i++) ona->rx_rings[i].save_ring = ona->rx_rings[i].ring; /* cross link the krings */ for (i = 0; i < na->num_tx_rings; i++) { na->tx_rings[i].pipe = pna->peer->up.rx_rings + i; na->rx_rings[i].pipe = pna->peer->up.tx_rings + i; pna->peer->up.tx_rings[i].pipe = na->rx_rings + i; pna->peer->up.rx_rings[i].pipe = na->tx_rings + i; } } else { int i; /* case 2) above */ /* recover the hidden rings */ ND("%p: case 2, hidden rings", na); for (i = 0; i < na->num_tx_rings + 1; i++) na->tx_rings[i].ring = na->tx_rings[i].save_ring; for (i = 0; i < na->num_rx_rings + 1; i++) na->rx_rings[i].ring = na->rx_rings[i].save_ring; } return 0; del_krings2: netmap_krings_delete(ona); del_rings1: netmap_mem_rings_delete(na); del_krings1: netmap_krings_delete(na); err: return error; }