diff --git a/defs.h b/defs.h index 5ee60f1e..f784d40c 100644 --- a/defs.h +++ b/defs.h @@ -887,6 +887,7 @@ struct task_table { /* kernel/local task table data */ int callbacks; struct task_context **context_by_task; /* task_context sorted by task addr */ ulong pid_xarray; + long shmempages; }; #define TASK_INIT_DONE (0x1) diff --git a/memory.c b/memory.c index acbee638..3f524fa4 100644 --- a/memory.c +++ b/memory.c @@ -4466,13 +4466,13 @@ in_user_stack(ulong task, ulong vaddr) } /* - * Set the const value of filepages and anonpages - * according to MM_FILEPAGES and MM_ANONPAGES. + * Set the const value of filepages, anonpages and shmempages + * according to MM_FILEPAGES, MM_ANONPAGES and MM_SHMEMPAGES. */ static void rss_page_types_init(void) { - long anonpages, filepages; + long anonpages, filepages, shmempages; if (VALID_MEMBER(mm_struct_rss)) return; @@ -4487,6 +4487,15 @@ rss_page_types_init(void) } tt->filepages = filepages; tt->anonpages = anonpages; + + /* + * The default value(MM_SHMEMPAGES) is 3, which is introduced + * in linux v4.5-rc1 and later. See commit eca56ff906bd. + */ + if (!enumerator_value("MM_SHMEMPAGES", &shmempages)) + tt->shmempages = -1; + else + tt->shmempages = shmempages; } } @@ -4812,10 +4821,11 @@ 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) && VALID_MEMBER(mm_rss_stat_count)) { - long anonpages, filepages, count; + long anonpages, filepages, shmempages, count; anonpages = tt->anonpages; filepages = tt->filepages; + shmempages = tt->shmempages; count = LONG(tt->mm_struct + OFFSET(mm_struct_rss_stat) + OFFSET(mm_rss_stat_count) + @@ -4836,6 +4846,15 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm) if (count > 0) rss += count; + if (shmempages > 0) { + count = LONG(tt->mm_struct + + OFFSET(mm_struct_rss_stat) + + OFFSET(mm_rss_stat_count) + + (shmempages * 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; @@ -4847,6 +4866,10 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm) fbc = tc->mm_struct + OFFSET(mm_struct_rss_stat) + (tt->anonpages * SIZE(percpu_counter)); rss += percpu_counter_sum_positive(fbc); + + fbc = tc->mm_struct + OFFSET(mm_struct_rss_stat) + + (tt->shmempages * SIZE(percpu_counter)); + rss += percpu_counter_sum_positive(fbc); } /* Check whether SPLIT_RSS_COUNTING is enabled */ @@ -4880,12 +4903,11 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm) if (ACTIVE() || last->rss_cache == UNINITIALIZED) { while (first <= last) { + ulong addr = first->task + OFFSET(task_struct_rss_stat) + + OFFSET(task_rss_stat_count); + /* count 0 -> filepages */ - if (!readmem(first->task + - OFFSET(task_struct_rss_stat) + - OFFSET(task_rss_stat_count), KVADDR, - &sync_rss, - sizeof(int), + if (!readmem(addr, KVADDR, &sync_rss, sizeof(int), "task_struct rss_stat MM_FILEPAGES", RETURN_ON_ERROR)) continue; @@ -4894,12 +4916,7 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm) rss_cache += sync_rss; /* count 1 -> anonpages */ - if (!readmem(first->task + - OFFSET(task_struct_rss_stat) + - OFFSET(task_rss_stat_count) + - sizeof(int), - KVADDR, &sync_rss, - sizeof(int), + if (!readmem(addr + sizeof(int), KVADDR, &sync_rss, sizeof(int), "task_struct rss_stat MM_ANONPAGES", RETURN_ON_ERROR)) continue; @@ -4907,6 +4924,18 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm) if (sync_rss > 0) rss_cache += sync_rss; + /* count 3 -> shmempages */ + if (tt->shmempages >= 0) { + if (!readmem(addr + tt->shmempages * sizeof(int), KVADDR, + &sync_rss, sizeof(int), + "task_struct rss_stat MM_SHMEMPAGES", + RETURN_ON_ERROR)) + continue; + + if (sync_rss > 0) + rss_cache += sync_rss; + } + if (first == last) break; first++; diff --git a/task.c b/task.c index c9206f50..4018a543 100644 --- a/task.c +++ b/task.c @@ -7873,6 +7873,7 @@ dump_task_table(int verbose) fprintf(fp, " init_pid_ns: %lx\n", tt->init_pid_ns); fprintf(fp, " filepages: %ld\n", tt->filepages); fprintf(fp, " anonpages: %ld\n", tt->anonpages); + fprintf(fp, " shmempages: %ld\n", tt->shmempages); fprintf(fp, " stack_end_magic: %lx\n", tt->stack_end_magic); fprintf(fp, " pf_kthread: %lx ", tt->pf_kthread); switch (tt->pf_kthread)