aboutsummaryrefslogtreecommitdiff
path: root/sys/net/netmap_user.h
diff options
context:
space:
mode:
authorVincenzo Maffione <vmaffione@FreeBSD.org>2018-12-05 11:57:16 +0000
committerVincenzo Maffione <vmaffione@FreeBSD.org>2018-12-05 11:57:16 +0000
commitb6e66be22bdce2aadcf52ee6230faa1e6cd3f805 (patch)
treee9311c45835e19b2d58f105e0627078f15f1cd63 /sys/net/netmap_user.h
parentabc73e04c2a0add60dea19c7aab5a0a4d51ab418 (diff)
Notes
Diffstat (limited to 'sys/net/netmap_user.h')
-rw-r--r--sys/net/netmap_user.h31
1 files changed, 25 insertions, 6 deletions
diff --git a/sys/net/netmap_user.h b/sys/net/netmap_user.h
index a86bcb6b6e3e..e9ce9c43e278 100644
--- a/sys/net/netmap_user.h
+++ b/sys/net/netmap_user.h
@@ -138,11 +138,12 @@ nm_tx_pending(struct netmap_ring *r)
return nm_ring_next(r, r->tail) != r->head;
}
-
+/* Compute the number of slots available in the netmap ring. We use
+ * ring->head as explained in the comment above nm_ring_empty(). */
static inline uint32_t
nm_ring_space(struct netmap_ring *ring)
{
- int ret = ring->tail - ring->cur;
+ int ret = ring->tail - ring->head;
if (ret < 0)
ret += ring->num_slots;
return ret;
@@ -1091,18 +1092,36 @@ nm_dispatch(struct nm_desc *d, int cnt, nm_cb_t cb, u_char *arg)
ring = NETMAP_RXRING(d->nifp, ri);
for ( ; !nm_ring_empty(ring) && cnt != got; got++) {
u_int idx, i;
+ u_char *oldbuf;
+ struct netmap_slot *slot;
if (d->hdr.buf) { /* from previous round */
cb(arg, &d->hdr, d->hdr.buf);
}
i = ring->cur;
- idx = ring->slot[i].buf_idx;
+ slot = &ring->slot[i];
+ idx = slot->buf_idx;
/* d->cur_rx_ring doesn't change inside this loop, but
* set it here, so it reflects d->hdr.buf's ring */
d->cur_rx_ring = ri;
- d->hdr.slot = &ring->slot[i];
- d->hdr.buf = (u_char *)NETMAP_BUF(ring, idx);
+ d->hdr.slot = slot;
+ oldbuf = d->hdr.buf = (u_char *)NETMAP_BUF(ring, idx);
// __builtin_prefetch(buf);
- d->hdr.len = d->hdr.caplen = ring->slot[i].len;
+ d->hdr.len = d->hdr.caplen = slot->len;
+ while (slot->flags & NS_MOREFRAG) {
+ u_char *nbuf;
+ u_int oldlen = slot->len;
+ i = nm_ring_next(ring, i);
+ slot = &ring->slot[i];
+ d->hdr.len += slot->len;
+ nbuf = (u_char *)NETMAP_BUF(ring, slot->buf_idx);
+ if (oldbuf != NULL && nbuf - oldbuf == ring->nr_buf_size &&
+ oldlen == ring->nr_buf_size) {
+ d->hdr.caplen += slot->len;
+ oldbuf = nbuf;
+ } else {
+ oldbuf = NULL;
+ }
+ }
d->hdr.ts = ring->ts;
ring->head = ring->cur = nm_ring_next(ring, i);
}