>From ab3eb627ae53074e6e9a94503e5b3022f0532e18 Mon Sep 17 00:00:00 2001 From: zhangyanfei Date: Mon, 22 Oct 2012 10:35:36 +0800 Subject: [PATCH 1/2] runq: make tasks in cfs_rq displayed hierarchically Signed-off-by: zhangyanfei --- defs.h | 10 +++++++ kernel.c | 2 + symbols.c | 20 ++++++++++++++ task.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 108 insertions(+), 8 deletions(-) diff --git a/defs.h b/defs.h index 319584f..4ee550c 100755 --- a/defs.h +++ b/defs.h @@ -1792,6 +1792,15 @@ 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 task_group_cfs_bandwidth; + long task_group_rt_bandwidth; + long task_group_rt_rq; + long task_group_cfs_rq; + long cfs_rq_tg; + long rt_rq_tg; + long cgroup_subsys_state_cgroup; + long cgroup_dentry; }; struct size_table { /* stash of commonly-used sizes */ @@ -1927,6 +1936,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/kernel.c b/kernel.c index 45da48e..d5fee08 100755 --- a/kernel.c +++ b/kernel.c @@ -308,6 +308,8 @@ kernel_init() STRUCT_SIZE_INIT(prio_array, "prio_array"); MEMBER_OFFSET_INIT(rq_cfs, "rq", "cfs"); + if (STRUCT_EXISTS("task_group")) + STRUCT_SIZE_INIT(task_group, "task_group"); /* * In 2.4, smp_send_stop() sets smp_num_cpus back to 1 diff --git a/symbols.c b/symbols.c index 1f09c9f..fc2b5c7 100755 --- a/symbols.c +++ b/symbols.c @@ -8820,6 +8820,24 @@ 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, " task_group_cfs_bandwidth: %ld\n", + OFFSET(task_group_cfs_bandwidth)); + fprintf(fp, " task_group_rt_bandwidth: %ld\n", + OFFSET(task_group_rt_bandwidth)); + fprintf(fp, " task_group_rt_rq: %ld\n", + OFFSET(task_group_rt_rq)); + 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, " rt_rq_tg: %ld\n", + OFFSET(rt_rq_tg)); + fprintf(fp, " cgroup_subsys_state_cgroup: %ld\n", + OFFSET(cgroup_subsys_state_cgroup)); + fprintf(fp, " cgroup_dentry: %ld\n", + OFFSET(cgroup_dentry)); fprintf(fp, "\n size_table:\n"); fprintf(fp, " page: %ld\n", SIZE(page)); @@ -9037,6 +9055,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..e0aff17 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,6 +7422,31 @@ rb_next(struct rb_node *node) } static void +dump_task_group_name(ulong group) +{ + ulong cgroup, dentry, name; + char *dentry_buf; + int len; + char buf[BUFSIZ]; + 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; @@ -7434,16 +7459,27 @@ dump_task_runq_entry(struct task_context *tc) } 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 && VALID_MEMBER(cfs_rq_tg)) { + readmem(cfs_rq + OFFSET(cfs_rq_tg), KVADDR, + &tmp, sizeof(ulong), "cfs_rq tg", + FAULT_ON_ERROR); + INDENT(-1 + 6 * depth); + fprintf(fp, "GROUP CFS RB_ROOT: %lx", cfs_rq); + 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); @@ -7452,7 +7488,8 @@ dump_tasks_in_cfs_rq(ulong cfs_rq) &curr_my_q, sizeof(ulong), "curr->my_q", FAULT_ON_ERROR); if (curr_my_q) - total += dump_tasks_in_cfs_rq(curr_my_q); + total += dump_tasks_in_cfs_rq(depth + 1, + curr_my_q); } } @@ -7466,7 +7503,7 @@ 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 += dump_tasks_in_cfs_rq(depth + 1, my_q); continue; } } @@ -7475,9 +7512,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(6 * depth); dump_task_runq_entry(tc); - else { + } else { error(WARNING, "duplicate CFS runqueue node: task %lx\n", tc->task); return total; @@ -7489,6 +7527,27 @@ dump_tasks_in_cfs_rq(ulong cfs_rq) } static void +task_group_offset_init(void) +{ + if (MEMBER_EXISTS("task_group", "rt_bandwidth")) { + MEMBER_OFFSET_INIT(task_group_rt_bandwidth, + "task_group", "rt_bandwidth"); + MEMBER_OFFSET_INIT(task_group_rt_rq, "task_group", "rt_rq"); + MEMBER_OFFSET_INIT(rt_rq_tg, "rt_rq", "tg"); + 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", "cfs_bandwidth")) { + MEMBER_OFFSET_INIT(task_group_cfs_bandwidth, + "task_group", "cfs_bandwidth"); + MEMBER_OFFSET_INIT(task_group_cfs_rq, "task_group", "cfs_rq"); + MEMBER_OFFSET_INIT(cfs_rq_tg, "cfs_rq", "tg"); + } +} + +static void dump_on_rq_tasks(void) { char buf[BUFSIZE]; @@ -7586,6 +7645,9 @@ dump_CFS_runqueues(void) MEMBER_OFFSET_INIT(rt_prio_array_queue, "rt_prio_array", "queue"); } + if (VALID_STRUCT(task_group) && !VALID_MEMBER(task_group_cfs_rq)) + task_group_offset_init(); + if (!(rq_sp = per_cpu_symbol_search("per_cpu__runqueues"))) error(FATAL, "per-cpu runqueues do not exist\n"); @@ -7641,7 +7703,7 @@ 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); @@ -7665,6 +7727,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 +7777,13 @@ 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)); + 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