diff options
author | Jakub Kicinski <kuba@kernel.org> | 2023-11-26 15:07:29 -0800 |
---|---|---|
committer | Paolo Abeni <pabeni@redhat.com> | 2023-11-28 15:48:39 +0100 |
commit | f17c69649c698e4df3cfe0010b7bbf142dec3e40 (patch) | |
tree | b6d39f97735510c1fdb92ea0afc5bb5e9cf57512 | |
parent | 23cfaf67ba5d2f013d2576b8a9173c45a4a7f895 (diff) | |
download | linux-f17c69649c698e4df3cfe0010b7bbf142dec3e40.tar.gz linux-f17c69649c698e4df3cfe0010b7bbf142dec3e40.tar.bz2 linux-f17c69649c698e4df3cfe0010b7bbf142dec3e40.zip |
net: page_pool: id the page pools
To give ourselves the flexibility of creating netlink commands
and ability to refer to page pool instances in uAPIs create
IDs for page pools.
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Shakeel Butt <shakeelb@google.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-rw-r--r-- | include/net/page_pool/types.h | 4 | ||||
-rw-r--r-- | net/core/Makefile | 2 | ||||
-rw-r--r-- | net/core/page_pool.c | 21 | ||||
-rw-r--r-- | net/core/page_pool_priv.h | 9 | ||||
-rw-r--r-- | net/core/page_pool_user.c | 36 |
5 files changed, 66 insertions, 6 deletions
diff --git a/include/net/page_pool/types.h b/include/net/page_pool/types.h index e1bb92c192de..c19f0df3bf0b 100644 --- a/include/net/page_pool/types.h +++ b/include/net/page_pool/types.h @@ -187,6 +187,10 @@ struct page_pool { /* Slow/Control-path information follows */ struct page_pool_params_slow slow; + /* User-facing fields, protected by page_pools_lock */ + struct { + u32 id; + } user; }; struct page *page_pool_alloc_pages(struct page_pool *pool, gfp_t gfp); diff --git a/net/core/Makefile b/net/core/Makefile index 0cb734cbc24b..821aec06abf1 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -18,7 +18,7 @@ obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o obj-y += net-sysfs.o -obj-$(CONFIG_PAGE_POOL) += page_pool.o +obj-$(CONFIG_PAGE_POOL) += page_pool.o page_pool_user.o obj-$(CONFIG_PROC_FS) += net-procfs.o obj-$(CONFIG_NET_PKTGEN) += pktgen.o obj-$(CONFIG_NETPOLL) += netpoll.o diff --git a/net/core/page_pool.c b/net/core/page_pool.c index 2e4575477e71..a8d96ea38d18 100644 --- a/net/core/page_pool.c +++ b/net/core/page_pool.c @@ -23,6 +23,8 @@ #include <trace/events/page_pool.h> +#include "page_pool_priv.h" + #define DEFER_TIME (msecs_to_jiffies(1000)) #define DEFER_WARN_INTERVAL (60 * HZ) @@ -264,13 +266,21 @@ struct page_pool *page_pool_create(const struct page_pool_params *params) return ERR_PTR(-ENOMEM); err = page_pool_init(pool, params); - if (err < 0) { - pr_warn("%s() gave up with errno %d\n", __func__, err); - kfree(pool); - return ERR_PTR(err); - } + if (err < 0) + goto err_free; + + err = page_pool_list(pool); + if (err) + goto err_uninit; return pool; + +err_uninit: + page_pool_uninit(pool); +err_free: + pr_warn("%s() gave up with errno %d\n", __func__, err); + kfree(pool); + return ERR_PTR(err); } EXPORT_SYMBOL(page_pool_create); @@ -833,6 +843,7 @@ static void __page_pool_destroy(struct page_pool *pool) if (pool->disconnect) pool->disconnect(pool); + page_pool_unlist(pool); page_pool_uninit(pool); kfree(pool); } diff --git a/net/core/page_pool_priv.h b/net/core/page_pool_priv.h new file mode 100644 index 000000000000..c17ea092b4ab --- /dev/null +++ b/net/core/page_pool_priv.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __PAGE_POOL_PRIV_H +#define __PAGE_POOL_PRIV_H + +int page_pool_list(struct page_pool *pool); +void page_pool_unlist(struct page_pool *pool); + +#endif diff --git a/net/core/page_pool_user.c b/net/core/page_pool_user.c new file mode 100644 index 000000000000..630d1eeecf2a --- /dev/null +++ b/net/core/page_pool_user.c @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/mutex.h> +#include <linux/xarray.h> +#include <net/page_pool/types.h> + +#include "page_pool_priv.h" + +static DEFINE_XARRAY_FLAGS(page_pools, XA_FLAGS_ALLOC1); +static DEFINE_MUTEX(page_pools_lock); + +int page_pool_list(struct page_pool *pool) +{ + static u32 id_alloc_next; + int err; + + mutex_lock(&page_pools_lock); + err = xa_alloc_cyclic(&page_pools, &pool->user.id, pool, xa_limit_32b, + &id_alloc_next, GFP_KERNEL); + if (err < 0) + goto err_unlock; + + mutex_unlock(&page_pools_lock); + return 0; + +err_unlock: + mutex_unlock(&page_pools_lock); + return err; +} + +void page_pool_unlist(struct page_pool *pool) +{ + mutex_lock(&page_pools_lock); + xa_erase(&page_pools, pool->user.id); + mutex_unlock(&page_pools_lock); +} |