Commit 69cb4952 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Paolo Abeni

net: page_pool: report when page pool was destroyed

Report when page pool was destroyed. Together with the inflight
/ memory use reporting this can serve as a replacement for the
warning about leaked page pools we currently print to dmesg.

Example output for a fake leaked page pool using some hacks
in netdevsim (one "live" pool, and one "leaked" on the same dev):

$ ./cli.py --no-schema --spec netlink/specs/netdev.yaml \
           --dump page-pool-get
[{'id': 2, 'ifindex': 3},
 {'id': 1, 'ifindex': 3, 'destroyed': 133, 'inflight': 1}]
Tested-by: default avatarDragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Acked-by: default avatarJesper Dangaard Brouer <hawk@kernel.org>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 7aee8429
...@@ -127,6 +127,18 @@ attribute-sets: ...@@ -127,6 +127,18 @@ attribute-sets:
type: uint type: uint
doc: | doc: |
Amount of memory held by inflight pages. Amount of memory held by inflight pages.
-
name: detach-time
type: uint
doc: |
Seconds in CLOCK_BOOTTIME of when Page Pool was detached by
the driver. Once detached Page Pool can no longer be used to
allocate memory.
Page Pools wait for all the memory allocated from them to be freed
before truly disappearing. "Detached" Page Pools cannot be
"re-attached", they are just waiting to disappear.
Attribute is absent if Page Pool has not been detached, and
can still be used to allocate new memory.
operations: operations:
list: list:
...@@ -178,6 +190,7 @@ operations: ...@@ -178,6 +190,7 @@ operations:
- napi-id - napi-id
- inflight - inflight
- inflight-mem - inflight-mem
- detach-time
dump: dump:
reply: *pp-reply reply: *pp-reply
config-cond: page-pool config-cond: page-pool
......
...@@ -193,6 +193,7 @@ struct page_pool { ...@@ -193,6 +193,7 @@ struct page_pool {
/* User-facing fields, protected by page_pools_lock */ /* User-facing fields, protected by page_pools_lock */
struct { struct {
struct hlist_node list; struct hlist_node list;
u64 detach_time;
u32 napi_id; u32 napi_id;
u32 id; u32 id;
} user; } user;
......
...@@ -70,6 +70,7 @@ enum { ...@@ -70,6 +70,7 @@ enum {
NETDEV_A_PAGE_POOL_NAPI_ID, NETDEV_A_PAGE_POOL_NAPI_ID,
NETDEV_A_PAGE_POOL_INFLIGHT, NETDEV_A_PAGE_POOL_INFLIGHT,
NETDEV_A_PAGE_POOL_INFLIGHT_MEM, NETDEV_A_PAGE_POOL_INFLIGHT_MEM,
NETDEV_A_PAGE_POOL_DETACH_TIME,
__NETDEV_A_PAGE_POOL_MAX, __NETDEV_A_PAGE_POOL_MAX,
NETDEV_A_PAGE_POOL_MAX = (__NETDEV_A_PAGE_POOL_MAX - 1) NETDEV_A_PAGE_POOL_MAX = (__NETDEV_A_PAGE_POOL_MAX - 1)
......
...@@ -953,6 +953,7 @@ void page_pool_destroy(struct page_pool *pool) ...@@ -953,6 +953,7 @@ void page_pool_destroy(struct page_pool *pool)
if (!page_pool_release(pool)) if (!page_pool_release(pool))
return; return;
page_pool_detached(pool);
pool->defer_start = jiffies; pool->defer_start = jiffies;
pool->defer_warn = jiffies + DEFER_WARN_INTERVAL; pool->defer_warn = jiffies + DEFER_WARN_INTERVAL;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
s32 page_pool_inflight(const struct page_pool *pool, bool strict); s32 page_pool_inflight(const struct page_pool *pool, bool strict);
int page_pool_list(struct page_pool *pool); int page_pool_list(struct page_pool *pool);
void page_pool_detached(struct page_pool *pool);
void page_pool_unlist(struct page_pool *pool); void page_pool_unlist(struct page_pool *pool);
#endif #endif
...@@ -134,6 +134,10 @@ page_pool_nl_fill(struct sk_buff *rsp, const struct page_pool *pool, ...@@ -134,6 +134,10 @@ page_pool_nl_fill(struct sk_buff *rsp, const struct page_pool *pool,
nla_put_uint(rsp, NETDEV_A_PAGE_POOL_INFLIGHT_MEM, nla_put_uint(rsp, NETDEV_A_PAGE_POOL_INFLIGHT_MEM,
inflight * refsz)) inflight * refsz))
goto err_cancel; goto err_cancel;
if (pool->user.detach_time &&
nla_put_uint(rsp, NETDEV_A_PAGE_POOL_DETACH_TIME,
pool->user.detach_time))
goto err_cancel;
genlmsg_end(rsp, hdr); genlmsg_end(rsp, hdr);
...@@ -219,6 +223,14 @@ int page_pool_list(struct page_pool *pool) ...@@ -219,6 +223,14 @@ int page_pool_list(struct page_pool *pool)
return err; return err;
} }
void page_pool_detached(struct page_pool *pool)
{
mutex_lock(&page_pools_lock);
pool->user.detach_time = ktime_get_boottime_seconds();
netdev_nl_page_pool_event(pool, NETDEV_CMD_PAGE_POOL_CHANGE_NTF);
mutex_unlock(&page_pools_lock);
}
void page_pool_unlist(struct page_pool *pool) void page_pool_unlist(struct page_pool *pool)
{ {
mutex_lock(&page_pools_lock); mutex_lock(&page_pools_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment