--- defs.h | 3 ++ memory.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- task.c | 11 +++++++++ 3 files changed, 78 insertions(+), 6 deletions(-) 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..e4e4a13 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,79 @@ 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)) { + struct list_data ld; + int cnt, i; + long *tlist; + char buf[BUFSIZE]; + int sync_rss; + + BZERO(&ld, sizeof(struct list_data)); + ld.flags |= (VERBOSE | LIST_HEAD_FORMAT); + ld.member_offset = 0; + ld.list_head_offset = OFFSET(task_struct_thread_group); + ld.start = task + ld.list_head_offset; + + open_tmpfile(); + cnt = do_list(&ld); + tlist = (long *)GETBUF(cnt * sizeof(long)); + rewind(pc->tmpfile); + + for (i = 0; fgets(buf, BUFSIZE, pc->tmpfile); i++){ + if (sscanf(buf, "%lx", &tlist[i]) != 1) { + error(INFO, "task list parse error\n"); + break; + } + } + + for (i = 0; i < cnt; i++) { + /* count 0 -> filepages */ + if (!readmem(tlist[i] + + OFFSET(task_struct_rss_stat) + + OFFSET(task_rss_stat_count), KVADDR, + &sync_rss, + sizeof(int), "task_struct rss_stat 0", + RETURN_ON_ERROR)) + continue; + + rss += sync_rss; + + /* count 1 -> anonpages */ + if (!readmem(tlist[i] + + OFFSET(task_struct_rss_stat) + + OFFSET(task_rss_stat_count) + sizeof(int), + KVADDR, &sync_rss, + sizeof(int), "task_struct rss_stat 0", + RETURN_ON_ERROR)) + continue; + + rss += sync_rss; + } + + close_tmpfile(); + FREEBUF((char *)tlist); + } + /* * 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..c3c78ab 100755 --- a/task.c +++ b/task.c @@ -349,6 +349,17 @@ task_init(void) MEMBER_OFFSET_INIT(task_struct_run_list, "task_struct", "run_list"); + if (MEMBER_EXISTS("task_struct", "thread_group")) + MEMBER_OFFSET_INIT(task_struct_thread_group, "task_struct", + "thread_group"); + + if (MEMBER_EXISTS("task_struct", "rss_stat")) { + 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