aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2008-05-20 18:12:44 -0400
committerDavid S. Miller <davem@davemloft.net>2008-05-20 18:12:44 -0400
commitd3ede327e83f202c3a0962e207318f65717c5eb7 (patch)
tree2875979c06b127edc325bf77518837c28477ebd5
parent5fb13570543f4ae022996c9d7c0c099c8abf22dd (diff)
pktgen: make sure that pktgen_thread_worker has been executed
The following courruption can happen during pktgen stop: list_del corruption. prev->next should be ffff81007e8a5e70, but was 6b6b6b6b6b6b6b6b kernel BUG at lib/list_debug.c:67! :pktgen:pktgen_thread_worker+0x374/0x10b0 ? autoremove_wake_function+0x0/0x40 ? _spin_unlock_irqrestore+0x42/0x80 ? :pktgen:pktgen_thread_worker+0x0/0x10b0 kthread+0x4d/0x80 child_rip+0xa/0x12 ? restore_args+0x0/0x30 ? kthread+0x0/0x80 ? child_rip+0x0/0x12 RIP list_del+0x48/0x70 The problem is that pktgen_thread_worker can not be executed if kthread_stop has been called too early. Insert a completion on the normal initialization path to make sure that pktgen_thread_worker will gain the control for sure. Signed-off-by: Denis V. Lunev <den@openvz.org> Acked-by: Alexey Dobriyan <adobriyan@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/pktgen.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 8dca21110493..fdf537707e51 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -390,6 +390,7 @@ struct pktgen_thread {
390 int cpu; 390 int cpu;
391 391
392 wait_queue_head_t queue; 392 wait_queue_head_t queue;
393 struct completion start_done;
393}; 394};
394 395
395#define REMOVE 1 396#define REMOVE 1
@@ -3414,6 +3415,7 @@ static int pktgen_thread_worker(void *arg)
3414 BUG_ON(smp_processor_id() != cpu); 3415 BUG_ON(smp_processor_id() != cpu);
3415 3416
3416 init_waitqueue_head(&t->queue); 3417 init_waitqueue_head(&t->queue);
3418 complete(&t->start_done);
3417 3419
3418 pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, task_pid_nr(current)); 3420 pr_debug("pktgen: starting pktgen/%d: pid=%d\n", cpu, task_pid_nr(current));
3419 3421
@@ -3615,6 +3617,7 @@ static int __init pktgen_create_thread(int cpu)
3615 INIT_LIST_HEAD(&t->if_list); 3617 INIT_LIST_HEAD(&t->if_list);
3616 3618
3617 list_add_tail(&t->th_list, &pktgen_threads); 3619 list_add_tail(&t->th_list, &pktgen_threads);
3620 init_completion(&t->start_done);
3618 3621
3619 p = kthread_create(pktgen_thread_worker, t, "kpktgend_%d", cpu); 3622 p = kthread_create(pktgen_thread_worker, t, "kpktgend_%d", cpu);
3620 if (IS_ERR(p)) { 3623 if (IS_ERR(p)) {
@@ -3639,6 +3642,7 @@ static int __init pktgen_create_thread(int cpu)
3639 } 3642 }
3640 3643
3641 wake_up_process(p); 3644 wake_up_process(p);
3645 wait_for_completion(&t->start_done);
3642 3646
3643 return 0; 3647 return 0;
3644} 3648}