>From 3ed651e7b1d803ad6d91c2cd14d613a44cd4894f Mon Sep 17 00:00:00 2001 From: Zhang Yanfei Date: Thu, 25 Oct 2012 18:33:58 +0800 Subject: [PATCH] runq: make tasks in cfs_rq displayed hierarchically Signed-off-by: Zhang Yanfei --- defs.h | 11 ++++++ symbols.c | 22 ++++++++++++ task.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 130 insertions(+), 14 deletions(-) diff --git a/defs.h b/defs.h index 319584f..ce4e35e 100755 --- a/defs.h +++ b/defs.h @@ -1792,6 +1792,16 @@ struct offset_table { /* stash of commonly-used offsets */ long sched_rt_entity_my_q; long neigh_table_hash_shift; long neigh_table_nht_ptr; + long task_group_css; + long cgroup_subsys_state_cgroup; + long cgroup_dentry; + long task_group_rt_rq; + long cfs_rq_tg; + long task_group_cfs_rq; + long rt_rq_tg; + long task_group_parent; + long task_group_siblings; + long task_group_children; }; struct size_table { /* stash of commonly-used sizes */ @@ -1927,6 +1937,7 @@ struct size_table { /* stash of commonly-used sizes */ long log; long log_level; long rt_rq; + long task_group; }; struct array_table { diff --git a/symbols.c b/symbols.c index 1f09c9f..1127e3b 100755 --- a/symbols.c +++ b/symbols.c @@ -8820,6 +8820,26 @@ dump_offset_table(char *spec, ulong makestruct) OFFSET(log_flags_level)); fprintf(fp, " sched_rt_entity_my_q: %ld\n", OFFSET(sched_rt_entity_my_q)); + fprintf(fp, " task_group_css: %ld\n", + OFFSET(task_group_css)); + fprintf(fp, " cgroup_subsys_state_cgroup: %ld\n", + OFFSET(cgroup_subsys_state_cgroup)); + fprintf(fp, " cgroup_dentry: %ld\n", + OFFSET(cgroup_dentry)); + fprintf(fp, " task_group_rt_rq: %ld\n", + OFFSET(task_group_rt_rq)); + fprintf(fp, " rt_rq_tg: %ld\n", + OFFSET(rt_rq_tg)); + fprintf(fp, " task_group_cfs_rq: %ld\n", + OFFSET(task_group_cfs_rq)); + fprintf(fp, " cfs_rq_tg: %ld\n", + OFFSET(cfs_rq_tg)); + fprintf(fp, " task_group_parent: %ld\n", + OFFSET(task_group_parent)); + fprintf(fp, " task_group_siblings: %ld\n", + OFFSET(task_group_siblings)); + fprintf(fp, " task_group_children: %ld\n", + OFFSET(task_group_children)); fprintf(fp, "\n size_table:\n"); fprintf(fp, " page: %ld\n", SIZE(page)); @@ -9037,6 +9057,8 @@ dump_offset_table(char *spec, ulong makestruct) SIZE(log_level)); fprintf(fp, " rt_rq: %ld\n", SIZE(rt_rq)); + fprintf(fp, " task_group: %ld\n", + SIZE(task_group)); fprintf(fp, "\n array_table:\n"); /* diff --git a/task.c b/task.c index f8c6325..6407f43 100755 --- a/task.c +++ b/task.c @@ -64,7 +64,7 @@ static struct rb_node *rb_parent(struct rb_node *, struct rb_node *); static struct rb_node *rb_right(struct rb_node *, struct rb_node *); static struct rb_node *rb_left(struct rb_node *, struct rb_node *); static void dump_task_runq_entry(struct task_context *); -static int dump_tasks_in_cfs_rq(ulong); +static int dump_tasks_in_cfs_rq(int, ulong); static void dump_on_rq_tasks(void); static void dump_CFS_runqueues(void); static void dump_RT_prio_array(int, ulong, char *); @@ -7422,28 +7422,65 @@ rb_next(struct rb_node *node) } static void +dump_task_group_name(ulong group) +{ + ulong cgroup, dentry, name; + char *dentry_buf; + int len; + char tmp_buf[100]; + + readmem(group + OFFSET(task_group_css) + OFFSET(cgroup_subsys_state_cgroup), + KVADDR, &cgroup, sizeof(ulong), + "task_group css cgroup", FAULT_ON_ERROR); + readmem(cgroup + OFFSET(cgroup_dentry), KVADDR, &dentry, sizeof(ulong), + "cgroup dentry", FAULT_ON_ERROR); + + dentry_buf = GETBUF(SIZE(dentry)); + readmem(dentry, KVADDR, dentry_buf, SIZE(dentry), + "dentry", FAULT_ON_ERROR); + len = UINT(dentry_buf + OFFSET(dentry_d_name) + OFFSET(qstr_len)); + name = ULONG(dentry_buf + OFFSET(dentry_d_name) + OFFSET(qstr_name)); + BZERO(tmp_buf, 100); + readmem(name, KVADDR, tmp_buf, len, "qstr name", FAULT_ON_ERROR); + fprintf(fp, " <%s> ", tmp_buf); +} + +static void dump_task_runq_entry(struct task_context *tc) { int prio; readmem(tc->task + OFFSET(task_struct_prio), KVADDR, &prio, sizeof(int), "task prio", FAULT_ON_ERROR); - fprintf(fp, " [%3d] ", prio); + fprintf(fp, "[%3d] ", prio); fprintf(fp, "PID: %-5ld TASK: %lx COMMAND: \"%s\"\n", tc->pid, tc->task, tc->comm); } static int -dump_tasks_in_cfs_rq(ulong cfs_rq) +dump_tasks_in_cfs_rq(int depth, ulong cfs_rq) { struct task_context *tc; struct rb_root *root; struct rb_node *node; ulong my_q, leftmost, curr, curr_my_q; int total; + ulong tmp; total = 0; + if (depth) { + INDENT(2 + 3 * depth); + fprintf(fp, "GROUP CFS RB_ROOT: %lx", cfs_rq); + if (VALID_MEMBER(cfs_rq_tg) && VALID_MEMBER(task_group_css)) { + readmem(cfs_rq + OFFSET(cfs_rq_tg), KVADDR, + &tmp, sizeof(ulong), "cfs_rq tg", + FAULT_ON_ERROR); + dump_task_group_name(tmp); + } + fprintf(fp, "\n"); + } + if (VALID_MEMBER(sched_entity_my_q)) { readmem(cfs_rq + OFFSET(cfs_rq_curr), KVADDR, &curr, sizeof(ulong), "curr", FAULT_ON_ERROR); @@ -7451,8 +7488,11 @@ dump_tasks_in_cfs_rq(ulong cfs_rq) readmem(curr + OFFSET(sched_entity_my_q), KVADDR, &curr_my_q, sizeof(ulong), "curr->my_q", FAULT_ON_ERROR); - if (curr_my_q) - total += dump_tasks_in_cfs_rq(curr_my_q); + if (curr_my_q) { + total++; + total += dump_tasks_in_cfs_rq(depth + 1, + curr_my_q); + } } } @@ -7466,7 +7506,8 @@ dump_tasks_in_cfs_rq(ulong cfs_rq) + OFFSET(sched_entity_my_q), KVADDR, &my_q, sizeof(ulong), "my_q", FAULT_ON_ERROR); if (my_q) { - total += dump_tasks_in_cfs_rq(my_q); + total++; + total += dump_tasks_in_cfs_rq(depth + 1, my_q); continue; } } @@ -7475,9 +7516,10 @@ dump_tasks_in_cfs_rq(ulong cfs_rq) OFFSET(sched_entity_run_node)); if (!tc) continue; - if (hq_enter((ulong)tc)) + if (hq_enter((ulong)tc)) { + INDENT(5 + 3 * depth); dump_task_runq_entry(tc); - else { + } else { error(WARNING, "duplicate CFS runqueue node: task %lx\n", tc->task); return total; @@ -7485,10 +7527,42 @@ dump_tasks_in_cfs_rq(ulong cfs_rq) total++; } + if (!total) { + INDENT(5 + 3 * depth); + fprintf(fp, "[no tasks queued]\n"); + } + return total; } static void +task_group_offset_init(void) +{ + STRUCT_SIZE_INIT(task_group, "task_group"); + if (MEMBER_EXISTS("task_group", "css")) { + MEMBER_OFFSET_INIT(task_group_css, "task_group", "css"); + MEMBER_OFFSET_INIT(cgroup_subsys_state_cgroup, "cgroup_subsys_state", "cgroup"); + MEMBER_OFFSET_INIT(cgroup_dentry, "cgroup", "dentry"); + } + + if (MEMBER_EXISTS("task_group", "rt_rq")) { + MEMBER_OFFSET_INIT(task_group_rt_rq, "task_group", "rt_rq"); + MEMBER_OFFSET_INIT(rt_rq_tg, "rt_rq", "tg"); + } + + if (MEMBER_EXISTS("task_group", "cfs_rq")) { + MEMBER_OFFSET_INIT(task_group_cfs_rq, "task_group", "cfs_rq"); + MEMBER_OFFSET_INIT(cfs_rq_tg, "cfs_rq", "tg"); + } + + if (MEMBER_EXISTS("task_group", "parent")) { + MEMBER_OFFSET_INIT(task_group_parent, "task_group", "parent"); + MEMBER_OFFSET_INIT(task_group_siblings, "task_group", "siblings"); + MEMBER_OFFSET_INIT(task_group_children, "task_group", "children"); + } +} + +static void dump_on_rq_tasks(void) { char buf[BUFSIZE]; @@ -7586,6 +7660,9 @@ dump_CFS_runqueues(void) MEMBER_OFFSET_INIT(rt_prio_array_queue, "rt_prio_array", "queue"); } + if (!VALID_STRUCT(task_group) && STRUCT_EXISTS("task_group")) + task_group_offset_init(); + if (!(rq_sp = per_cpu_symbol_search("per_cpu__runqueues"))) error(FATAL, "per-cpu runqueues do not exist\n"); @@ -7641,12 +7718,8 @@ dump_CFS_runqueues(void) fprintf(fp, " CFS RB_ROOT: %lx\n", (ulong)root); hq_open(); - tot = dump_tasks_in_cfs_rq(cfs_rq); + tot = dump_tasks_in_cfs_rq(0, cfs_rq); hq_close(); - if (!tot) { - INDENT(5); - fprintf(fp, "[no tasks queued]\n"); - } } FREEBUF(runqbuf); @@ -7665,6 +7738,7 @@ dump_RT_prio_array(int depth, ulong k_prio_array, char *u_prio_array) ulong *tlist; ulong my_q, task_addr; char *rt_rq_buf; + ulong tmp; if (!depth) fprintf(fp, " RT PRIO_ARRAY: %lx\n", k_prio_array); @@ -7714,8 +7788,17 @@ dump_RT_prio_array(int depth, ulong k_prio_array, char *u_prio_array) INDENT(5 + 6 * depth); fprintf(fp, "[%3d] ", i); - fprintf(fp, "GROUP RT PRIO_ARRAY: %lx\n", + fprintf(fp, "GROUP RT PRIO_ARRAY: %lx", my_q + OFFSET(rt_rq_active)); + if (VALID_MEMBER(rt_rq_tg) && + VALID_MEMBER(task_group_css)) { + readmem(my_q + OFFSET(rt_rq_tg), + KVADDR, &tmp, sizeof(ulong), + "rt_rq tg", + FAULT_ON_ERROR); + dump_task_group_name(tmp); + } + fprintf(fp, "\n"); tot++; dump_RT_prio_array(depth + 1, my_q + OFFSET(rt_rq_active), -- 1.7.1