Offering: HULK hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I9GSSR
----------------------------------------
Add a new debufgs interface page_owner_filter, to filter pages not allocated by modules. This will save some space and time when uses only care pages allocated by modules.
Signed-off-by: Jinjiang Tu tujinjiang@huawei.com --- mm/page_owner.c | 4 +++ mm/page_owner.h | 11 +++++++ mm/page_owner_module.c | 68 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+)
diff --git a/mm/page_owner.c b/mm/page_owner.c index 3e3cf55d270e..c060ec8585da 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -604,6 +604,9 @@ read_page_owner(struct file *file, char __user *buf, size_t count, loff_t *ppos) if (!handle) goto ext_put_continue;
+ if (po_is_filtered(page_owner)) + goto ext_put_continue; + /* Record the next PFN to read in the file offset */ *ppos = (pfn - min_low_pfn) + 1;
@@ -727,6 +730,7 @@ static int __init pageowner_init(void) debugfs_create_file("page_owner", 0400, NULL, NULL, &proc_page_owner_operations);
+ po_module_stat_init(); return 0; } late_initcall(pageowner_init) diff --git a/mm/page_owner.h b/mm/page_owner.h index 18ea05e999e7..c516de29ba6a 100644 --- a/mm/page_owner.h +++ b/mm/page_owner.h @@ -28,6 +28,8 @@ struct page_owner { void po_find_module_name_with_update(depot_stack_handle_t handle, char *mod_name, size_t size); void po_set_module_name(struct page_owner *page_owner, char *mod_name); int po_module_name_snprint(struct page_owner *page_owner, char *kbuf, size_t size); +void po_module_stat_init(void); +bool po_is_filtered(struct page_owner *page_owner);
static inline void po_copy_module_name(struct page_owner *dst, struct page_owner *src) @@ -54,6 +56,15 @@ static inline int po_module_name_snprint(struct page_owner *page_owner, static inline void po_copy_module_name(struct page_owner *dst, struct page_owner *src) { } + +static inline void po_module_stat_init(void) +{ +} + +static inline bool po_is_filtered(struct page_owner *page_owner) +{ + return false; +} #endif
#endif diff --git a/mm/page_owner_module.c b/mm/page_owner_module.c index 2a2becf975da..cc9150d5b6ff 100644 --- a/mm/page_owner_module.c +++ b/mm/page_owner_module.c @@ -11,6 +11,12 @@
#include "page_owner.h"
+#define PAGE_OWNER_FILTER_BUF_SIZE 16 +#define PAGE_OWNER_NONE_FILTER 0 +#define PAGE_OWNER_MODULE_FILTER 1 + +static unsigned int page_owner_filter = PAGE_OWNER_NONE_FILTER; + void po_find_module_name_with_update(depot_stack_handle_t handle, char *mod_name, size_t size) { int i; @@ -68,3 +74,65 @@ int po_module_name_snprint(struct page_owner *page_owner,
return 0; } + +static ssize_t read_page_owner_filter(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + char kbuf[PAGE_OWNER_FILTER_BUF_SIZE]; + int kcount; + + if (page_owner_filter & PAGE_OWNER_MODULE_FILTER) + kcount = snprintf(kbuf, sizeof(kbuf), "module\n"); + else + kcount = snprintf(kbuf, sizeof(kbuf), "none\n"); + + return simple_read_from_buffer(user_buf, count, ppos, kbuf, kcount); +} + +static ssize_t write_page_owner_filter(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + char kbuf[PAGE_OWNER_FILTER_BUF_SIZE]; + char *p_kbuf; + size_t kbuf_size; + + kbuf_size = min(count, sizeof(kbuf) - 1); + if (copy_from_user(kbuf, user_buf, kbuf_size)) + return -EFAULT; + + kbuf[kbuf_size] = '\0'; + p_kbuf = strstrip(kbuf); + + if (!strcmp(p_kbuf, "module")) + page_owner_filter = PAGE_OWNER_MODULE_FILTER; + else if (!strcmp(p_kbuf, "none")) + page_owner_filter = PAGE_OWNER_NONE_FILTER; + else + return -EINVAL; + + return count; +} + +static const struct file_operations page_owner_filter_ops = { + .read = read_page_owner_filter, + .write = write_page_owner_filter, + .llseek = default_llseek, +}; + +bool po_is_filtered(struct page_owner *page_owner) +{ + if (unlikely(!page_owner)) + return false; + + if (page_owner_filter & PAGE_OWNER_MODULE_FILTER && + !po_is_module(page_owner)) + return true; + + return false; +} + +void po_module_stat_init(void) +{ + debugfs_create_file("page_owner_filter", 0600, NULL, NULL, + &page_owner_filter_ops); +}