Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Jul 2026 15:49:24 +0000
From:      Bjoern A. Zeeb <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 9de11cc26ab6 - main - LinuxKPI: skbuff: implement __skb_linearize()
Message-ID:  <6a5a4f04.2034c.6d8f23c2@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=9de11cc26ab61d7f80e8af84dbc55d8cbd6f832d

commit 9de11cc26ab61d7f80e8af84dbc55d8cbd6f832d
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2026-02-03 22:13:24 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2026-07-17 15:48:53 +0000

    LinuxKPI: skbuff: implement __skb_linearize()
    
    skb_linearize() is used by mt7921, mt7925, and in the general mt76 tx dma
    code. __skb_linearize() is used in the general iwlwifi TX code but given
    the way we currently create TX skbs in LinuxKPI 802.11 we never hit that
    case.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      3 days
---
 sys/compat/linuxkpi/common/include/linux/skbuff.h |  6 +--
 sys/compat/linuxkpi/common/src/linux_skbuff.c     | 60 +++++++++++++++++++++++
 2 files changed, 63 insertions(+), 3 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/skbuff.h b/sys/compat/linuxkpi/common/include/linux/skbuff.h
index a0724803e732..9434655fc9f4 100644
--- a/sys/compat/linuxkpi/common/include/linux/skbuff.h
+++ b/sys/compat/linuxkpi/common/include/linux/skbuff.h
@@ -209,6 +209,8 @@ void linuxkpi_kfree_skb(struct sk_buff *);
 
 struct sk_buff *linuxkpi_skb_copy(const struct sk_buff *, gfp_t);
 
+int lkpi___skb_linearize(struct sk_buff *);
+
 /* -------------------------------------------------------------------------- */
 
 static inline struct sk_buff *
@@ -978,9 +980,7 @@ skb_network_header(struct sk_buff *skb)
 static inline int
 __skb_linearize(struct sk_buff *skb)
 {
-	SKB_TRACE(skb);
-	SKB_TODO();
-	return (-ENXIO);
+	return (lkpi___skb_linearize(skb));
 }
 
 static inline int
diff --git a/sys/compat/linuxkpi/common/src/linux_skbuff.c b/sys/compat/linuxkpi/common/src/linux_skbuff.c
index abfb642ba708..a2aa601d594e 100644
--- a/sys/compat/linuxkpi/common/src/linux_skbuff.c
+++ b/sys/compat/linuxkpi/common/src/linux_skbuff.c
@@ -222,6 +222,66 @@ linuxkpi_skb_copy(const struct sk_buff *skb, gfp_t gfp)
 	return (new);
 }
 
+int
+lkpi___skb_linearize(struct sk_buff *skb)
+{
+	struct sk_buff *new;
+	struct skb_shared_info *shinfo;
+	uint16_t fragno, count;
+
+	SKB_TRACE(skb);
+	SKB_IMPROVE("Hack completely re-allocating and freeing; FIXME");
+	new = skb_copy(skb, GFP_NOWAIT);
+	if (new == NULL)
+		return (-ENOMEM);
+
+	/* Now need to swap head, data, tail, ... and free from old (and then new). */
+	shinfo = skb->shinfo;
+	for (count = fragno = 0;
+	    count < shinfo->nr_frags && fragno < nitems(shinfo->frags);
+	    fragno++) {
+
+		if (shinfo->frags[fragno].page != NULL) {
+			struct page *p;
+
+			p = shinfo->frags[fragno].page;
+			shinfo->frags[fragno].size = 0;
+			shinfo->frags[fragno].offset = 0;
+			shinfo->frags[fragno].page = NULL;
+			__free_page(p);
+			count++;
+		}
+	}
+
+	if ((skb->_flags & _SKB_FLAGS_SKBEXTFRAG) != 0) {
+		void *p;
+
+		p = skb->head;
+		skb_free_frag(p);
+		skb->head = NULL;
+		skb->_flags &= ~_SKB_FLAGS_SKBEXTFRAG;
+	}
+
+#ifdef	SKB_DMA32_MALLOC
+	if (__predict_false(linuxkpi_skb_memlimit != 0))
+		free(skb->head, M_LKPISKB);
+	else
+#endif
+	kfree(skb->head);
+
+	skb->head = new->head;
+	skb->data = new->data;
+	skb->tail = new->tail;
+	skb->end = new->end;
+	skb->len = new->len;
+	skb->data_len = new->data_len;
+	skb->truesize = new->truesize;
+
+	uma_zfree(skbzone, new);
+
+	return (0);
+}
+
 void
 linuxkpi_kfree_skb(struct sk_buff *skb)
 {


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a5a4f04.2034c.6d8f23c2>