git: 43ffd0f5c0f9 - main - LinuxKPI: skbuff: switch to using uma for the skb
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 22 Apr 2025 23:46:18 UTC
The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=43ffd0f5c0f91237a37736f1d40045b0052b775b commit 43ffd0f5c0f91237a37736f1d40045b0052b775b Author: Bjoern A. Zeeb <bz@FreeBSD.org> AuthorDate: 2025-04-22 20:41:40 +0000 Commit: Bjoern A. Zeeb <bz@FreeBSD.org> CommitDate: 2025-04-22 23:45:49 +0000 LinuxKPI: skbuff: switch to using uma for the skb Split allocating the skb header and its payload data memory into skb header from uma and the data to whatever we used to do for it. This is a first step which should allow us to one day at least in the RX path take the data, attach it to an mbuf and send it up the stack and just free the skbuff header. Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/compat/linuxkpi/common/src/linux_skbuff.c | 65 ++++++++++++++++++++------- 1 file changed, 49 insertions(+), 16 deletions(-) diff --git a/sys/compat/linuxkpi/common/src/linux_skbuff.c b/sys/compat/linuxkpi/common/src/linux_skbuff.c index 4139295fc837..d454e5fc3ab8 100644 --- a/sys/compat/linuxkpi/common/src/linux_skbuff.c +++ b/sys/compat/linuxkpi/common/src/linux_skbuff.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2020-2022 The FreeBSD Foundation + * Copyright (c) 2020-2025 The FreeBSD Foundation * Copyright (c) 2021-2022 Bjoern A. Zeeb * * This software was developed by Björn Zeeb under sponsorship from @@ -42,6 +42,8 @@ #include <sys/malloc.h> #include <sys/sysctl.h> +#include <vm/uma.h> + #ifdef DDB #include <ddb/ddb.h> #endif @@ -63,6 +65,8 @@ SYSCTL_INT(_compat_linuxkpi_skb, OID_AUTO, debug, CTLFLAG_RWTUN, &linuxkpi_debug_skb, 0, "SKB debug level"); #endif +static uma_zone_t skbzone; + #ifdef __LP64__ /* * Realtek wireless drivers (e.g., rtw88) require 32bit DMA in a single segment. @@ -84,16 +88,28 @@ struct sk_buff * linuxkpi_alloc_skb(size_t size, gfp_t gfp) { struct sk_buff *skb; + void *p; size_t len; - len = sizeof(*skb) + size + sizeof(struct skb_shared_info); + skb = uma_zalloc(skbzone, linux_check_m_flags(gfp) | M_ZERO); + if (skb == NULL) + return (NULL); + + skb->prev = skb->next = skb; + skb->truesize = size; + skb->shinfo = (struct skb_shared_info *)(skb + 1); + + if (size == 0) + return (skb); + + len = size; /* * 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)) { - skb = malloc(len, M_LKPISKB, linux_check_m_flags(gfp) | M_ZERO); + p = malloc(len, M_LKPISKB, linux_check_m_flags(gfp) | M_ZERO); } else { vm_paddr_t high; @@ -107,23 +123,21 @@ linuxkpi_alloc_skb(size_t size, gfp_t gfp) break; } len = roundup_pow_of_two(len); - skb = contigmalloc(len, M_LKPISKB, + p = contigmalloc(len, M_LKPISKB, linux_check_m_flags(gfp) | M_ZERO, 0, high, PAGE_SIZE, 0); } #else - skb = malloc(len, M_LKPISKB, linux_check_m_flags(gfp) | M_ZERO); + p = malloc(len, M_LKPISKB, linux_check_m_flags(gfp) | M_ZERO); #endif - if (skb == NULL) - return (skb); - skb->truesize = size; + if (p == NULL) { + uma_zfree(skbzone, skb); + return (NULL); + } - skb->head = skb->data = skb->tail = (uint8_t *)(skb+1); + skb->head = skb->data = (uint8_t *)p; + skb_reset_tail_pointer(skb); skb->end = skb->head + size; - skb->prev = skb->next = skb; - - skb->shinfo = (struct skb_shared_info *)(skb->end); - SKB_TRACE_FMT(skb, "data %p size %zu", (skb) ? skb->data : NULL, size); return (skb); } @@ -161,8 +175,8 @@ linuxkpi_build_skb(void *data, size_t fragsz) skb->_flags |= _SKB_FLAGS_SKBEXTFRAG; skb->truesize = fragsz; skb->head = skb->data = data; - skb_reset_tail_pointer(skb); /* XXX is that correct? */ - skb->end = (void *)((uintptr_t)skb->head + fragsz); + skb_reset_tail_pointer(skb); + skb->end = skb->head + fragsz; return (skb); } @@ -255,10 +269,29 @@ linuxkpi_kfree_skb(struct sk_buff *skb) p = skb->head; skb_free_frag(p); + skb->head = NULL; } - free(skb, M_LKPISKB); + free(skb->head, M_LKPISKB); + uma_zfree(skbzone, skb); +} + +static void +lkpi_skbuff_init(void *arg __unused) +{ + skbzone = uma_zcreate("skbuff", + sizeof(struct sk_buff) + sizeof(struct skb_shared_info), + NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0); + /* Do we need to apply limits? */ +} +SYSINIT(linuxkpi_skbuff, SI_SUB_DRIVERS, SI_ORDER_FIRST, lkpi_skbuff_init, NULL); + +static void +lkpi_skbuff_destroy(void *arg __unused) +{ + uma_zdestroy(skbzone); } +SYSUNINIT(linuxkpi_skbuff, SI_SUB_DRIVERS, SI_ORDER_SECOND, lkpi_skbuff_destroy, NULL); #ifdef DDB DB_SHOW_COMMAND(skb, db_show_skb)