type: uint
doc: |
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:
list:
- napi-id
- inflight
- inflight-mem
+ - detach-time
dump:
reply: *pp-reply
config-cond: page-pool
/* User-facing fields, protected by page_pools_lock */
struct {
struct hlist_node list;
+ u64 detach_time;
u32 napi_id;
u32 id;
} user;
NETDEV_A_PAGE_POOL_NAPI_ID,
NETDEV_A_PAGE_POOL_INFLIGHT,
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 - 1)
if (!page_pool_release(pool))
return;
+ page_pool_detached(pool);
pool->defer_start = jiffies;
pool->defer_warn = jiffies + DEFER_WARN_INTERVAL;
s32 page_pool_inflight(const struct page_pool *pool, bool strict);
int page_pool_list(struct page_pool *pool);
+void page_pool_detached(struct page_pool *pool);
void page_pool_unlist(struct page_pool *pool);
#endif
nla_put_uint(rsp, NETDEV_A_PAGE_POOL_INFLIGHT_MEM,
inflight * refsz))
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);
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)
{
mutex_lock(&page_pools_lock);