Received: by 2002:a05:6500:2018:b0:1fb:9675:f89d with SMTP id t24csp39703lqh; Thu, 30 May 2024 13:17:32 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCU4kWUDtKSA0JjIOL19O36YTXczuGhpFpxQo0ae8pWckvdYseLXQmcQ4qIHH8bXii66kcP4PW7MeI4Dp2cnU4xRxwSif5rR5z3GxP/Uew== X-Google-Smtp-Source: AGHT+IGy7jxR5a5KPsN8Kd7Vp12f2lU6kxvfQJOJm2/3ehWrxuVT6A3RZzvpmkoiUMn2Az2msaAU X-Received: by 2002:a17:906:36cb:b0:a62:415b:b5c with SMTP id a640c23a62f3a-a65e8d36febmr200477166b.5.1717100251914; Thu, 30 May 2024 13:17:31 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1717100251; cv=pass; d=google.com; s=arc-20160816; b=VQyDIhq+JIeaz4n/1dnhkCXt65kVOi7buSEeEpljRd4x8f4TXROnH0i1wE8xoghoM3 cFDiojF7Z2MRc9+QKg3egfUdnJUakn87SNz5xaE5/YD1aMOKpzx1TIaPJUBKzF7clZV6 X4zJromnsO72flE0Y8CVZCCibHafvcEhJS0mBRgCq0fy069WvEv83z1yi9KSTbUwprtF o43vU3/5YiF4ZHzhTZwWuUSKaXP6aZdZ1rt/EYFzJIMx0h4cZPHAHwbKGtDP0wQehkAA nWOoWoxynwx5OK/4gaMqX7H2wmPMYbJ4tMeFpgqpH72gcNnoE4ciPbYGHEaQpaGN+Ckw sy6A== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:from:subject:message-id:references:mime-version :list-unsubscribe:list-subscribe:list-id:precedence:in-reply-to:date :dkim-signature; bh=2EPevCT7/2IjjDXAWaiob99tAoIzY7exVAkr0lb7mAI=; fh=LBnvjqt1jrNmrzLrxeUhh/5tyjWYb9HtjJ2KfThhFAY=; b=k4zpJGiYaHkHJUDq9wmwFzuRo/D9+6dHaSbN//3PaZYXPpinxtu+SnuSpQGd9tLtmx dkPEqHWneP8OdZ1iTLYpvI66nEcXQc2G+8Opny0Utx5+1sT60P5KSVwouS4zA8IDKg+7 Hm4weonAsAnrHsQewEafjyIOpL3bnUzwCYO5r30rAUabAJgpgDpwPVO/uBNJ3eHTqqd+ XPwLN8PrXhgJJt17gQsor4IX/YhUy2F2sJdNP1oV2kN/VOpKpIp9rbNsQ50rIv6nZDEP tJ0HW37GQ0xJRU4c7G8d7Es0u50YrE5FHE7tkgRRWRrHxoeePV96aFUckIpHn4YFXPSb hJmg==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=A7QPoA+v; arc=pass (i=1 spf=pass spfdomain=flex--almasrymina.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-195860-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-195860-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id a640c23a62f3a-a67e74f0909si11715766b.264.2024.05.30.13.17.31 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 30 May 2024 13:17:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-195860-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=A7QPoA+v; arc=pass (i=1 spf=pass spfdomain=flex--almasrymina.bounces.google.com dkim=pass dkdomain=google.com dmarc=pass fromdomain=google.com); spf=pass (google.com: domain of linux-kernel+bounces-195860-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-195860-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id 7CC2C1F25CAF for ; Thu, 30 May 2024 20:17:31 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 3D1C415B54E; Thu, 30 May 2024 20:16:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="A7QPoA+v" Received: from mail-yw1-f201.google.com (mail-yw1-f201.google.com [209.85.128.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 16DD2158A26 for ; Thu, 30 May 2024 20:16:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717100187; cv=none; b=fSvsJeJ84VI657BNTJUtfRTmQO/nd20cYYpcb3nQc/fHwb1VNTxM0MdW1gKdZho6SdueMsz+U4eCfjgBAsCejOuoWQjhfF+qqQVCBSL5VkZuOe/nccAMEV8SKdIwgbmtg0BUFx1cddrEPSgWlmbpH9Mfxf0gGHmDLoEZS9gulYI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717100187; c=relaxed/simple; bh=aBnYje6A82XaEKFyLV9gCbV9fgLuPXwNN+l/HwJvBXA=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=PcM0jg+9LEGPnmHEOK8/Za23UJawyXcMYpfDEnlrpCRgPm1+SOvJl4MWivFe7YGw5r1ZotCIONHfNILeaATDNT1eVx4k0R+UPOMNUDbzio+2zfv0hqCIy01cPfthdNrt+3M+ivw9+WEbZ93kIk11IgAnIUZVzSR8umOxudTU5Zs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--almasrymina.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=A7QPoA+v; arc=none smtp.client-ip=209.85.128.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--almasrymina.bounces.google.com Received: by mail-yw1-f201.google.com with SMTP id 00721157ae682-629638f1cb0so4181727b3.3 for ; Thu, 30 May 2024 13:16:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1717100183; x=1717704983; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=2EPevCT7/2IjjDXAWaiob99tAoIzY7exVAkr0lb7mAI=; b=A7QPoA+vWRgks12DbQcyyuCzLN3AdkvhIKcn2khvdMl+oNMIDXkWEet9lYrpi1Q/Jz bF3n1YnPASjfwoevU+4b/rzxB2yPMEW3pPXakBHexyiYswIcYMhsVQN8VkAn5MN1ngfG hecKLjyzCt6Vw8rgbgUqDwOkrvPmqd0nTi+GuU+tHApc0VgjhNfJxiJqIjW8cixs8caM bepHo1p4BLiSYqWXYC0QqFge2ApRXt3+99xoPRArxDlw36vWrcuPFVG4DYfV8wpY7Zlx 2iF3tUlX24Ju1paSp38Mwuh2zrjsWDY1IU34GX9ahBtcxAle+xJqrExJKFzM5DNMsFgE ZWvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717100183; x=1717704983; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2EPevCT7/2IjjDXAWaiob99tAoIzY7exVAkr0lb7mAI=; b=qE/cceS+Wk9cq0b/0iphExBwbR6RSKDTaVqi4980G+aD88qFdig0/kd9305SvpZ05C nkRAUXyHpxR9gBgX+VqGjQ/hQZcFn5yjb6mkRmCG+txKYejq+vQoaexcpdL73R/ms3+9 5A3k+26B6+zJ62Ke1aS1kpia031W+cXB5F+zxKp/B4rFkwfzN2/ULIDUmzlRke5PIgp7 6JBX+uMNuobLcKCDIGIKT/0B51SL0wsYVflz3IJS5k4HWN4sB3GUc8gUVJjJIrSuLYyE rHarcDSzLZbSQxgMUeeY5PI5iJK8Ywt/iw8ESiG3H/LUHXGZUee+QOKUpYG0uG1uR0IB I16A== X-Forwarded-Encrypted: i=1; AJvYcCWovWj55Fj4w4d4dg0aHALb0ba3jrTTOrJcj8HqUIJ+3rHRKInepq64Kj85cyFocSMDfvU4pOr9kBg9yePJKaBDa1xhRpIEMAIqVOCQ X-Gm-Message-State: AOJu0YxH36VOo/DryjK8p2OkrnqX6W8wn5ekJEL2yi7oiaU5rO8fN6QD wEczA+clmYZGo6jOAWqj+Usa6uIbNJwAiOYGvmFoaqmKZTE9bRY54BEd0IZ5NN7dph7tcrU7lXC 9AuPHuQGVPLQUAY/DWCPLiA== X-Received: from almasrymina.c.googlers.com ([fda3:e722:ac3:cc00:20:ed76:c0a8:4bc5]) (user=almasrymina job=sendgmr) by 2002:a05:690c:e:b0:62a:415b:a137 with SMTP id 00721157ae682-62c6bc22eecmr8577877b3.1.1717100182928; Thu, 30 May 2024 13:16:22 -0700 (PDT) Date: Thu, 30 May 2024 20:16:01 +0000 In-Reply-To: <20240530201616.1316526-1-almasrymina@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20240530201616.1316526-1-almasrymina@google.com> X-Mailer: git-send-email 2.45.1.288.g0e0cd299f1-goog Message-ID: <20240530201616.1316526-3-almasrymina@google.com> Subject: [PATCH net-next v10 02/14] net: page_pool: create hooks for custom page providers From: Mina Almasry To: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-alpha@vger.kernel.org, linux-mips@vger.kernel.org, linux-parisc@vger.kernel.org, sparclinux@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-arch@vger.kernel.org, bpf@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org Cc: Mina Almasry , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Donald Hunter , Jonathan Corbet , Richard Henderson , Ivan Kokshaysky , Matt Turner , Thomas Bogendoerfer , "James E.J. Bottomley" , Helge Deller , Andreas Larsson , Jesper Dangaard Brouer , Ilias Apalodimas , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Arnd Bergmann , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , John Fastabend , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Steffen Klassert , Herbert Xu , David Ahern , Willem de Bruijn , Shuah Khan , Sumit Semwal , "=?UTF-8?q?Christian=20K=C3=B6nig?=" , Pavel Begunkov , David Wei , Jason Gunthorpe , Yunsheng Lin , Shailend Chand , Harshitha Ramamurthy , Shakeel Butt , Jeroen de Borst , Praveen Kaligineedi , Christoph Hellwig Content-Type: text/plain; charset="UTF-8" From: Jakub Kicinski The page providers which try to reuse the same pages will need to hold onto the ref, even if page gets released from the pool - as in releasing the page from the pp just transfers the "ownership" reference from pp to the provider, and provider will wait for other references to be gone before feeding this page back into the pool. Signed-off-by: Jakub Kicinski Signed-off-by: Mina Almasry --- - This is implemented by Jakub in his RFC: https://lore.kernel.org/netdev/f8270765-a27b-6ccf-33ea-cda097168d79@redhat.com/T/ I take no credit for the idea or implementation; I only added minor edits to make this workable with device memory TCP, and removed some hacky test code. This is a critical dependency of device memory TCP and thus I'm pulling it into this series to make it revewable and mergeable. - There is a pending discussion about the acceptance of the page_pool memory provider hooks: https://lore.kernel.org/netdev/20240403002053.2376017-3-almasrymina@google.com/ I'm unsure if the discussion has been resolved yet. Sending the series anyway to get reviews/feedback on the (unrelated) rest of the series. Cc: Christoph Hellwig v10: - Renamed alloc_pages -> alloc_netmems. alloc_pages is now a preprocessor macro, and reusing the string results in a build error. RFC v3 -> v1 - Removed unusued mem_provider. (Yunsheng). - Replaced memory_provider & mp_priv with netdev_rx_queue (Jakub). --- include/net/page_pool/types.h | 12 ++++++++++ net/core/page_pool.c | 43 +++++++++++++++++++++++++++++++---- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/include/net/page_pool/types.h b/include/net/page_pool/types.h index b088d131aeb0d..b038b838f042f 100644 --- a/include/net/page_pool/types.h +++ b/include/net/page_pool/types.h @@ -51,6 +51,7 @@ struct pp_alloc_cache { * @dev: device, for DMA pre-mapping purposes * @netdev: netdev this pool will serve (leave as NULL if none or multiple) * @napi: NAPI which is the sole consumer of pages, otherwise NULL + * @queue: struct netdev_rx_queue this page_pool is being created for. * @dma_dir: DMA mapping direction * @max_len: max DMA sync memory size for PP_FLAG_DMA_SYNC_DEV * @offset: DMA sync address offset for PP_FLAG_DMA_SYNC_DEV @@ -64,6 +65,7 @@ struct page_pool_params { int nid; struct device *dev; struct napi_struct *napi; + struct netdev_rx_queue *queue; enum dma_data_direction dma_dir; unsigned int max_len; unsigned int offset; @@ -127,6 +129,13 @@ struct page_pool_stats { }; #endif +struct memory_provider_ops { + int (*init)(struct page_pool *pool); + void (*destroy)(struct page_pool *pool); + struct page *(*alloc_netmems)(struct page_pool *pool, gfp_t gfp); + bool (*release_page)(struct page_pool *pool, struct page *page); +}; + struct page_pool { struct page_pool_params_fast p; @@ -193,6 +202,9 @@ struct page_pool { */ struct ptr_ring ring; + void *mp_priv; + const struct memory_provider_ops *mp_ops; + #ifdef CONFIG_PAGE_POOL_STATS /* recycle stats are per-cpu to avoid locking */ struct page_pool_recycle_stats __percpu *recycle_stats; diff --git a/net/core/page_pool.c b/net/core/page_pool.c index f4444b4e39e63..251c9356c9202 100644 --- a/net/core/page_pool.c +++ b/net/core/page_pool.c @@ -26,6 +26,8 @@ #include "page_pool_priv.h" +static DEFINE_STATIC_KEY_FALSE(page_pool_mem_providers); + #define DEFER_TIME (msecs_to_jiffies(1000)) #define DEFER_WARN_INTERVAL (60 * HZ) @@ -186,6 +188,7 @@ static int page_pool_init(struct page_pool *pool, int cpuid) { unsigned int ring_qsize = 1024; /* Default */ + int err; page_pool_struct_check(); @@ -267,7 +270,22 @@ static int page_pool_init(struct page_pool *pool, if (pool->dma_map) get_device(pool->p.dev); + if (pool->mp_ops) { + err = pool->mp_ops->init(pool); + if (err) { + pr_warn("%s() mem-provider init failed %d\n", __func__, + err); + goto free_ptr_ring; + } + + static_branch_inc(&page_pool_mem_providers); + } + return 0; + +free_ptr_ring: + ptr_ring_cleanup(&pool->ring, NULL); + return err; } static void page_pool_uninit(struct page_pool *pool) @@ -569,7 +587,10 @@ struct page *page_pool_alloc_pages(struct page_pool *pool, gfp_t gfp) return page; /* Slow-path: cache empty, do real allocation */ - page = __page_pool_alloc_pages_slow(pool, gfp); + if (static_branch_unlikely(&page_pool_mem_providers) && pool->mp_ops) + page = pool->mp_ops->alloc_netmems(pool, gfp); + else + page = __page_pool_alloc_pages_slow(pool, gfp); return page; } EXPORT_SYMBOL(page_pool_alloc_pages); @@ -627,10 +648,13 @@ void __page_pool_release_page_dma(struct page_pool *pool, struct page *page) void page_pool_return_page(struct page_pool *pool, struct page *page) { int count; + bool put; - __page_pool_release_page_dma(pool, page); - - page_pool_clear_pp_info(page); + put = true; + if (static_branch_unlikely(&page_pool_mem_providers) && pool->mp_ops) + put = pool->mp_ops->release_page(pool, page); + else + __page_pool_release_page_dma(pool, page); /* This may be the last page returned, releasing the pool, so * it is not safe to reference pool afterwards. @@ -638,7 +662,10 @@ void page_pool_return_page(struct page_pool *pool, struct page *page) count = atomic_inc_return_relaxed(&pool->pages_state_release_cnt); trace_page_pool_state_release(pool, page, count); - put_page(page); + if (put) { + page_pool_clear_pp_info(page); + put_page(page); + } /* An optimization would be to call __free_pages(page, pool->p.order) * knowing page is not part of page-cache (thus avoiding a * __page_cache_release() call). @@ -937,6 +964,12 @@ static void __page_pool_destroy(struct page_pool *pool) page_pool_unlist(pool); page_pool_uninit(pool); + + if (pool->mp_ops) { + pool->mp_ops->destroy(pool); + static_branch_dec(&page_pool_mem_providers); + } + kfree(pool); } -- 2.45.1.288.g0e0cd299f1-goog