diff --git a/defs.h b/defs.h index 55ca09d..ce67f9c 100755 --- a/defs.h +++ b/defs.h @@ -1881,6 +1881,9 @@ struct offset_table { /* stash of commonly-used offsets */ long task_struct_thread_context_fp; long task_struct_thread_context_sp; long task_struct_thread_context_pc; + long task_struct_thread_group; + long task_struct_rss_stat; + long task_rss_stat_count; }; struct size_table { /* stash of commonly-used sizes */ diff --git a/memory.c b/memory.c index 53ad4a2..f6957d1 100755 --- a/memory.c +++ b/memory.c @@ -3976,6 +3976,7 @@ void get_task_mem_usage(ulong task, struct task_mem_usage *tm) { struct task_context *tc; + long rss = 0; BZERO(tm, sizeof(struct task_mem_usage)); @@ -4009,22 +4010,65 @@ get_task_mem_usage(ulong task, struct task_mem_usage *tm) filepages = 0; anonpages = 1; } - tm->rss += ULONG(tt->mm_struct + + rss += LONG(tt->mm_struct + OFFSET(mm_struct_rss_stat) + OFFSET(mm_rss_stat_count) + - (filepages * sizeof(ulong))); - tm->rss += ULONG(tt->mm_struct + + (filepages * sizeof(long))); + rss += LONG(tt->mm_struct + OFFSET(mm_struct_rss_stat) + OFFSET(mm_rss_stat_count) + - (anonpages * sizeof(ulong))); + (anonpages * sizeof(long))); } + + /* Check whether SPLIT_RSS_COUNTING is enabled */ + if (VALID_MEMBER(task_struct_rss_stat)) { + int i, sync_rss; + ulong tgid; + struct task_context *tc1; + + tgid = task_tgid(task); + + tc1 = FIRST_CONTEXT(); + for (i = 0; i < RUNNING_TASKS(); i++, tc1++) { + if (task_tgid(tc1->task) != tgid) + continue; + + /* count 0 -> filepages */ + if (!readmem(tc1->task + + OFFSET(task_struct_rss_stat) + + OFFSET(task_rss_stat_count), KVADDR, + &sync_rss, + sizeof(int), + "task_struct rss_stat MM_FILEPAGES", + RETURN_ON_ERROR)) + continue; + + rss += sync_rss; + + /* count 1 -> anonpages */ + if (!readmem(tc1->task + + OFFSET(task_struct_rss_stat) + + OFFSET(task_rss_stat_count) + + sizeof(int), + KVADDR, &sync_rss, + sizeof(int), + "task_struct rss_stat MM_ANONPAGES", + RETURN_ON_ERROR)) + continue; + + rss += sync_rss; + } + } + /* * mm_struct._anon_rss and mm_struct._file_rss should exist. */ if (VALID_MEMBER(mm_struct_anon_rss)) - tm->rss += ULONG(tt->mm_struct + OFFSET(mm_struct_anon_rss)); + rss += LONG(tt->mm_struct + OFFSET(mm_struct_anon_rss)); if (VALID_MEMBER(mm_struct_file_rss)) - tm->rss += ULONG(tt->mm_struct + OFFSET(mm_struct_file_rss)); + rss += LONG(tt->mm_struct + OFFSET(mm_struct_file_rss)); + + tm->rss = (unsigned long)rss; } tm->total_vm = ULONG(tt->mm_struct + OFFSET(mm_struct_total_vm)); tm->pgd_addr = ULONG(tt->mm_struct + OFFSET(mm_struct_pgd)); diff --git a/task.c b/task.c index 6fb2b4e..db477ec 100755 --- a/task.c +++ b/task.c @@ -349,6 +349,15 @@ task_init(void) MEMBER_OFFSET_INIT(task_struct_run_list, "task_struct", "run_list"); + MEMBER_OFFSET_INIT(task_struct_thread_group, "task_struct", + "thread_group"); + + MEMBER_OFFSET_INIT(task_struct_rss_stat, "task_struct", + "rss_stat"); + + MEMBER_OFFSET_INIT(task_rss_stat_count, "task_rss_stat", + "count"); + if ((tt->task_struct = (char *)malloc(SIZE(task_struct))) == NULL) error(FATAL, "cannot malloc task_struct space."); -- 1.7.6