Message ID | 168269858438.2191653.17490250680021679888.stgit@firesoul (mailing list archive) |
---|---|
State | RFC |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | page_pool: new approach for leak detection and shutdown phase | expand |
Context | Check | Description |
---|---|---|
netdev/series_format | success | Posting correctly formatted |
netdev/tree_selection | success | Clearly marked for net-next |
netdev/fixes_present | success | Fixes tag not required for -next series |
netdev/header_inline | success | No static functions without inline keyword in header files |
netdev/build_32bit | success | Errors and warnings before: 16 this patch: 16 |
netdev/cc_maintainers | success | CCed 3 of 3 maintainers |
netdev/build_clang | success | Errors and warnings before: 8 this patch: 8 |
netdev/verify_signedoff | success | Signed-off-by tag matches author and committer |
netdev/deprecated_api | success | None detected |
netdev/check_selftest | success | No net selftest shell script |
netdev/verify_fixes | success | No Fixes tag |
netdev/build_allmodconfig_warn | success | Errors and warnings before: 15 this patch: 15 |
netdev/checkpatch | success | total: 0 errors, 0 warnings, 0 checks, 19 lines checked |
netdev/kdoc | success | Errors and warnings before: 0 this patch: 0 |
netdev/source_inline | success | Was 0 now: 0 |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 8e39705c7bdc..137b72f8ab8b 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1247,6 +1247,9 @@ static inline bool page_expected_state(struct page *page, page_ref_count(page) | #ifdef CONFIG_MEMCG page->memcg_data | +#endif +#ifdef CONFIG_PAGE_POOL + ((page->pp_magic & ~0x3UL) == PP_SIGNATURE) | #endif (page->flags & check_flags))) return false; @@ -1273,6 +1276,10 @@ static const char *page_bad_reason(struct page *page, unsigned long flags) #ifdef CONFIG_MEMCG if (unlikely(page->memcg_data)) bad_reason = "page still charged to cgroup"; +#endif +#ifdef CONFIG_PAGE_POOL + if (unlikely((page->pp_magic & ~0x3UL) == PP_SIGNATURE)) + bad_reason = "page_pool leak"; #endif return bad_reason; }
Pages belonging to a page_pool (PP) instance must be freed through the PP APIs in-order to correctly release any DMA mappings and release refcnt on the DMA device when freeing PP instance. When PP release a page (page_pool_release_page) the page->pp_magic value is cleared. This patch detect a leaked PP page in free_page_is_bad() via unexpected state of page->pp_magic value being PP_SIGNATURE. We choose to report and treat it as a bad page. It would be possible to release the page via returning it to the PP instance as the page->pp pointer is likely still valid. Notice this code is only activated when either compiled with CONFIG_DEBUG_VM or boot cmdline debug_pagealloc=on, and CONFIG_PAGE_POOL. Reduced example output of leak with PP_SIGNATURE = dead000000000040: BUG: Bad page state in process swapper/0 pfn:110bbf page:000000005bc8cfb8 refcount:0 mapcount:0 mapping:0000000000000000 index:0x110bbf000 pfn:0x110bbf flags: 0x2fffff80000000(node=0|zone=2|lastcpupid=0x1fffff) raw: 002fffff80000000 dead000000000040 ffff888117255000 0000000000000000 raw: 0000000110bbf000 000000000000003e 00000000ffffffff 0000000000000000 page dumped because: page_pool leak [...] Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com> --- mm/page_alloc.c | 7 +++++++ 1 file changed, 7 insertions(+)