Name: Extra debugging stuff for hotplug CPU. Author: Rusty Russell Status: Booted on 2.6.0-test6-bk1 Depends: Hotcpu/hotcpu-i386.patch.gz D: For chasing down the sleeping tasks bug. diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .16933-linux-2.6.0-test7-bk4/kernel/workqueue.c .16933-linux-2.6.0-test7-bk4.updated/kernel/workqueue.c --- .16933-linux-2.6.0-test7-bk4/kernel/workqueue.c 2003-10-13 08:55:21.000000000 +1000 +++ .16933-linux-2.6.0-test7-bk4.updated/kernel/workqueue.c 2003-10-13 08:55:22.000000000 +1000 @@ -348,6 +367,26 @@ int current_is_keventd(void) return 0; } +void show_workqueues(void) +{ + struct workqueue_struct *wq; + unsigned int cpu; + extern void show_blk(void); + + show_blk(); + list_for_each_entry(wq, &workqueues, list) { + for_each_cpu(cpu) + printk("%s: %u: %s %p %i %li %li\n", + wq->name, cpu, + list_empty(&wq->cpu_wq[cpu].worklist) + ? "EMPTY" : "SOME", + wq->cpu_wq[cpu].worker, + waitqueue_active(&wq->cpu_wq[cpu].work_done), + wq->cpu_wq[cpu].insert_sequence, + wq->cpu_wq[cpu].remove_sequence); + } +} + #ifdef CONFIG_HOTPLUG_CPU /* Take the work from this (downed) CPU. */ static void take_over_work(struct workqueue_struct *wq, unsigned int cpu) diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11453-2.6.0-test6-bk7-hotcpu-i386.pre/drivers/block/ll_rw_blk.c .11453-2.6.0-test6-bk7-hotcpu-i386/drivers/block/ll_rw_blk.c --- .11453-2.6.0-test6-bk7-hotcpu-i386.pre/drivers/block/ll_rw_blk.c 2003-10-06 06:14:00.000000000 +1000 +++ .11453-2.6.0-test6-bk7-hotcpu-i386/drivers/block/ll_rw_blk.c 2003-10-06 16:17:51.000000000 +1000 @@ -99,6 +99,8 @@ static void clear_queue_congested(reques enum bdi_state bit; wait_queue_head_t *wqh = &congestion_wqh[rw]; + printk("clear_queue_congested %p %i on %u\n", + q, rw, smp_processor_id()); bit = (rw == WRITE) ? BDI_write_congested : BDI_read_congested; clear_bit(bit, &q->backing_dev_info.state); if (waitqueue_active(wqh)) @@ -1786,6 +1788,10 @@ void blk_put_request(struct request *req } } +#include +#include +static DEFINE_PER_CPU(local_t, blk_congestion_count); + /** * blk_congestion_wait - wait for a queue to become uncongested * @rw: READ or WRITE @@ -1800,10 +1806,38 @@ void blk_congestion_wait(int rw, long ti DEFINE_WAIT(wait); wait_queue_head_t *wqh = &congestion_wqh[rw]; + cpu_local_inc(blk_congestion_count); blk_run_queues(); prepare_to_wait(wqh, &wait, TASK_UNINTERRUPTIBLE); io_schedule_timeout(timeout); finish_wait(wqh, &wait); + cpu_local_dec(blk_congestion_count); +} + + +void show_blk(void) +{ + unsigned int cpu; + wait_queue_t *w; + wait_queue_head_t *wqh; + + for_each_cpu(cpu) + printk("blk_congestion_count for %u: %li\n", + cpu, local_read(&per_cpu(blk_congestion_count, cpu))); + + wqh = &congestion_wqh[READ]; + spin_lock(&wqh->lock); + printk("Waiting for read congestion:\n"); + list_for_each_entry(w, &wqh->task_list, task_list) + printk("%s: %u\n", w->task->comm, w->task->pid); + spin_unlock(&wqh->lock); + + wqh = &congestion_wqh[WRITE]; + spin_lock(&wqh->lock); + printk("Waiting for write congestion:\n"); + list_for_each_entry(w, &wqh->task_list, task_list) + printk("%s: %u\n", w->task->comm, w->task->pid); + spin_unlock(&wqh->lock); } /* diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .11453-2.6.0-test6-bk7-hotcpu-i386.pre/drivers/char/sysrq.c .11453-2.6.0-test6-bk7-hotcpu-i386/drivers/char/sysrq.c --- .11453-2.6.0-test6-bk7-hotcpu-i386.pre/drivers/char/sysrq.c 2003-09-29 10:25:26.000000000 +1000 +++ .11453-2.6.0-test6-bk7-hotcpu-i386/drivers/char/sysrq.c 2003-10-06 16:17:51.000000000 +1000 @@ -214,6 +214,19 @@ static struct sysrq_key_op sysrq_kill_op .action_msg = "Kill All Tasks", }; +static void sysrq_handle_workqueues(int key, struct pt_regs *pt_regs, + struct tty_struct *tty) +{ + extern void show_workqueues(void); + + show_workqueues(); +} +static struct sysrq_key_op sysrq_workqueueus_op = { + .handler = sysrq_handle_workqueues, + .help_msg = "Workq", + .action_msg = "Showing Workqueues", +}; + /* END SIGNAL SYSRQ HANDLERS BLOCK */ @@ -264,7 +277,7 @@ static struct sysrq_key_op *sysrq_key_ta /* t */ &sysrq_showstate_op, /* u */ &sysrq_mountro_op, /* v */ NULL, /* May be assigned at init time by SMP VOYAGER */ -/* w */ NULL, +/* w */ &sysrq_workqueueus_op, /* x */ NULL, /* y */ NULL, /* z */ NULL