]>
Commit | Line | Data |
---|---|---|
2532c0bb CW |
1 | From stable-bounces@linux.kernel.org Mon Jan 1 21:11:24 2007 |
2 | Date: Mon, 01 Jan 2007 21:04:19 -0800 (PST) | |
3 | Message-Id: <20070101.210419.104643422.davem@davemloft.net> | |
4 | To: stable@kernel.org | |
5 | From: David Miller <davem@davemloft.net> | |
6 | Cc: bunk@stusta.de | |
7 | Subject: PKTGEN: Fix module load/unload races. | |
8 | ||
9 | From: Robert Olsson <Robert.Olsson@data.slu.se> | |
10 | ||
11 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
12 | Signed-off-by: Chris Wright <chrisw@sous-sol.org> | |
13 | ||
14 | --- | |
15 | net/core/pktgen.c | 20 ++++++++++++++++++-- | |
16 | 1 file changed, 18 insertions(+), 2 deletions(-) | |
17 | ||
18 | --- linux-2.6.19.1.orig/net/core/pktgen.c | |
19 | +++ linux-2.6.19.1/net/core/pktgen.c | |
20 | @@ -147,6 +147,7 @@ | |
21 | #include <linux/proc_fs.h> | |
22 | #include <linux/seq_file.h> | |
23 | #include <linux/wait.h> | |
24 | +#include <linux/completion.h> | |
25 | #include <linux/etherdevice.h> | |
26 | #include <net/checksum.h> | |
27 | #include <net/ipv6.h> | |
28 | @@ -206,6 +207,11 @@ static struct proc_dir_entry *pg_proc_di | |
29 | #define VLAN_TAG_SIZE(x) ((x)->vlan_id == 0xffff ? 0 : 4) | |
30 | #define SVLAN_TAG_SIZE(x) ((x)->svlan_id == 0xffff ? 0 : 4) | |
31 | ||
32 | +struct pktgen_thread_info { | |
33 | + struct pktgen_thread *t; | |
34 | + struct completion *c; | |
35 | +}; | |
36 | + | |
37 | struct flow_state { | |
38 | __u32 cur_daddr; | |
39 | int count; | |
40 | @@ -3264,10 +3270,11 @@ out:; | |
41 | * Main loop of the thread goes here | |
42 | */ | |
43 | ||
44 | -static void pktgen_thread_worker(struct pktgen_thread *t) | |
45 | +static void pktgen_thread_worker(struct pktgen_thread_info *info) | |
46 | { | |
47 | DEFINE_WAIT(wait); | |
48 | struct pktgen_dev *pkt_dev = NULL; | |
49 | + struct pktgen_thread *t = info->t; | |
50 | int cpu = t->cpu; | |
51 | sigset_t tmpsig; | |
52 | u32 max_before_softirq; | |
53 | @@ -3307,6 +3314,8 @@ static void pktgen_thread_worker(struct | |
54 | __set_current_state(TASK_INTERRUPTIBLE); | |
55 | mb(); | |
56 | ||
57 | + complete(info->c); | |
58 | + | |
59 | while (1) { | |
60 | ||
61 | __set_current_state(TASK_RUNNING); | |
62 | @@ -3518,6 +3527,8 @@ static struct pktgen_thread *__init pktg | |
63 | static int __init pktgen_create_thread(const char *name, int cpu) | |
64 | { | |
65 | int err; | |
66 | + struct pktgen_thread_info info; | |
67 | + struct completion started; | |
68 | struct pktgen_thread *t = NULL; | |
69 | struct proc_dir_entry *pe; | |
70 | ||
71 | @@ -3558,7 +3569,11 @@ static int __init pktgen_create_thread(c | |
72 | ||
73 | t->removed = 0; | |
74 | ||
75 | - err = kernel_thread((void *)pktgen_thread_worker, (void *)t, | |
76 | + init_completion(&started); | |
77 | + info.t = t; | |
78 | + info.c = &started; | |
79 | + | |
80 | + err = kernel_thread((void *)pktgen_thread_worker, (void *)&info, | |
81 | CLONE_FS | CLONE_FILES | CLONE_SIGHAND); | |
82 | if (err < 0) { | |
83 | printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu); | |
84 | @@ -3568,6 +3583,7 @@ static int __init pktgen_create_thread(c | |
85 | return err; | |
86 | } | |
87 | ||
88 | + wait_for_completion(&started); | |
89 | return 0; | |
90 | } | |
91 |