diff options
| author | Luigi Rizzo <luigi@FreeBSD.org> | 2015-07-10 05:51:36 +0000 |
|---|---|---|
| committer | Luigi Rizzo <luigi@FreeBSD.org> | 2015-07-10 05:51:36 +0000 |
| commit | 847bf38369b6ea5abf8b6409006468cfe4f66d5e (patch) | |
| tree | 2a938ad28f8fa79c60e58c3430a4c2c93631db94 /sys/dev/netmap/netmap_pipe.c | |
| parent | 9d73ee0f82b756db5e53a32e55766db958d41dba (diff) | |
Notes
Diffstat (limited to 'sys/dev/netmap/netmap_pipe.c')
| -rw-r--r-- | sys/dev/netmap/netmap_pipe.c | 135 |
1 files changed, 62 insertions, 73 deletions
diff --git a/sys/dev/netmap/netmap_pipe.c b/sys/dev/netmap/netmap_pipe.c index 64828670c35bd..3fe29bb2ff9c6 100644 --- a/sys/dev/netmap/netmap_pipe.c +++ b/sys/dev/netmap/netmap_pipe.c @@ -72,51 +72,31 @@ #define NM_PIPE_MAXSLOTS 4096 -int netmap_default_pipes = 0; /* default number of pipes for each nic */ +int netmap_default_pipes = 0; /* ignored, kept for compatibility */ SYSCTL_DECL(_dev_netmap); SYSCTL_INT(_dev_netmap, OID_AUTO, default_pipes, CTLFLAG_RW, &netmap_default_pipes, 0 , ""); /* allocate the pipe array in the parent adapter */ -int -netmap_pipe_alloc(struct netmap_adapter *na, struct nmreq *nmr) +static int +nm_pipe_alloc(struct netmap_adapter *na, u_int npipes) { size_t len; - int mode = nmr->nr_flags & NR_REG_MASK; - u_int npipes; + struct netmap_pipe_adapter **npa; - if (mode == NR_REG_PIPE_MASTER || mode == NR_REG_PIPE_SLAVE) { - /* this is for our parent, not for us */ + if (npipes <= na->na_max_pipes) + /* we already have more entries that requested */ return 0; - } - - /* TODO: we can resize the array if the new - * request can accomodate the already existing pipes - */ - if (na->na_pipes) { - nmr->nr_arg1 = na->na_max_pipes; - return 0; - } - - npipes = nmr->nr_arg1; - if (npipes == 0) - npipes = netmap_default_pipes; - nm_bound_var(&npipes, 0, 0, NM_MAXPIPES, NULL); - - if (npipes == 0) { - /* really zero, nothing to alloc */ - goto out; - } + + if (npipes < na->na_next_pipe || npipes > NM_MAXPIPES) + return EINVAL; - len = sizeof(struct netmap_pipe_adapter *) * npipes; - na->na_pipes = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); - if (na->na_pipes == NULL) + len = sizeof(struct netmap_pipe_adapter *) * npipes; + npa = realloc(na->na_pipes, len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (npa == NULL) return ENOMEM; + na->na_pipes = npa; na->na_max_pipes = npipes; - na->na_next_pipe = 0; - -out: - nmr->nr_arg1 = npipes; return 0; } @@ -126,7 +106,10 @@ void netmap_pipe_dealloc(struct netmap_adapter *na) { if (na->na_pipes) { - ND("freeing pipes for %s", na->name); + if (na->na_next_pipe > 0) { + D("freeing not empty pipe array for %s (%d dangling pipes)!", na->name, + na->na_next_pipe); + } free(na->na_pipes, M_DEVBUF); na->na_pipes = NULL; na->na_max_pipes = 0; @@ -155,8 +138,10 @@ static int netmap_pipe_add(struct netmap_adapter *parent, struct netmap_pipe_adapter *na) { if (parent->na_next_pipe >= parent->na_max_pipes) { - D("%s: no space left for pipes", parent->name); - return ENOMEM; + u_int npipes = parent->na_max_pipes ? 2*parent->na_max_pipes : 2; + int error = nm_pipe_alloc(parent, npipes); + if (error) + return error; } parent->na_pipes[parent->na_next_pipe] = na; @@ -172,8 +157,10 @@ netmap_pipe_remove(struct netmap_adapter *parent, struct netmap_pipe_adapter *na u_int n; n = --parent->na_next_pipe; if (n != na->parent_slot) { - parent->na_pipes[na->parent_slot] = - parent->na_pipes[n]; + struct netmap_pipe_adapter **p = + &parent->na_pipes[na->parent_slot]; + *p = parent->na_pipes[n]; + (*p)->parent_slot = na->parent_slot; } parent->na_pipes[n] = NULL; } @@ -208,7 +195,6 @@ netmap_pipe_txsync(struct netmap_kring *txkring, int flags) if (limit == 0) { /* either the rxring is full, or nothing to send */ - nm_txsync_finalize(txkring); /* actually useless */ return 0; } @@ -222,7 +208,9 @@ netmap_pipe_txsync(struct netmap_kring *txkring, int flags) *rs = *ts; *ts = tmp; - /* no need to report the buffer change */ + /* report the buffer change */ + ts->flags |= NS_BUF_CHANGED; + rs->flags |= NS_BUF_CHANGED; j = nm_next(j, lim_rx); k = nm_next(k, lim_tx); @@ -233,12 +221,11 @@ netmap_pipe_txsync(struct netmap_kring *txkring, int flags) txkring->nr_hwcur = k; txkring->nr_hwtail = nm_prev(k, lim_tx); - nm_txsync_finalize(txkring); ND(2, "after: hwcur %d hwtail %d cur %d head %d tail %d j %d", txkring->nr_hwcur, txkring->nr_hwtail, txkring->rcur, txkring->rhead, txkring->rtail, j); mb(); /* make sure rxkring->nr_hwtail is updated before notifying */ - rxkring->na->nm_notify(rxkring->na, rxkring->ring_id, NR_RX, 0); + rxkring->nm_notify(rxkring, 0); return 0; } @@ -254,12 +241,11 @@ netmap_pipe_rxsync(struct netmap_kring *rxkring, int flags) ND(5, "hwcur %d hwtail %d cur %d head %d tail %d", rxkring->nr_hwcur, rxkring->nr_hwtail, rxkring->rcur, rxkring->rhead, rxkring->rtail); mb(); /* paired with the first mb() in txsync */ - nm_rxsync_finalize(rxkring); if (oldhwcur != rxkring->nr_hwcur) { /* we have released some slots, notify the other end */ mb(); /* make sure nr_hwcur is updated before notifying */ - txkring->na->nm_notify(txkring->na, txkring->ring_id, NR_TX, 0); + txkring->nm_notify(txkring, 0); } return 0; } @@ -318,11 +304,13 @@ netmap_pipe_krings_create(struct netmap_adapter *na) (struct netmap_pipe_adapter *)na; struct netmap_adapter *ona = &pna->peer->up; int error = 0; + enum txrx t; + if (pna->peer_ref) { int i; /* case 1) above */ - D("%p: case 1, create everything", na); + ND("%p: case 1, create everything", na); error = netmap_krings_create(na, 0); if (error) goto err; @@ -338,10 +326,10 @@ netmap_pipe_krings_create(struct netmap_adapter *na) 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; + for_rx_tx(t) { + for (i = 0; i < nma_get_nrings(na, t) + 1; i++) + NMR(na, t)[i].save_ring = NMR(na, t)[i].ring; + } /* now, create krings and rings of the other end */ error = netmap_krings_create(ona, 0); @@ -352,27 +340,28 @@ netmap_pipe_krings_create(struct netmap_adapter *na) 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; + for_rx_tx(t) { + for (i = 0; i < nma_get_nrings(ona, t) + 1; i++) + NMR(ona, t)[i].save_ring = NMR(ona, t)[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; + for_rx_tx(t) { + enum txrx r= nm_txrx_swap(t); /* swap NR_TX <-> NR_RX */ + for (i = 0; i < nma_get_nrings(na, t); i++) { + NMR(na, t)[i].pipe = NMR(&pna->peer->up, r) + i; + NMR(&pna->peer->up, r)[i].pipe = NMR(na, t) + 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; + for_rx_tx(t) { + for (i = 0; i < nma_get_nrings(na, t) + 1; i++) + NMR(na, t)[i].ring = NMR(na, t)[i].save_ring; + } } return 0; @@ -423,6 +412,8 @@ netmap_pipe_reg(struct netmap_adapter *na, int onoff) { struct netmap_pipe_adapter *pna = (struct netmap_pipe_adapter *)na; + enum txrx t; + ND("%p: onoff %d", na, onoff); if (onoff) { na->na_flags |= NAF_NETMAP_ON; @@ -443,11 +434,10 @@ netmap_pipe_reg(struct netmap_adapter *na, int onoff) netmap_adapter_get(na); pna->peer->peer_ref = 1; /* hide our rings from netmap_mem_rings_delete */ - for (i = 0; i < na->num_tx_rings + 1; i++) { - na->tx_rings[i].ring = NULL; - } - for (i = 0; i < na->num_rx_rings + 1; i++) { - na->rx_rings[i].ring = NULL; + for_rx_tx(t) { + for (i = 0; i < nma_get_nrings(na, t) + 1; i++) { + NMR(na, t)[i].ring = NULL; + } } } return 0; @@ -481,6 +471,7 @@ netmap_pipe_krings_delete(struct netmap_adapter *na) (struct netmap_pipe_adapter *)na; struct netmap_adapter *ona; /* na of the other end */ int i; + enum txrx t; if (!pna->peer_ref) { ND("%p: case 2, kept alive by peer", na); @@ -496,10 +487,10 @@ netmap_pipe_krings_delete(struct netmap_adapter *na) * 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; + for_rx_tx(t) { + for (i = 0; i < nma_get_nrings(ona, t) + 1; i++) + NMR(ona, t)[i].ring = NMR(ona, t)[i].save_ring; + } netmap_mem_rings_delete(ona); netmap_krings_delete(ona); } @@ -604,8 +595,6 @@ netmap_get_pipe_na(struct nmreq *nmr, struct netmap_adapter **na, int create) mna->up.nm_krings_delete = netmap_pipe_krings_delete; mna->up.nm_mem = pna->nm_mem; mna->up.na_lut = pna->na_lut; - mna->up.na_lut_objtotal = pna->na_lut_objtotal; - mna->up.na_lut_objsize = pna->na_lut_objsize; mna->up.num_tx_rings = 1; mna->up.num_rx_rings = 1; |
