]> git.ipfire.org Git - people/ms/linux.git/commitdiff
[PKTGEN]: Fix module load/unload races.
authorRobert Olsson <data.slu.se>
Wed, 3 Jan 2007 23:57:17 +0000 (00:57 +0100)
committerAdrian Bunk <bunk@stusta.de>
Thu, 4 Jan 2007 00:02:58 +0000 (01:02 +0100)
Adrian Bunk:
Backported to 2.6.16.

Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
net/core/pktgen.c

index 47d0c28ae39083747e617836c326989ca1af7dd9..6e972e489b6dd078b9eb1fe3fb9ea3719c648fff 100644 (file)
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/wait.h>
+#include <linux/completion.h>
 #include <linux/etherdevice.h>
 #include <net/checksum.h>
 #include <net/ipv6.h>
@@ -194,6 +195,11 @@ static struct proc_dir_entry *pg_proc_dir = NULL;
 
 #define MAX_CFLOWS  65536
 
+struct pktgen_thread_info {
+       struct pktgen_thread *t;
+       struct completion *c;
+};
+
 struct flow_state
 {
        __u32           cur_daddr;
@@ -2656,10 +2662,11 @@ retry_now:
  * Main loop of the thread goes here
  */
 
-static void pktgen_thread_worker(struct pktgen_thread *t) 
+static void pktgen_thread_worker(struct pktgen_thread_info *info)
 {
        DEFINE_WAIT(wait);
         struct pktgen_dev *pkt_dev = NULL;
+       struct pktgen_thread *t = info->t;
        int cpu = t->cpu;
        sigset_t tmpsig;
        u32 max_before_softirq;
@@ -2700,6 +2707,8 @@ static void pktgen_thread_worker(struct pktgen_thread *t)
         __set_current_state(TASK_INTERRUPTIBLE);
         mb();
 
+        complete(info->c);
+
         while (1) {
                
                __set_current_state(TASK_RUNNING);
@@ -2894,6 +2903,8 @@ static struct pktgen_thread * __init pktgen_find_thread(const char* name)
 
 static int __init pktgen_create_thread(const char* name, int cpu) 
 {
+       struct pktgen_thread_info info;
+       struct completion started;
         struct pktgen_thread *t = NULL;
        struct proc_dir_entry *pe;
 
@@ -2931,10 +2942,15 @@ static int __init pktgen_create_thread(const char* name, int cpu)
         t->next = pktgen_threads;
         pktgen_threads = t;
 
-       if (kernel_thread((void *) pktgen_thread_worker, (void *) t, 
+       init_completion(&started);
+       info.t = t;
+       info.c = &started;
+
+       if (kernel_thread((void *) pktgen_thread_worker, (void *)&info, 
                          CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0)
                printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu);
 
+       wait_for_completion(&started);
        return 0;
 }