Commit 7aee8429 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Paolo Abeni
Browse files

net: page_pool: report amount of memory held by page pools



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: 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 d2ef6aa0
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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)
+9 −4
Original line number Diff line number Diff line
@@ -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);

	if (strict) {
		trace_page_pool_release(pool, inflight, hold_cnt, release_cnt);
	WARN(inflight < 0, "Negative(%d) inflight packet-pages", inflight);
		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);

+2 −0
Original line number Diff line number Diff line
@@ -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);

+8 −0
Original line number Diff line number Diff line
@@ -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;