[Crash-utility] [PATCH] Fix bugs in runq

Dave Anderson anderson at redhat.com
Wed Aug 29 18:30:04 UTC 2012



----- Original Message -----

> > Another question re: your patch -- is it possible to have a "depth" greater
> > than 1?
>
> Yes, "depth" could be greater than 1, see the example below:
>
> CPU 0 RUNQUEUE: ffff880028216680
>   CURRENT: PID: 17085  TASK: ffff880137c63540  COMMAND: "bash"
>   RT PRIO_ARRAY: ffff880028216808                                        <-- depth = 0
>      [  0] PID: 17129  TASK: ffff880037aeaaa0  COMMAND: "rtloop99"
>            PID: 2832   TASK: ffff88013b09cae0  COMMAND: "rtkit-daemon"
>            PID: 6      TASK: ffff88013d7c6080  COMMAND: "watchdog/0"
>      [  1] GROUP RT PRIO_ARRAY: ffff88002ca65000                         <-- depth = 1
>               [  1] GROUP RT PRIO_ARRAY: ffff880015821000                <-- depth = 2
>                        [  1] PID: 17126  TASK: ffff880135d2a040  COMMAND: "rtloop98"
>               [ 98] PID: 17119  TASK: ffff88010190d500  COMMAND: "rtloop1"
>                     PID: 17121  TASK: ffff88013bd27500  COMMAND: "rtloop1"
>                     PID: 17120  TASK: ffff88010190caa0  COMMAND: "rtloop1"
>   CFS RB_ROOT: ffff880028216718
...

> Hmm, I think the depth could not be that big. So how do you think this
> kind of output.
> 
> The attached patch just changed "CHILD" to "GROUP".

Interesting -- how did you set up the depth-greater-than-one scenario?

Anyway, given that it is possible, let's at least tighten up the output display
by changing each "9 * depth" usage to be "6 * depth".  That should alter
your example output to look like this:

CPU 0 RUNQUEUE: ffff880028216680
  CURRENT: PID: 17085  TASK: ffff880137c63540  COMMAND: "bash"
  RT PRIO_ARRAY: ffff880028216808                                       
     [  0] PID: 17129  TASK: ffff880037aeaaa0  COMMAND: "rtloop99"
           PID: 2832   TASK: ffff88013b09cae0  COMMAND: "rtkit-daemon"
           PID: 6      TASK: ffff88013d7c6080  COMMAND: "watchdog/0"
     [  1] GROUP RT PRIO_ARRAY: ffff88002ca65000                       
           [  1] GROUP RT PRIO_ARRAY: ffff880015821000                
                 [  1] PID: 17126  TASK: ffff880135d2a040  COMMAND: "rtloop98"
           [ 98] PID: 17119  TASK: ffff88010190d500  COMMAND: "rtloop1"
                 PID: 17121  TASK: ffff88013bd27500  COMMAND: "rtloop1"
                 PID: 17120  TASK: ffff88010190caa0  COMMAND: "rtloop1"
  CFS RB_ROOT: ffff880028216718
     ...

And also, I'd prefer to not create the dangling "static int depth", 
but rather to add a depth argument to dump_RT_prio_array(), where 
dump_CFS_runqueues() passes a 0, and dump_RT_prio_array() passes
"depth+1" to itself: 

static void
dump_RT_prio_array(int depth, ulong k_prio_array, char *u_prio_array)
{
	int i, c, tot, cnt, qheads;
	ulong offset, kvaddr, uvaddr;
	ulong list_head[2];
        struct list_data list_data, *ld;
	struct task_context *tc;
	ulong *tlist;
	ulong my_q, task_addr;
	char *rt_rq_buf;

	if (!depth)
		fprintf(fp, "  RT PRIO_ARRAY: %lx\n",  k_prio_array);

        qheads = (i = ARRAY_LENGTH(rt_prio_array_queue)) ?
                i : get_array_length("rt_prio_array.queue", NULL, SIZE(list_head));

	ld = &list_data;

	for (i = tot = 0; i < qheads; i++) {
		offset =  OFFSET(rt_prio_array_queue) + (i * SIZE(list_head));
		kvaddr = k_prio_array + offset;
		uvaddr = (ulong)u_prio_array + offset;
		BCOPY((char *)uvaddr, (char *)&list_head[0], sizeof(ulong)*2);

		if (CRASHDEBUG(1))
			fprintf(fp, "rt_prio_array[%d] @ %lx => %lx/%lx\n", 
				i, kvaddr, list_head[0], list_head[1]);

		if ((list_head[0] == kvaddr) && (list_head[1] == kvaddr))
			continue;

		INDENT(5 + 6 * depth);
		fprintf(fp, "[%3d] ", i);

		BZERO(ld, sizeof(struct list_data));
		ld->start = list_head[0];
		if (VALID_MEMBER(task_struct_rt) &&
		    VALID_MEMBER(sched_rt_entity_run_list))
			ld->list_head_offset = OFFSET(sched_rt_entity_run_list);
		else
			ld->list_head_offset = OFFSET(task_struct_run_list);
		ld->end = kvaddr;
		hq_open();
		cnt = do_list(ld);
		hq_close();
		tlist = (ulong *)GETBUF((cnt) * sizeof(ulong));
		cnt = retrieve_list(tlist, cnt);
		for (c = 0; c < cnt; c++) {
			task_addr = tlist[c];
			if (VALID_MEMBER(sched_rt_entity_my_q)) {
				readmem(tlist[c] + OFFSET(sched_rt_entity_my_q),
					KVADDR, &my_q, sizeof(ulong), "my_q",
					FAULT_ON_ERROR);
				if (my_q) {
					rt_rq_buf = GETBUF(SIZE(rt_rq));
					readmem(my_q, KVADDR, rt_rq_buf,
						SIZE(rt_rq), "rt_rq",
						FAULT_ON_ERROR);
					if (c)
						INDENT(11 + 6 * depth);
					fprintf(fp, "GROUP RT PRIO_ARRAY: %lx\n",
						my_q + OFFSET(rt_rq_active));
					tot++;
					dump_RT_prio_array(depth+1,
						my_q + OFFSET(rt_rq_active),
						&rt_rq_buf[OFFSET(rt_rq_active)]);
					continue;
				} else
					task_addr -= OFFSET(task_struct_rt);
			}
			if (!(tc = task_to_context(task_addr)))
				continue;
			if (c)
				INDENT(11 + 6 * depth);
			fprintf(fp, "PID: %-5ld  TASK: %lx  COMMAND: \"%s\"\n",
				tc->pid, tc->task, tc->comm);
			tot++;
		}
		FREEBUF(tlist);
	}

	if (!tot) {
		INDENT(5 + 6 * depth);
		fprintf(fp, "[no tasks queued]\n");	
	}
}

Can you verify that those changes work for you?

Thanks,
  Dave




More information about the Crash-utility mailing list