aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2024-08-02 13:09:41 +0000
committerMark Johnston <markj@FreeBSD.org>2024-08-02 18:05:37 +0000
commit2e4781cb12af2d13262ed5decf6fd95c8d58d9f5 (patch)
treeeb7e40aee911dcc4fc3380ba225dae5ab16958af
parente5d6af4fe754dfec6ddc6802b3bbc2dae84d733a (diff)
xen/netfront: Decouple XENNET tags from mbuf lifetimes
netmap's generic mode tries to improve performance by minimizing mbuf allocations. In service of this goal, it maintains an extra reference to the mbuf and polls the counter to see if the driver has released its reference by calling m_freem(). As a result, the extref destructor is not called when expected by the netfront driver, and mbufs tags are not freed. Modify the tx path to release its mbuf tags promptly when reclaiming tx descriptors. They are drawn from a fixed-size pool, so otherwise are quickly exhausted when a netfront interface is in netmap generic mode. Co-authored by: royger MFC after: 2 weeks Fixes: dabb3db7a817 ("xen/netfront: deal with mbuf data crossing a page boundary") Sponsored by: Cloud Software Group Sponsored by: Klara, Inc. Sponsored by: Zenarmor
-rw-r--r--sys/dev/xen/netfront/netfront.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c
index 6ac6ecc3bdb7..e13fb8765bae 100644
--- a/sys/dev/xen/netfront/netfront.c
+++ b/sys/dev/xen/netfront/netfront.c
@@ -335,8 +335,16 @@ static void mbuf_release(struct mbuf *m)
KASSERT(ref != NULL, ("Cannot find refcount"));
KASSERT(ref->count > 0, ("Invalid reference count"));
- if (--ref->count == 0)
+ if (--ref->count == 0) {
+ /*
+ * Explicitly free the tag while we hold the tx queue lock.
+ * This ensures that the tag is deleted promptly in case
+ * something else is holding extra references to the mbuf chain,
+ * such as netmap.
+ */
+ m_tag_delete(m, &ref->tag);
m_freem(m);
+ }
}
static void tag_free(struct m_tag *t)