Skip to content

Commit

Permalink
netmap: manually backport multiple fixes
Browse files Browse the repository at this point in the history
o Restore netmap emulation mode to working order, including
  fixing the destructor panics on detach.
o Omit pipe additions to these fixes, likely problematic for
  Suricata to pass traffic like it does on 11.0 without this
  patch.
o Allow to build the module without errors in the tree.

Many thanks to Vincenzo Maffione for assistance and review!  :)

From b497fe34fd275da6b850bf271f510d02b888b8bc Mon Sep 17 00:00:00 2001
From: Giuseppe Lettieri <g.lettieri@iet.unipi.it>
Date: Thu, 2 Jun 2016 00:21:40 +0200
Subject: [PATCH] allocate only the rings requested by the user

From 09936864fa5b67b82ef4a9907819b7018e9a38f2 Mon Sep 17 00:00:00 2001
From: Giuseppe Lettieri <g.lettieri@iet.unipi.it>
Date: Wed, 20 Jul 2016 20:35:12 +0000
Subject: [PATCH] freebsd: fix const-related warning

From ab90c6c10224fefbb6a6c6e0b92e6ba80e5b694d Mon Sep 17 00:00:00 2001
From: Vincenzo Maffione <v.maffione@gmail.com>
Date: Wed, 28 Sep 2016 18:39:55 +0200
Subject: [PATCH] freebsd: generic: change mbuf allocation management

From fe811e11b2c37fc274a1134e1c10b2f6ada1a91c Mon Sep 17 00:00:00 2001
From: Vincenzo Maffione <v.maffione@gmail.com>
Date: Thu, 29 Sep 2016 08:54:52 +0200
Subject: [PATCH] freebsd: generic: call m_extadd() only once for each mbuf
  • Loading branch information
fichtner committed Jan 16, 2017
1 parent 33c11a6 commit 1758864
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 60 deletions.
27 changes: 14 additions & 13 deletions sys/dev/netmap/netmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,10 @@ netmap_do_unregif(struct netmap_priv_d *priv)
na->active_fds--;
/* release exclusive use if it was requested on regif */
netmap_rel_exclusive(priv);

/* delete rings and buffers that are no longer needed */
netmap_mem_rings_delete(na);

if (na->active_fds <= 0) { /* last instance */

if (netmap_verbose)
Expand Down Expand Up @@ -939,8 +943,6 @@ netmap_do_unregif(struct netmap_priv_d *priv)
* XXX The wake up now must happen during *_down(), when
* we order all activities to stop. -gl
*/
/* delete rings and buffers */
netmap_mem_rings_delete(na);
na->nm_krings_delete(na);
}
/* possibily decrement counter of tx_si/rx_si users */
Expand Down Expand Up @@ -1948,7 +1950,7 @@ netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na,
if (na->active_fds == 0) {
/*
* If this is the first registration of the adapter,
* also create the netmap rings and their in-kernel view,
* create the in-kernel view of the netmap rings,
* the netmap krings.
*/

Expand All @@ -1959,25 +1961,25 @@ netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na,
error = na->nm_krings_create(na);
if (error)
goto err_drop_mem;

/* create all missing netmap rings */
error = netmap_mem_rings_create(na);
if (error)
goto err_del_krings;
}

/* now the kring must exist and we can check whether some
/* now the krings must exist and we can check whether some
* previous bind has exclusive ownership on them
*/
error = netmap_get_exclusive(priv);
if (error)
goto err_del_rings;
goto err_del_krings;

/* create all needed missing netmap rings */
error = netmap_mem_rings_create(na);
if (error)
goto err_rel_excl;

/* in all cases, create a new netmap if */
nifp = netmap_mem_if_new(na);
if (nifp == NULL) {
error = ENOMEM;
goto err_rel_excl;
goto err_del_rings;
}

