diff options
Diffstat (limited to 'sys/dev/netmap/netmap_pipe.c')
| -rw-r--r-- | sys/dev/netmap/netmap_pipe.c | 60 |
1 files changed, 41 insertions, 19 deletions
diff --git a/sys/dev/netmap/netmap_pipe.c b/sys/dev/netmap/netmap_pipe.c index f2ea3815f0e3..fbeee4e641b0 100644 --- a/sys/dev/netmap/netmap_pipe.c +++ b/sys/dev/netmap/netmap_pipe.c @@ -1,7 +1,7 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * - * Copyright (C) 2014-2016 Giuseppe Lettieri + * Copyright (C) 2014-2018 Giuseppe Lettieri * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -185,8 +185,9 @@ int netmap_pipe_txsync(struct netmap_kring *txkring, int flags) { struct netmap_kring *rxkring = txkring->pipe; - u_int k, lim = txkring->nkr_num_slots - 1; + u_int k, lim = txkring->nkr_num_slots - 1, nk; int m; /* slots to transfer */ + int complete; /* did we see a complete packet ? */ struct netmap_ring *txring = txkring->ring, *rxring = rxkring->ring; ND("%p: %s %x -> %s", txkring, txkring->name, flags, rxkring->name); @@ -194,6 +195,9 @@ netmap_pipe_txsync(struct netmap_kring *txkring, int flags) txkring->nr_hwcur, txkring->nr_hwtail, txkring->rcur, txkring->rhead, txkring->rtail); + /* update the hwtail */ + txkring->nr_hwtail = txkring->pipe_tail; + m = txkring->rhead - txkring->nr_hwcur; /* new slots */ if (m < 0) m += txkring->nkr_num_slots; @@ -203,29 +207,29 @@ netmap_pipe_txsync(struct netmap_kring *txkring, int flags) return 0; } - for (k = txkring->nr_hwcur; m; m--, k = nm_next(k, lim)) { + for (k = txkring->nr_hwcur, nk = lim + 1, complete = 0; m; + m--, k = nm_next(k, lim), nk = (complete ? k : nk)) { struct netmap_slot *rs = &rxring->slot[k]; struct netmap_slot *ts = &txring->slot[k]; - rs->len = ts->len; - rs->ptr = ts->ptr; - + *rs = *ts; if (ts->flags & NS_BUF_CHANGED) { - rs->buf_idx = ts->buf_idx; - rs->flags |= NS_BUF_CHANGED; ts->flags &= ~NS_BUF_CHANGED; } + complete = !(ts->flags & NS_MOREFRAG); } - mb(); /* make sure the slots are updated before publishing them */ - rxkring->nr_hwtail = k; txkring->nr_hwcur = k; ND(20, "TX after : hwcur %d hwtail %d cur %d head %d tail %d k %d", txkring->nr_hwcur, txkring->nr_hwtail, txkring->rcur, txkring->rhead, txkring->rtail, k); - rxkring->nm_notify(rxkring, 0); + if (likely(nk <= lim)) { + mb(); /* make sure the slots are updated before publishing them */ + rxkring->pipe_tail = nk; /* only publish complete packets */ + rxkring->nm_notify(rxkring, 0); + } return 0; } @@ -243,6 +247,9 @@ netmap_pipe_rxsync(struct netmap_kring *rxkring, int flags) rxkring->nr_hwcur, rxkring->nr_hwtail, rxkring->rcur, rxkring->rhead, rxkring->rtail); + /* update the hwtail */ + rxkring->nr_hwtail = rxkring->pipe_tail; + m = rxkring->rhead - rxkring->nr_hwcur; /* released slots */ if (m < 0) m += rxkring->nkr_num_slots; @@ -264,7 +271,7 @@ netmap_pipe_rxsync(struct netmap_kring *rxkring, int flags) } mb(); /* make sure the slots are updated before publishing them */ - txkring->nr_hwtail = nm_prev(k, lim); + txkring->pipe_tail = nm_prev(k, lim); rxkring->nr_hwcur = k; ND(20, "RX after : hwcur %d hwtail %d cur %d head %d tail %d k %d", @@ -346,14 +353,19 @@ netmap_pipe_krings_create(struct netmap_adapter *na) if (error) goto del_krings1; - /* cross link the krings */ + /* cross link the krings and initialize the pipe_tails */ 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(ona, r)[i]; - NMR(ona, r)[i]->pipe = NMR(na, t)[i]; + struct netmap_kring *k1 = NMR(na, t)[i], + *k2 = NMR(ona, r)[i]; + k1->pipe = k2; + k2->pipe = k1; /* mark all peer-adapter rings as fake */ - NMR(ona, r)[i]->nr_kflags |= NKR_FAKERING; + k2->nr_kflags |= NKR_FAKERING; + /* init tails */ + k1->pipe_tail = k1->nr_hwtail; + k2->pipe_tail = k2->nr_hwtail; } } @@ -436,6 +448,16 @@ netmap_pipe_reg(struct netmap_adapter *na, int onoff) if (nm_kring_pending_on(kring)) { struct netmap_kring *sring, *dring; + kring->nr_mode = NKR_NETMAP_ON; + if ((kring->nr_kflags & NKR_FAKERING) && + (kring->pipe->nr_kflags & NKR_FAKERING)) { + /* this is a re-open of a pipe + * end-point kept alive by the other end. + * We need to leave everything as it is + */ + continue; + } + /* copy the buffers from the non-fake ring */ if (kring->nr_kflags & NKR_FAKERING) { sring = kring->pipe; @@ -556,10 +578,10 @@ cleanup: if (ring == NULL) continue; - if (kring->nr_hwtail == kring->nr_hwcur) - ring->slot[kring->nr_hwtail].buf_idx = 0; + if (kring->tx == NR_RX) + ring->slot[kring->pipe_tail].buf_idx = 0; - for (j = nm_next(kring->nr_hwtail, lim); + for (j = nm_next(kring->pipe_tail, lim); j != kring->nr_hwcur; j = nm_next(j, lim)) { |
