[PATCH] Fix for mm_struct.rss_stat conversion into percpu_counter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Kernel commit f1a7941243c1 ("mm: convert mm's rss stats into
percpu_counter") changed mm_struct.rss_stat from struct mm_rss_stat
into an array of struct percpu_counter. (currently in linux-next)

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@xxxxxxx>
---
  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 afdcf6c4ac20..005b79cf9e74 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 {
@@ -5305,6 +5307,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..dc658bc14c33 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)) {
+			/* Linux v6.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.31.1
--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux