22c47c372b
Release: crash-8.0.2-3 Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
164 lines
5.3 KiB
Diff
164 lines
5.3 KiB
Diff
From f182d08bab202dddf20b742fef6cc2bda0a56d6c Mon Sep 17 00:00:00 2001
|
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
|
Date: Thu, 15 Dec 2022 11:31:38 +0900
|
|
Subject: [PATCH 06/28] Fix for mm_struct.rss_stat conversion into
|
|
percpu_counter
|
|
|
|
Kernel commit f1a7941243c1 ("mm: convert mm's rss stats into
|
|
percpu_counter"), which is contained in Linux 6.2-rc1 and later
|
|
kernels, changed mm_struct.rss_stat from struct mm_rss_stat into an
|
|
array of struct percpu_counter.
|
|
|
|
Without the patch, "ps" and several commands fail with the following
|
|
error message:
|
|
|
|
ps: invalid structure member offset: mm_rss_stat_count
|
|
FILE: memory.c LINE: 4724 FUNCTION: get_task_mem_usage()
|
|
|
|
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
|
---
|
|
defs.h | 3 +++
|
|
kernel.c | 2 ++
|
|
memory.c | 14 +++++++++++++-
|
|
symbols.c | 6 ++++--
|
|
tools.c | 28 ++++++++++++++++++++++++++++
|
|
5 files changed, 50 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/defs.h b/defs.h
|
|
index 67c9df2130a6..04476b3ff62e 100644
|
|
--- a/defs.h
|
|
+++ b/defs.h
|
|
@@ -2181,6 +2181,7 @@ struct offset_table { /* stash of commonly-used offsets */
|
|
long blk_mq_tags_nr_reserved_tags;
|
|
long blk_mq_tags_rqs;
|
|
long request_queue_hctx_table;
|
|
+ long percpu_counter_counters;
|
|
};
|
|
|
|
struct size_table { /* stash of commonly-used sizes */
|
|
@@ -2351,6 +2352,7 @@ struct size_table { /* stash of commonly-used sizes */
|
|
long sbitmap_queue;
|
|
long sbq_wait_state;
|
|
long blk_mq_tags;
|
|
+ long percpu_counter;
|
|
};
|
|
|
|
struct array_table {
|
|
@@ -5325,6 +5327,7 @@ struct rb_node *rb_right(struct rb_node *, struct rb_node *);
|
|
struct rb_node *rb_left(struct rb_node *, struct rb_node *);
|
|
struct rb_node *rb_next(struct rb_node *);
|
|
struct rb_node *rb_last(struct rb_root *);
|
|
+long percpu_counter_sum_positive(ulong fbc);
|
|
|
|
/*
|
|
* symbols.c
|
|
diff --git a/kernel.c b/kernel.c
|
|
index aa030e8097ea..a42e6ad7d78c 100644
|
|
--- a/kernel.c
|
|
+++ b/kernel.c
|
|
@@ -316,6 +316,8 @@ kernel_init()
|
|
}
|
|
|
|
MEMBER_OFFSET_INIT(percpu_counter_count, "percpu_counter", "count");
|
|
+ MEMBER_OFFSET_INIT(percpu_counter_counters, "percpu_counter", "counters");
|
|
+ STRUCT_SIZE_INIT(percpu_counter, "percpu_counter");
|
|
|
|
if (STRUCT_EXISTS("runqueue")) {
|
|
rqstruct = "runqueue";
|
|
diff --git a/memory.c b/memory.c
|
|
index 9c15c1b745ef..9d003713534b 100644
|
|
--- a/memory.c
|
|
+++ b/memory.c
|
|
@@ -4713,7 +4713,7 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
|
/*
|
|
* Latest kernels have mm_struct.mm_rss_stat[].
|
|
*/
|
|
- if (VALID_MEMBER(mm_struct_rss_stat)) {
|
|
+ if (VALID_MEMBER(mm_struct_rss_stat) && VALID_MEMBER(mm_rss_stat_count)) {
|
|
long anonpages, filepages, count;
|
|
|
|
anonpages = tt->anonpages;
|
|
@@ -4737,6 +4737,18 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm)
|
|
(anonpages * sizeof(long)));
|
|
if (count > 0)
|
|
rss += count;
|
|
+
|
|
+ } else if (VALID_MEMBER(mm_struct_rss_stat)) {
|
|
+ /* 6.2: struct percpu_counter rss_stat[NR_MM_COUNTERS] */
|
|
+ ulong fbc;
|
|
+
|
|
+ fbc = tc->mm_struct + OFFSET(mm_struct_rss_stat) +
|
|
+ (tt->filepages * SIZE(percpu_counter));
|
|
+ rss += percpu_counter_sum_positive(fbc);
|
|
+
|
|
+ fbc = tc->mm_struct + OFFSET(mm_struct_rss_stat) +
|
|
+ (tt->anonpages * SIZE(percpu_counter));
|
|
+ rss += percpu_counter_sum_positive(fbc);
|
|
}
|
|
|
|
/* Check whether SPLIT_RSS_COUNTING is enabled */
|
|
diff --git a/symbols.c b/symbols.c
|
|
index 42c4eb400044..e279cfa68490 100644
|
|
--- a/symbols.c
|
|
+++ b/symbols.c
|
|
@@ -10633,8 +10633,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
|
OFFSET(ktime_t_nsec));
|
|
fprintf(fp, " atomic_t_counter: %ld\n",
|
|
OFFSET(atomic_t_counter));
|
|
- fprintf(fp, " percpu_counter_count: %ld\n",
|
|
- OFFSET(percpu_counter_count));
|
|
+ fprintf(fp, " percpu_counter_count: %ld\n", OFFSET(percpu_counter_count));
|
|
+ fprintf(fp, " percpu_counter_counters: %ld\n", OFFSET(percpu_counter_counters));
|
|
fprintf(fp, " sk_buff_head_next: %ld\n",
|
|
OFFSET(sk_buff_head_next));
|
|
fprintf(fp, " sk_buff_head_qlen: %ld\n",
|
|
@@ -11028,6 +11028,8 @@ dump_offset_table(char *spec, ulong makestruct)
|
|
fprintf(fp, " sbq_wait_state: %ld\n", SIZE(sbq_wait_state));
|
|
fprintf(fp, " blk_mq_tags: %ld\n", SIZE(blk_mq_tags));
|
|
|
|
+ fprintf(fp, " percpu_counter: %ld\n", SIZE(percpu_counter));
|
|
+
|
|
fprintf(fp, "\n array_table:\n");
|
|
/*
|
|
* Use get_array_length() for those fields not set up at init-time;
|
|
diff --git a/tools.c b/tools.c
|
|
index 39306c18c98f..5f86771f5327 100644
|
|
--- a/tools.c
|
|
+++ b/tools.c
|
|
@@ -6902,3 +6902,31 @@ rb_last(struct rb_root *root)
|
|
|
|
return node;
|
|
}
|
|
+
|
|
+long
|
|
+percpu_counter_sum_positive(ulong fbc)
|
|
+{
|
|
+ int i, count;
|
|
+ ulong addr;
|
|
+ long ret;
|
|
+
|
|
+ if (INVALID_MEMBER(percpu_counter_count))
|
|
+ return 0;
|
|
+
|
|
+ readmem(fbc + OFFSET(percpu_counter_count), KVADDR, &ret,
|
|
+ sizeof(long long), "percpu_counter.count", FAULT_ON_ERROR);
|
|
+
|
|
+ if (INVALID_MEMBER(percpu_counter_counters)) /* !CONFIG_SMP */
|
|
+ return (ret < 0) ? 0 : ret;
|
|
+
|
|
+ readmem(fbc + OFFSET(percpu_counter_counters), KVADDR, &addr,
|
|
+ sizeof(void *), "percpu_counter.counters", FAULT_ON_ERROR);
|
|
+
|
|
+ for (i = 0; i < kt->cpus; i++) {
|
|
+ readmem(addr + kt->__per_cpu_offset[i], KVADDR, &count,
|
|
+ sizeof(int), "percpu_counter.counters count", FAULT_ON_ERROR);
|
|
+ ret += count;
|
|
+ }
|
|
+
|
|
+ return (ret < 0) ? 0 : ret;
|
|
+}
|
|
--
|
|
2.37.1
|
|
|