[PATCH] percpu: include sidelined and depopulating chunks into debug output

From: Roman Gushchin
Date: Fri Apr 16 2021 - 12:54:38 EST


Information about sidelined chunks and chunks in the depopulate queue
could be extremely valuable for debugging different problems.

Dump information about these chunks on pair with regular chunks
in percpu slots via percpu stats interface.

Signed-off-by: Roman Gushchin <guro@xxxxxx>
---
mm/percpu-internal.h | 2 ++
mm/percpu-stats.c | 10 ++++++++++
mm/percpu.c | 4 ++--
3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/mm/percpu-internal.h b/mm/percpu-internal.h
index 8e432663c41e..c11f115ced5c 100644
--- a/mm/percpu-internal.h
+++ b/mm/percpu-internal.h
@@ -90,6 +90,8 @@ extern spinlock_t pcpu_lock;
extern struct list_head *pcpu_chunk_lists;
extern int pcpu_nr_slots;
extern int pcpu_nr_empty_pop_pages[];
+extern struct list_head pcpu_depopulate_list[];
+extern struct list_head pcpu_sideline_list[];

extern struct pcpu_chunk *pcpu_first_chunk;
extern struct pcpu_chunk *pcpu_reserved_chunk;
diff --git a/mm/percpu-stats.c b/mm/percpu-stats.c
index f6026dbcdf6b..af09ed1ea5f8 100644
--- a/mm/percpu-stats.c
+++ b/mm/percpu-stats.c
@@ -228,6 +228,16 @@ static int percpu_stats_show(struct seq_file *m, void *v)
}
}
}
+
+ list_for_each_entry(chunk, &pcpu_sideline_list[type], list) {
+ seq_puts(m, "Chunk (sidelined):\n");
+ chunk_map_stats(m, chunk, buffer);
+ }
+
+ list_for_each_entry(chunk, &pcpu_depopulate_list[type], list) {
+ seq_puts(m, "Chunk (to depopulate):\n");
+ chunk_map_stats(m, chunk, buffer);
+ }
}

spin_unlock_irq(&pcpu_lock);
diff --git a/mm/percpu.c b/mm/percpu.c
index 5bb294e394b3..ded3a7541cb2 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -185,13 +185,13 @@ int pcpu_nr_empty_pop_pages[PCPU_NR_CHUNK_TYPES];
* List of chunks with a lot of free pages. Used to depopulate them
* asynchronously.
*/
-static struct list_head pcpu_depopulate_list[PCPU_NR_CHUNK_TYPES];
+struct list_head pcpu_depopulate_list[PCPU_NR_CHUNK_TYPES];

/*
* List of previously depopulated chunks. They are not usually used for new
* allocations, but can be returned back to service if a need arises.
*/
-static struct list_head pcpu_sideline_list[PCPU_NR_CHUNK_TYPES];
+struct list_head pcpu_sideline_list[PCPU_NR_CHUNK_TYPES];


/*
--
2.30.2