na->active_fds++;
Expand Down Expand Up @@ -2010,8 +2012,7 @@ netmap_do_regif(struct netmap_priv_d *priv, struct netmap_adapter *na,
err_rel_excl:
netmap_rel_exclusive(priv);
err_del_rings:
if (na->active_fds == 0)
netmap_mem_rings_delete(na);
netmap_mem_rings_delete(na);
err_del_krings:
if (na->active_fds == 0)
na->nm_krings_delete(na);
Expand Down
19 changes: 3 additions & 16 deletions sys/dev/netmap/netmap_freebsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -224,22 +224,9 @@ generic_xmit_frame(struct ifnet *ifp, struct mbuf *m,
* (and eventually, just reference the netmap buffer)
*/

if (GET_MBUF_REFCNT(m) != 1) {
D("invalid refcnt %d for %p",
GET_MBUF_REFCNT(m), m);
panic("in generic_xmit_frame");
}
// XXX the ext_size check is unnecessary if we link the netmap buf
if (m->m_ext.ext_size < len) {
RD(5, "size %d < len %d", m->m_ext.ext_size, len);
len = m->m_ext.ext_size;
}
if (0) { /* XXX seems to have negligible benefits */
m->m_ext.ext_buf = m->m_data = addr;
} else {
bcopy(addr, m->m_data, len);
}
m->m_len = m->m_pkthdr.len = len;
m->m_ext.ext_buf = m->m_data = addr;
m->m_ext.ext_size = m->m_len = m->m_pkthdr.len = len;

// inc refcount. All ours, we could skip the atomic
atomic_fetchadd_int(PNT_MBUF_REFCNT(m), 1);
M_HASHTYPE_SET(m, M_HASHTYPE_OPAQUE);
Expand Down
41 changes: 16 additions & 25 deletions sys/dev/netmap/netmap_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,34 +109,30 @@ __FBSDID("$FreeBSD$");
*/
#define SET_MBUF_DESTRUCTOR(m, fn) do { \
(m)->m_ext.ext_free = (void *)fn; \
(m)->m_ext.ext_type = EXT_EXTREF; \
} while (0)

static void
netmap_default_mbuf_destructor(struct mbuf *m)
{
/* restore original mbuf */
m->m_ext.ext_buf = m->m_data = m->m_ext.ext_arg1;
m->m_ext.ext_arg1 = NULL;
m->m_ext.ext_type = EXT_PACKET;
m->m_ext.ext_free = NULL;
if (GET_MBUF_REFCNT(m) == 0)
SET_MBUF_REFCNT(m, 1);
uma_zfree(zone_pack, m);
}
#if __FreeBSD_version < 1100000
static int void_mbuf_dtor(struct mbuf *m, void *arg1, void *arg2) { return 0; }
#else
static void void_mbuf_dtor(struct mbuf *m, void *arg1, void *arg2) { }
#endif

static inline struct mbuf *
netmap_get_mbuf(int len)
{
struct mbuf *m;
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (m) {
m->m_flags |= M_NOFREE; /* XXXNP: Almost certainly incorrect. */
m->m_ext.ext_arg1 = m->m_ext.ext_buf; // XXX save
m->m_ext.ext_free = (void *)netmap_default_mbuf_destructor;
m->m_ext.ext_type = EXT_EXTREF;
ND(5, "create m %p refcnt %d", m, GET_MBUF_REFCNT(m));

m = m_gethdr(M_NOWAIT, MT_DATA);
if (m == NULL) {
return m;
}

m_extadd(m, NULL /* buf */, 0 /* size */, void_mbuf_dtor, NULL, NULL, 0, EXT_NET_DRV
#if __FreeBSD_version < 1100000
, M_NOWAIT
#endif
);

return m;
}

Expand Down Expand Up @@ -412,11 +408,6 @@ static void
generic_mbuf_destructor(struct mbuf *m)
{
netmap_generic_irq(MBUF_IFP(m), MBUF_TXQ(m), NULL);
#ifdef __FreeBSD__
if (netmap_verbose)
RD(5, "Tx irq (%p) queue %d index %d" , m, MBUF_TXQ(m), (int)(uintptr_t)m->m_ext.ext_arg1);
netmap_default_mbuf_destructor(m);
#endif /* __FreeBSD__ */
IFRATE(rate_ctx.new.txirq++);
}

Expand Down
6 changes: 3 additions & 3 deletions sys/dev/netmap/netmap_kern.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,9 @@ struct netmap_adapter *netmap_getna(if_t ifp);
#endif

#if __FreeBSD_version >= 1100027
#define GET_MBUF_REFCNT(m) ((m)->m_ext.ext_cnt ? *((m)->m_ext.ext_cnt) : -1)
#define SET_MBUF_REFCNT(m, x) *((m)->m_ext.ext_cnt) = x
#define PNT_MBUF_REFCNT(m) ((m)->m_ext.ext_cnt)
#define GET_MBUF_REFCNT(m) ((m)->m_ext.ext_count)
#define SET_MBUF_REFCNT(m, x) (m)->m_ext.ext_count = x
#define PNT_MBUF_REFCNT(m) &((m)->m_ext.ext_count)
#else
#define GET_MBUF_REFCNT(m) ((m)->m_ext.ref_cnt ? *((m)->m_ext.ref_cnt) : -1)
#define SET_MBUF_REFCNT(m, x) *((m)->m_ext.ref_cnt) = x
Expand Down
22 changes: 19 additions & 3 deletions sys/dev/netmap/netmap_mem2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1421,8 +1421,11 @@ netmap_free_rings(struct netmap_adapter *na)
struct netmap_kring *kring = &NMR(na, t)[i];
struct netmap_ring *ring = kring->ring;

if (ring == NULL)
if (ring == NULL) {
ND("skipping ring %s (ring %p, users %d)",
kring->name, ring, kring->users);
continue;
}
netmap_free_bufs(na->nm_mem, ring->slot, kring->nkr_num_slots);
netmap_ring_free(na->nm_mem, ring);
kring->ring = NULL;
Expand Down Expand Up @@ -1453,8 +1456,9 @@ netmap_mem2_rings_create(struct netmap_adapter *na)
u_int len, ndesc;

if (ring) {
ND("%s already created", kring->name);
continue; /* already created by somebody else */
/* uneeded, or already created by somebody else */
ND("skipping ring %s", kring->name);
continue;
}
ndesc = kring->nkr_num_slots;
len = sizeof(struct netmap_ring) +
Expand Down Expand Up @@ -1569,10 +1573,22 @@ netmap_mem2_if_new(struct netmap_adapter *na)
*/
base = netmap_if_offset(na->nm_mem, nifp);
for (i = 0; i < n[NR_TX]; i++) {
if (na->tx_rings[i].ring == NULL) {
// XXX maybe use the offset of an error ring,
// like we do for buffers?
*(ssize_t *)(uintptr_t)&nifp->ring_ofs[i] = 0;
continue;
}
*(ssize_t *)(uintptr_t)&nifp->ring_ofs[i] =
netmap_ring_offset(na->nm_mem, na->tx_rings[i].ring) - base;
}
for (i = 0; i < n[NR_RX]; i++) {
if (na->rx_rings[i].ring == NULL) {
// XXX maybe use the offset of an error ring,
// like we do for buffers?
*(ssize_t *)(uintptr_t)&nifp->ring_ofs[i+n[NR_TX]] = 0;
continue;
}
*(ssize_t *)(uintptr_t)&nifp->ring_ofs[i+n[NR_TX]] =
netmap_ring_offset(na->nm_mem, na->rx_rings[i].ring) - base;
}
Expand Down
1 change: 1 addition & 0 deletions sys/modules/netmap/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ SRCS += netmap_freebsd.c
SRCS += netmap_offloadings.c
SRCS += netmap_pipe.c
SRCS += netmap_monitor.c
SRCS += opt_inet.h opt_inet6.h

.include <bsd.kmod.mk>

0 comments on commit 1758864

Please sign in to comment.