diff options
| author | Bjoern A. Zeeb <bz@FreeBSD.org> | 2026-02-03 22:13:24 +0000 |
|---|---|---|
| committer | Bjoern A. Zeeb <bz@FreeBSD.org> | 2026-07-17 15:48:54 +0000 |
| commit | cb13e826ec45e11e964e1921d281e0a06ca5e152 (patch) | |
| tree | dadaceed67cfa6395b02146105fa393bd5dee355 | |
| parent | 1e4ec01603c4b1e0b0eb524f28f731eb5cb5f6dc (diff) | |
| -rw-r--r-- | sys/compat/linuxkpi/common/src/linux_skbuff.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/sys/compat/linuxkpi/common/src/linux_skbuff.c b/sys/compat/linuxkpi/common/src/linux_skbuff.c index 5af9633691a6..d57c277c3267 100644 --- a/sys/compat/linuxkpi/common/src/linux_skbuff.c +++ b/sys/compat/linuxkpi/common/src/linux_skbuff.c @@ -140,6 +140,7 @@ linuxkpi_alloc_skb(size_t size, gfp_t gfp) skb->head = skb->data = (uint8_t *)p; skb_reset_tail_pointer(skb); skb->end = skb->head + size; + refcount_set(&skb->refcnt, 1); SKB_TRACE_FMT(skb, "data %p size %zu", (skb) ? skb->data : NULL, size); return (skb); @@ -180,6 +181,7 @@ linuxkpi_build_skb(void *data, size_t fragsz) skb->head = skb->data = data; skb_reset_tail_pointer(skb); skb->end = skb->head + fragsz; + refcount_set(&skb->refcnt, 1); return (skb); } @@ -288,6 +290,20 @@ lkpi___skb_linearize(struct sk_buff *skb) return (0); } +static bool +lkpi_skb_refcount_release(struct sk_buff *skb) +{ + if (skb == NULL) + return (false); + + /* Do we need further tests to avoid freeing this one? */ + + if (!refcount_dec_and_test(&skb->refcnt)) + return (false); + + return (true); +} + void linuxkpi_kfree_skb(struct sk_buff *skb) { @@ -298,6 +314,11 @@ linuxkpi_kfree_skb(struct sk_buff *skb) if (skb == NULL) return; + if (!lkpi_skb_refcount_release(skb)) { + SKB_TRACE_FMT(skb, "not freed due to refcnt"); + return; + } + /* * XXX TODO this will go away once we have skb backed by mbuf. * currently we allow the mbuf to stay around and use a private |
