From nobody Mon Jul 27 00:10:51 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4h7fBh2c2Xz6m99C for ; Mon, 27 Jul 2026 00:10:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4h7fBg4MJ5z43mw for ; Mon, 27 Jul 2026 00:10:51 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785111051; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=xj5KmoCKwamkUbHQVeJnWnFRy5+iSNvQvugNV8uX5hA=; b=OaK4cQljSbhuH8+wVk82PkpxY1chY6u0GvjfPE14rarFTbZV1O5ror9DDDWU2ajWys822z ar/8K5iZvBdhSFnxA13n9NgJjoYp4ldvDaho0NxSrnmAAEv3GJWwumWdQBrw5H09yHJHi0 K7zOYZVkVyPoP3C7xdbLpF3vm0fPn76QIYamhGgvVMjqV1dXWXHnR1B4Nlitr2Rz93d0Gt ILt+JoBc84t1g9jS39MO/vZnjNgsQgjnlTd4yG/LHWRIPm0F4ZlrpJe+yF2dua80V+cN+F sxsJzpS86BfZtO44HlryFwcpkkixRjJQLFhZYiizeAbT6swJJN3xAeF0xmxp8Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785111051; a=rsa-sha256; cv=none; b=KPOHxi9lXOR6M1+MRKaIdoSU+1h1S7hpSu0bR5/8b63oSJBkzV8gGW01zN1GGlnFYfIknL Afl1GiSjW2e+zN+nLOhHkMUTVlNre5348eLqxUAlEprFK2VzLPuY6XJudqtFwnh4K9WbtU AD0tqkD5edj1YapmEz0XpsdLvIm32ZE46K8kcV/10eKkAGRtBCnsCdHr0kRgHgT65gmxD3 QsdDGav4BFMSqMG4fjZEGgo2Z6aV3VEfMNtSdYV8fpkXKHuvscsut/IjxLh95jN9EenNDp p6lnnfqK/fEvmQ9jJqL5+ghwC/Bi9+3500Nugc7sZuXxJBeW/koUF8j1F1/5iA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785111051; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=xj5KmoCKwamkUbHQVeJnWnFRy5+iSNvQvugNV8uX5hA=; b=h5MC4zgl9mEPneDS7zMtlmwo4ycNUdHrZpXq9ZC80pEgu18nomwlMRsyX/js+9Wj0jNpZ7 01GJv0d41Twm9Jz3Xe2JyCbDenSDo2qNVtWnRmVgqxop+ahCEktLIQSdaM0ITU4qSqcwO8 6K544ceAYEtDOi2z8XN9xpC2/Vo/rFl8X5VRYWHL5rmHzylV6TruZ5eIdo0jVtTsgGHx8U ALOvf9V9nljROjxXSWbiwnpDfnTPAM2Dsp2VNbIPDoGEfhtQCxGgOMV2sk82V9JM21ZN6N qEM2GeBLAWKOFp+/tb1COayzGLKLqYkIPU2731CHtoBvlI+sUGS7Nhi9Bnd/FA== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4h7fBg2rlvzlK2 for ; Mon, 27 Jul 2026 00:10:51 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 26da2 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 27 Jul 2026 00:10:51 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Bjoern A. Zeeb Subject: git: 66891eda3520 - stable/15 - LinuxKPI: page pool updates and add to the build List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bz X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 66891eda352010338b625f77ec5db01f67e7e1b1 Auto-Submitted: auto-generated Date: Mon, 27 Jul 2026 00:10:51 +0000 Message-Id: <6a66a20b.26da2.69d312ad@gitrepo.freebsd.org> The branch stable/15 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=66891eda352010338b625f77ec5db01f67e7e1b1 commit 66891eda352010338b625f77ec5db01f67e7e1b1 Author: Bjoern A. Zeeb AuthorDate: 2026-07-18 11:54:42 +0000 Commit: Bjoern A. Zeeb CommitDate: 2026-07-26 16:49:11 +0000 LinuxKPI: page pool updates and add to the build Split implementation out from the header files. This "page pool" is the very minimalistic version we need in order to support packets on mt76. We allocate the page pool in order to have the meta data available of which we only make limited use. This implementation does no pooling, it does no page fragments for now, it always hands out a full page and frees it upon return. It is written in a way that it can be in the tree before the 'struct page' work it depends on has landed in order to reduce friction for people who want to try mt7921 (or others later) upfront. We use the same #ifdef as in the struct page work for that reason so one knob will turn everything on or off. Once the struct page work has landed and settled we can start filling this with more complexity. In the unlikely event that in the mean time any other consumer would start showing up they will have to be aware that the current code as-is essentially is a NOP without the 'struct page' work. A WARN_ONCE() will notify them. Sponsored by: The FreeBSD Foundation (cherry picked from commit e591a76621430d6d29f2580e2dec8991e450ed5e) --- .../common/include/net/page_pool/helpers.h | 58 ++++---- .../linuxkpi/common/include/net/page_pool/types.h | 19 ++- .../linuxkpi/common/src/linuxkpi_page_pool.c | 156 +++++++++++++++++++++ sys/conf/files | 2 + sys/modules/linuxkpi/Makefile | 1 + 5 files changed, 207 insertions(+), 29 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/net/page_pool/helpers.h b/sys/compat/linuxkpi/common/include/net/page_pool/helpers.h index 3469c39c7757..032e171fea3e 100644 --- a/sys/compat/linuxkpi/common/include/net/page_pool/helpers.h +++ b/sys/compat/linuxkpi/common/include/net/page_pool/helpers.h @@ -1,5 +1,9 @@ -/*- +/* * Copyright (c) 2023-2025 Bjoern A. Zeeb + * Copyright (c) 2025-2026 The FreeBSD Foundation + * + * Portions of this software were developed by Björn Zeeb + * under sponsorship from the FreeBSD Foundation. * * SPDX-License-Identifier: BSD-2-Clause */ @@ -12,58 +16,57 @@ #include #include +struct page_pool *linuxkpi_page_pool_create(const struct page_pool_params *); +void linuxkpi_page_pool_destroy(struct page_pool *); + +struct page *linuxkpi_page_pool_dev_alloc_frag(struct page_pool *, + uint32_t *, size_t); +void linuxkpi_page_pool_put_full_page(struct page_pool *, struct page *, bool); +dma_addr_t linuxkpi_page_pool_get_dma_addr(const struct page *); + + static inline struct page_pool * page_pool_create(const struct page_pool_params *ppparams) { - - pr_debug("%s: TODO\n", __func__); - return (NULL); + return (linuxkpi_page_pool_create(ppparams)); } static inline void -page_pool_destroy(struct page_pool *ppool) +page_pool_destroy(struct page_pool *pp) { - - pr_debug("%s: TODO\n", __func__); + linuxkpi_page_pool_destroy(pp); } + static inline struct page * -page_pool_dev_alloc_frag(struct page_pool *ppool, uint32_t *offset, +page_pool_dev_alloc_frag(struct page_pool *pp, uint32_t *offset, size_t size) { - - pr_debug("%s: TODO\n", __func__); - return (NULL); + return (linuxkpi_page_pool_dev_alloc_frag(pp, offset, size)); } -static inline dma_addr_t -page_pool_get_dma_addr(struct page *page) +static inline void +page_pool_put_full_page(struct page_pool *pp, struct page *page, + bool allow_direct) { - - pr_debug("%s: TODO\n", __func__); - return (0); + linuxkpi_page_pool_put_full_page(pp, page, allow_direct); } -static inline enum dma_data_direction -page_pool_get_dma_dir(const struct page_pool *ppool) +static inline dma_addr_t +page_pool_get_dma_addr(const struct page *page) { - - pr_debug("%s: TODO\n", __func__); - return (DMA_BIDIRECTIONAL); + return (linuxkpi_page_pool_get_dma_addr(page)); } -static inline void -page_pool_put_full_page(struct page_pool *ppool, struct page *page, - bool allow_direct) +static inline enum dma_data_direction +page_pool_get_dma_dir(const struct page_pool *pp) { - - pr_debug("%s: TODO\n", __func__); + return (pp->params.dma_dir); } static inline int page_pool_ethtool_stats_get_count(void) { - pr_debug("%s: TODO\n", __func__); return (0); } @@ -71,7 +74,6 @@ page_pool_ethtool_stats_get_count(void) static inline uint8_t * page_pool_ethtool_stats_get_strings(uint8_t *x) { - pr_debug("%s: TODO\n", __func__); return (x); } diff --git a/sys/compat/linuxkpi/common/include/net/page_pool/types.h b/sys/compat/linuxkpi/common/include/net/page_pool/types.h index 6747be50b9b2..e35fd32d3e02 100644 --- a/sys/compat/linuxkpi/common/include/net/page_pool/types.h +++ b/sys/compat/linuxkpi/common/include/net/page_pool/types.h @@ -1,5 +1,9 @@ -/*- +/* * Copyright (c) 2023-2025 Bjoern A. Zeeb + * Copyright (c) 2025-2026 The FreeBSD Foundation + * + * Portions of this software were developed by Björn Zeeb + * under sponsorship from the FreeBSD Foundation. * * SPDX-License-Identifier: BSD-2-Clause */ @@ -27,10 +31,23 @@ struct page_pool_params { }; struct page_pool { + struct page_pool_params params; }; #define PP_FLAG_DMA_MAP BIT(0) #define PP_FLAG_DMA_SYNC_DEV BIT(1) #define PP_FLAG_PAGE_FRAG BIT(2) +#define PP_FLAGS_ALL (PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV | \ + PP_FLAG_PAGE_FRAG) + +struct page *linuxkpi_page_pool_alloc_frag(struct page_pool *, uint32_t *, + size_t, gfp_t); + +static inline struct page * +page_pool_alloc_frag(struct page_pool *pp, uint32_t *offset, + size_t size, gfp_t gfp) +{ + return (linuxkpi_page_pool_alloc_frag(pp, offset, size, gfp)); +} #endif /* _LINUXKPI_NET_PAGE_POOL_TYPES_H */ diff --git a/sys/compat/linuxkpi/common/src/linuxkpi_page_pool.c b/sys/compat/linuxkpi/common/src/linuxkpi_page_pool.c new file mode 100644 index 000000000000..93e649faafd7 --- /dev/null +++ b/sys/compat/linuxkpi/common/src/linuxkpi_page_pool.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2025-2026 The FreeBSD Foundation + * + * This software was developed by Björn Zeeb under sponsorship from + * the FreeBSD Foundation. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +struct page_pool * +linuxkpi_page_pool_create(const struct page_pool_params *ppparams) +{ + struct page_pool *pp; + int error; + +#ifndef PAGE_IS_LKPI_PAGE + WARN_ONCE(1, "\n!!! LinuxKPI page pool not supported yet!!!\n\n"); +#endif + + pp = kzalloc_node(sizeof(*pp), GFP_KERNEL, ppparams->nid); + if (pp == NULL) + return (ERR_PTR(-ENOMEM)); + + pp->params = *ppparams; + + if ((pp->params.flags & PP_FLAG_DMA_MAP) != 0) { + if (pp->params.dma_dir != DMA_FROM_DEVICE && + pp->params.dma_dir != DMA_BIDIRECTIONAL) { + pr_warn_once("%s: invalid dma_dir %#04x\n", + __func__, pp->params.dma_dir); + error = -EINVAL; + goto free_pp; + } + } + + if ((pp->params.flags & PP_FLAG_DMA_SYNC_DEV) != 0) { + if ((pp->params.flags & PP_FLAG_DMA_MAP) == 0) { + pr_warn_once("%s: DMA_SYNC_DEV but no DMA_MAP\n", + __func__); + error = -EINVAL; + goto free_pp; + } + + if (pp->params.max_len == 0) { + pr_warn_once("%s: max_len unset\n", __func__); + error = -EINVAL; + goto free_pp; + } + } + + return (pp); + +free_pp: + kfree(pp); + return (ERR_PTR(error)); +} + +void +linuxkpi_page_pool_destroy(struct page_pool *pp) +{ + kfree(pp); +} + +/* ---------------------------------------------------------------------------- */ + +struct page * +linuxkpi_page_pool_alloc_frag(struct page_pool *pp, uint32_t *offset, + size_t size, gfp_t gfp) +{ +#ifdef PAGE_IS_LKPI_PAGE + struct page *p; + dma_addr_t dma; + + if (size > PAGE_SIZE) { + pr_warn_once("%s: size %zu > PAGE_SIZE\n", __func__, size); + return (NULL); + } + + /* + * We do not try to be smart on the first cut until 'struct page' work + * is sorted and settled. Everyone gets a page for now. + * XXX in the future deal with page fragments, pool limits, etc. + */ + p = alloc_page(gfp); + if (p == NULL) + return (NULL); + + if (offset != NULL) + *offset = 0; + + if ((pp->params.flags & PP_FLAG_DMA_MAP) != 0) { + dma = dma_map_page_attrs(pp->params.dev, p, 0, PAGE_SIZE, + pp->params.dma_dir, DMA_ATTR_SKIP_CPU_SYNC); + if (dma_mapping_error(pp->params.dev, dma)) { + put_page(p); + return (NULL); + } + + /* We store the dma address in struct page as well. */ + p->dma_addr = dma; + } + + if ((pp->params.flags & PP_FLAG_DMA_SYNC_DEV) != 0) + dma_sync_single_for_device(pp->params.dev, dma, PAGE_SIZE, + pp->params.dma_dir); + + /* + * We may not yet need to track the page pool on the page in order + * to know where to return it but prepare at least for that. + */ + p->pp = pp; + + return (p); +#else + return (NULL); +#endif /* PAGE_IS_LKPI_PAGE */ +} + +struct page * +linuxkpi_page_pool_dev_alloc_frag(struct page_pool *pp, uint32_t *offset, + size_t size) +{ + gfp_t gfp; + + gfp = (GFP_ATOMIC | __GFP_NOWARN); + return (page_pool_alloc_frag(pp, offset, size, gfp)); +} + +void +linuxkpi_page_pool_put_full_page(struct page_pool *pp, struct page *page, + bool allow_direct) +{ + /* We just free the full page we handed out for now. */ +#ifdef PAGE_IS_LKPI_PAGE + page->pp = NULL; + page->dma_addr = 0; +#endif + put_page(page); +} + +dma_addr_t +linuxkpi_page_pool_get_dma_addr(const struct page *page) +{ + + KASSERT(page != NULL, ("%s: page %p\n", __func__, page)); + +#ifdef PAGE_IS_LKPI_PAGE + return (page->dma_addr); +#else + return (0); +#endif +} diff --git a/sys/conf/files b/sys/conf/files index fd28ad8e093a..8a7eea3cf144 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -4680,6 +4680,8 @@ compat/linuxkpi/common/src/linux_netdev.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_page.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" +compat/linuxkpi/common/src/linuxkpi_page_pool.c optional compat_linuxkpi \ + compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_pci.c optional compat_linuxkpi pci \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_tasklet.c optional compat_linuxkpi \ diff --git a/sys/modules/linuxkpi/Makefile b/sys/modules/linuxkpi/Makefile index 2090fe76d857..da8d003e1d22 100644 --- a/sys/modules/linuxkpi/Makefile +++ b/sys/modules/linuxkpi/Makefile @@ -21,6 +21,7 @@ SRCS= linux_compat.c \ linux_lock.c \ linux_netdev.c \ linux_page.c \ + linuxkpi_page_pool.c \ linux_pci.c \ linux_radix.c \ linux_rcu.c \