net: page_pool: report amount of memory held by page pools
authorJakub Kicinski <kuba@kernel.org>
Sun, 26 Nov 2023 23:07:36 +0000 (15:07 -0800)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 28 Nov 2023 14:48:39 +0000 (15:48 +0100)
Advanced deployments need the ability to check memory use
of various system components. It makes it possible to make informed
decisions about memory allocation and to find regressions and leaks.

Report memory use of page pools. Report both number of references
and bytes held.

Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Documentation/netlink/specs/netdev.yaml
include/uapi/linux/netdev.h
net/core/page_pool.c
net/core/page_pool_priv.h
net/core/page_pool_user.c

index 82fbe81f7a49815e2cfc528bc0c6f3bb32cd521a..b76623ff2932b9b0e4db0ff08559385f5088e8ad 100644 (file)
@@ -114,6 +114,19 @@ attribute-sets:
         checks:
           min: 1
           max: u32-max
+      -
+        name: inflight
+        type: uint
+        doc: |
+          Number of outstanding references to this page pool (allocated
+          but yet to be freed pages). Allocated pages may be held in
+          socket receive queues, driver receive ring, page pool recycling
+          ring, the page pool cache, etc.
+      -
+        name: inflight-mem
+        type: uint
+        doc: |
+          Amount of memory held by inflight pages.
 
 operations:
   list:
@@ -163,6 +176,8 @@ operations:
             - id
             - ifindex
             - napi-id
+            - inflight
+            - inflight-mem
       dump:
         reply: *pp-reply
       config-cond: page-pool
index beb1588722267202030fc5317389038f28d57021..26ae5bdd3187b010e1014cc476ed7a0ab6048610 100644 (file)
@@ -68,6 +68,8 @@ enum {
        NETDEV_A_PAGE_POOL_ID = 1,
        NETDEV_A_PAGE_POOL_IFINDEX,
        NETDEV_A_PAGE_POOL_NAPI_ID,
+       NETDEV_A_PAGE_POOL_INFLIGHT,
+       NETDEV_A_PAGE_POOL_INFLIGHT_MEM,
 
        __NETDEV_A_PAGE_POOL_MAX,
        NETDEV_A_PAGE_POOL_MAX = (__NETDEV_A_PAGE_POOL_MAX - 1)
index a8d96ea38d1854c3d8a200c6cf202fa7de39b2b5..5663907592948b1a3cf48d0afe19e94ba78553ce 100644 (file)
@@ -529,7 +529,7 @@ EXPORT_SYMBOL(page_pool_alloc_pages);
  */
 #define _distance(a, b)        (s32)((a) - (b))
 
-static s32 page_pool_inflight(struct page_pool *pool)
+s32 page_pool_inflight(const struct page_pool *pool, bool strict)
 {
        u32 release_cnt = atomic_read(&pool->pages_state_release_cnt);
        u32 hold_cnt = READ_ONCE(pool->pages_state_hold_cnt);
@@ -537,8 +537,13 @@ static s32 page_pool_inflight(struct page_pool *pool)
 
        inflight = _distance(hold_cnt, release_cnt);
 
-       trace_page_pool_release(pool, inflight, hold_cnt, release_cnt);
-       WARN(inflight < 0, "Negative(%d) inflight packet-pages", inflight);
+       if (strict) {
+               trace_page_pool_release(pool, inflight, hold_cnt, release_cnt);
+               WARN(inflight < 0, "Negative(%d) inflight packet-pages",
+                    inflight);
+       } else {
+               inflight = max(0, inflight);
+       }
 
        return inflight;
 }
@@ -881,7 +886,7 @@ static int page_pool_release(struct page_pool *pool)
        int inflight;
 
        page_pool_scrub(pool);
-       inflight = page_pool_inflight(pool);
+       inflight = page_pool_inflight(pool, true);
        if (!inflight)
                __page_pool_destroy(pool);
 
index c17ea092b4ab145bf7eae9a2cba592e0132c88c0..72fb21ea1ddc1bec50420acc1bd7478ee73f2e39 100644 (file)
@@ -3,6 +3,8 @@
 #ifndef __PAGE_POOL_PRIV_H
 #define __PAGE_POOL_PRIV_H
 
+s32 page_pool_inflight(const struct page_pool *pool, bool strict);
+
 int page_pool_list(struct page_pool *pool);
 void page_pool_unlist(struct page_pool *pool);
 
index 1577fef880c95329f4e2664a1d400c2b71632a34..2db71e718485962e2d44a213f6f67f28c33c542f 100644 (file)
@@ -110,6 +110,7 @@ static int
 page_pool_nl_fill(struct sk_buff *rsp, const struct page_pool *pool,
                  const struct genl_info *info)
 {
+       size_t inflight, refsz;
        void *hdr;
 
        hdr = genlmsg_iput(rsp, info);
@@ -127,6 +128,13 @@ page_pool_nl_fill(struct sk_buff *rsp, const struct page_pool *pool,
            nla_put_uint(rsp, NETDEV_A_PAGE_POOL_NAPI_ID, pool->user.napi_id))
                goto err_cancel;
 
+       inflight = page_pool_inflight(pool, false);
+       refsz = PAGE_SIZE << pool->p.order;
+       if (nla_put_uint(rsp, NETDEV_A_PAGE_POOL_INFLIGHT, inflight) ||
+           nla_put_uint(rsp, NETDEV_A_PAGE_POOL_INFLIGHT_MEM,
+                        inflight * refsz))
+               goto err_cancel;
+
        genlmsg_end(rsp, hdr);
 
        return 0;