Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Apr 2025 11:41:48 GMT
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: df71d2753d00 - stable/14 - LinuxKPI: skbuff: rewrite data allocation to use __kmalloc by default
Message-ID:  <202504291141.53TBfmR6046126@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/14 has been updated by bz:

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

commit df71d2753d007c51d1722044877e1a4ade867aa4
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-04-22 20:53:47 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-04-29 10:49:30 +0000

    LinuxKPI: skbuff: rewrite data allocation to use __kmalloc by default
    
    Put tunable/contigmalloc code under SKB_DMA32_MALLOC and remove the
    __LP64__ checks for simplicity (apart from the 36bit check as that
    would overflow the variable with the constant value).
    busdma still has trouble bouncing contiguous memory with nseg=1 if
    it is multiple pages.
    
    Switch the other code to use __kmalloc() which now automatically
    provides physically contiguous memory and deals with freeing as well.
    This code should in theroy be enough now.
    
    If people use iwlwifi(4) pre-22000 (9xxx 8xxx ...) chipsets on Laptops
    with more than 64GB of memory they may see bounce errors as well now.
    
    Sposnored by:   The FreeBSD Foundation
    
    (cherry picked from commit e6c91f8e5be66d774bc07f4055aa38fb2e287ff6)
    (cherry picked from commit cd649cfc7ab23a8a36218977c60ed20afe48aea9)
---
 sys/compat/linuxkpi/common/src/linux_skbuff.c | 32 +++++++++++++++++----------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_skbuff.c b/sys/compat/linuxkpi/common/src/linux_skbuff.c
index d454e5fc3ab8..abfb642ba708 100644
--- a/sys/compat/linuxkpi/common/src/linux_skbuff.c
+++ b/sys/compat/linuxkpi/common/src/linux_skbuff.c
@@ -67,22 +67,26 @@ SYSCTL_INT(_compat_linuxkpi_skb, OID_AUTO, debug, CTLFLAG_RWTUN,
 
 static uma_zone_t skbzone;
 
-#ifdef __LP64__
+#define	SKB_DMA32_MALLOC
+#ifdef	SKB_DMA32_MALLOC
 /*
  * Realtek wireless drivers (e.g., rtw88) require 32bit DMA in a single segment.
  * busdma(9) has a hard time providing this currently for 3-ish pages at large
  * quantities (see lkpi_pci_nseg1_fail in linux_pci.c).
  * Work around this for now by allowing a tunable to enforce physical addresses
- * allocation limits on 64bit platforms using "old-school" contigmalloc(9) to
- * avoid bouncing.
+ * allocation limits using "old-school" contigmalloc(9) to avoid bouncing.
+ * Note: with the malloc/contigmalloc + kmalloc changes also providing physical
+ * contiguous memory, and the nseg=1 limit for bouncing we should in theory be
+ * fine now and not need any of this anymore, however busdma still has troubles
+ * boncing three contiguous pages so for now this stays.
  */
 static int linuxkpi_skb_memlimit;
 SYSCTL_INT(_compat_linuxkpi_skb, OID_AUTO, mem_limit, CTLFLAG_RDTUN,
     &linuxkpi_skb_memlimit, 0, "SKB memory limit: 0=no limit, "
     "1=32bit, 2=36bit, other=undef (currently 32bit)");
-#endif
 
 static MALLOC_DEFINE(M_LKPISKB, "lkpiskb", "Linux KPI skbuff compat");
+#endif
 
 struct sk_buff *
 linuxkpi_alloc_skb(size_t size, gfp_t gfp)
@@ -103,20 +107,20 @@ linuxkpi_alloc_skb(size_t size, gfp_t gfp)
 		return (skb);
 
 	len = size;
+#ifdef	SKB_DMA32_MALLOC
 	/*
 	 * Using our own type here not backing my kmalloc.
 	 * We assume no one calls kfree directly on the skb.
 	 */
-#ifdef __LP64__
-	if (__predict_true(linuxkpi_skb_memlimit == 0)) {
-		p = malloc(len, M_LKPISKB, linux_check_m_flags(gfp) | M_ZERO);
-	} else {
+	if (__predict_false(linuxkpi_skb_memlimit != 0)) {
 		vm_paddr_t high;
 
 		switch (linuxkpi_skb_memlimit) {
+#ifdef __LP64__
 		case 2:
 			high = (0xfffffffff);	/* 1<<36 really. */
 			break;
+#endif
 		case 1:
 		default:
 			high = (0xffffffff);	/* 1<<32 really. */
@@ -125,10 +129,9 @@ linuxkpi_alloc_skb(size_t size, gfp_t gfp)
 		len = roundup_pow_of_two(len);
 		p = contigmalloc(len, M_LKPISKB,
 		    linux_check_m_flags(gfp) | M_ZERO, 0, high, PAGE_SIZE, 0);
-	}
-#else
-	p = malloc(len, M_LKPISKB, linux_check_m_flags(gfp) | M_ZERO);
+	} else
 #endif
+	p = __kmalloc(len, linux_check_m_flags(gfp) | M_ZERO);
 	if (p == NULL) {
 		uma_zfree(skbzone, skb);
 		return (NULL);
@@ -272,7 +275,12 @@ linuxkpi_kfree_skb(struct sk_buff *skb)
 		skb->head = NULL;
 	}
 
-	free(skb->head, M_LKPISKB);
+#ifdef	SKB_DMA32_MALLOC
+	if (__predict_false(linuxkpi_skb_memlimit != 0))
+		free(skb->head, M_LKPISKB);
+	else
+#endif
+	kfree(skb->head);
 	uma_zfree(skbzone, skb);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202504291141.53TBfmR6046126>