]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
lib: add memory allocations report in show_mem()
authorSuren Baghdasaryan <surenb@google.com>
Thu, 21 Mar 2024 16:36:54 +0000 (09:36 -0700)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 26 Apr 2024 03:55:57 +0000 (20:55 -0700)
Include allocations in show_mem reports.

Link: https://lkml.kernel.org/r/20240321163705.3067592-33-surenb@google.com
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
Reviewed-by: Vlastimil Babka <vbabka@suse.cz>
Tested-by: Kees Cook <keescook@chromium.org>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Alex Gaynor <alex.gaynor@gmail.com>
Cc: Alice Ryhl <aliceryhl@google.com>
Cc: Andreas Hindborg <a.hindborg@samsung.com>
Cc: Benno Lossin <benno.lossin@proton.me>
Cc: "Björn Roy Baron" <bjorn3_gh@protonmail.com>
Cc: Boqun Feng <boqun.feng@gmail.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Dennis Zhou <dennis@kernel.org>
Cc: Gary Guo <gary@garyguo.net>
Cc: Miguel Ojeda <ojeda@kernel.org>
Cc: Pasha Tatashin <pasha.tatashin@soleen.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Wedson Almeida Filho <wedsonaf@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/alloc_tag.h
include/linux/codetag.h
lib/alloc_tag.c
lib/codetag.c
mm/show_mem.c

index 0567766e50bdbbb940ff5a0d3ac579668a09af73..d18388c0e9e1907c7dfa4bb25b7b6adbcc59eafe 100644 (file)
@@ -31,6 +31,13 @@ struct alloc_tag {
 
 #ifdef CONFIG_MEM_ALLOC_PROFILING
 
+struct codetag_bytes {
+       struct codetag *ct;
+       s64 bytes;
+};
+
+size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep);
+
 static inline struct alloc_tag *ct_to_alloc_tag(struct codetag *ct)
 {
        return container_of(ct, struct alloc_tag, ct);
index bfd0ba5c4185c28e99fc6a9139fd55d1bbface4c..c2a579ccd455882a0ceffc2e0831b5563e922878 100644 (file)
@@ -61,6 +61,7 @@ struct codetag_iterator {
 }
 
 void codetag_lock_module_list(struct codetag_type *cttype, bool lock);
+bool codetag_trylock_module_list(struct codetag_type *cttype);
 struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype);
 struct codetag *codetag_next_ct(struct codetag_iterator *iter);
 
index 6bd8e85beaf72ec37a798467da40f47a65ee6f61..26af9982ddc44c07124aefd6b33a7741de696667 100644 (file)
@@ -89,6 +89,44 @@ static const struct seq_operations allocinfo_seq_op = {
        .show   = allocinfo_show,
 };
 
+size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep)
+{
+       struct codetag_iterator iter;
+       struct codetag *ct;
+       struct codetag_bytes n;
+       unsigned int i, nr = 0;
+
+       if (can_sleep)
+               codetag_lock_module_list(alloc_tag_cttype, true);
+       else if (!codetag_trylock_module_list(alloc_tag_cttype))
+               return 0;
+
+       iter = codetag_get_ct_iter(alloc_tag_cttype);
+       while ((ct = codetag_next_ct(&iter))) {
+               struct alloc_tag_counters counter = alloc_tag_read(ct_to_alloc_tag(ct));
+
+               n.ct    = ct;
+               n.bytes = counter.bytes;
+
+               for (i = 0; i < nr; i++)
+                       if (n.bytes > tags[i].bytes)
+                               break;
+
+               if (i < count) {
+                       nr -= nr == count;
+                       memmove(&tags[i + 1],
+                               &tags[i],
+                               sizeof(tags[0]) * (nr - i));
+                       nr++;
+                       tags[i] = n;
+               }
+       }
+
+       codetag_lock_module_list(alloc_tag_cttype, false);
+
+       return nr;
+}
+
 static void __init procfs_init(void)
 {
        proc_create_seq("allocinfo", 0444, NULL, &allocinfo_seq_op);
index 408062f722ced08994f354f1d7eac68da3c38711..5ace625f2328f294a85c8fee6974335623546e36 100644 (file)
@@ -36,6 +36,11 @@ void codetag_lock_module_list(struct codetag_type *cttype, bool lock)
                up_read(&cttype->mod_lock);
 }
 
+bool codetag_trylock_module_list(struct codetag_type *cttype)
+{
+       return down_read_trylock(&cttype->mod_lock) != 0;
+}
+
 struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype)
 {
        struct codetag_iterator iter = {
index 8dcfafbd283c12a9f7ea1ad5b338848d9897a651..bdb439551eefcb6deb5c9f16a8b97db2873c1137 100644 (file)
@@ -423,4 +423,30 @@ void __show_mem(unsigned int filter, nodemask_t *nodemask, int max_zone_idx)
 #ifdef CONFIG_MEMORY_FAILURE
        printk("%lu pages hwpoisoned\n", atomic_long_read(&num_poisoned_pages));
 #endif
+#ifdef CONFIG_MEM_ALLOC_PROFILING
+       {
+               struct codetag_bytes tags[10];
+               size_t i, nr;
+
+               nr = alloc_tag_top_users(tags, ARRAY_SIZE(tags), false);
+               if (nr) {
+                       pr_notice("Memory allocations:\n");
+                       for (i = 0; i < nr; i++) {
+                               struct codetag *ct = tags[i].ct;
+                               struct alloc_tag *tag = ct_to_alloc_tag(ct);
+                               struct alloc_tag_counters counter = alloc_tag_read(tag);
+
+                               /* Same as alloc_tag_to_text() but w/o intermediate buffer */
+                               if (ct->modname)
+                                       pr_notice("%12lli %8llu %s:%u [%s] func:%s\n",
+                                                 counter.bytes, counter.calls, ct->filename,
+                                                 ct->lineno, ct->modname, ct->function);
+                               else
+                                       pr_notice("%12lli %8llu %s:%u func:%s\n",
+                                                 counter.bytes, counter.calls, ct->filename,
+                                                 ct->lineno, ct->function);
+                       }
+               }
+       }
+#endif
 }