diff options
-rw-r--r-- | net/core/pktgen.c | 96 |
1 files changed, 41 insertions, 55 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index e49b006a765..f2c0e965c13 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -125,6 +125,7 @@ #include <linux/capability.h> #include <linux/delay.h> #include <linux/timer.h> +#include <linux/list.h> #include <linux/init.h> #include <linux/skbuff.h> #include <linux/netdevice.h> @@ -330,7 +331,8 @@ struct pktgen_hdr { struct pktgen_thread { spinlock_t if_lock; struct pktgen_dev *if_list; /* All device here */ - struct pktgen_thread *next; + struct list_head th_list; + int removed; char name[32]; char result[512]; u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */ @@ -492,7 +494,7 @@ static int pg_clone_skb_d; static int debug; static DECLARE_MUTEX(pktgen_sem); -static struct pktgen_thread *pktgen_threads = NULL; +static LIST_HEAD(pktgen_threads); static struct notifier_block pktgen_notifier_block = { .notifier_call = pktgen_device_event, @@ -1522,9 +1524,7 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove) struct pktgen_thread *t; struct pktgen_dev *pkt_dev = NULL; - t = pktgen_threads; - - while (t) { + list_for_each_entry(t, &pktgen_threads, th_list) { pkt_dev = pktgen_find_dev(t, ifname); if (pkt_dev) { if (remove) { @@ -1535,7 +1535,6 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove) } break; } - t = t->next; } return pkt_dev; } @@ -2455,15 +2454,15 @@ static void pktgen_run(struct pktgen_thread *t) static void pktgen_stop_all_threads_ifs(void) { - struct pktgen_thread *t = pktgen_threads; + struct pktgen_thread *t; PG_DEBUG(printk("pktgen: entering pktgen_stop_all_threads_ifs.\n")); thread_lock(); - while (t) { + + list_for_each_entry(t, &pktgen_threads, th_list) t->control |= T_STOP; - t = t->next; - } + thread_unlock(); } @@ -2503,40 +2502,36 @@ signal: static int pktgen_wait_all_threads_run(void) { - struct pktgen_thread *t = pktgen_threads; + struct pktgen_thread *t; int sig = 1; - while (t) { + thread_lock(); + + list_for_each_entry(t, &pktgen_threads, th_list) { sig = pktgen_wait_thread_run(t); if (sig == 0) break; - thread_lock(); - t = t->next; - thread_unlock(); } - if (sig == 0) { - thread_lock(); - while (t) { + + if (sig == 0) + list_for_each_entry(t, &pktgen_threads, th_list) t->control |= (T_STOP); - t = t->next; - } - thread_unlock(); - } + + thread_unlock(); return sig; } static void pktgen_run_all_threads(void) { - struct pktgen_thread *t = pktgen_threads; + struct pktgen_thread *t; PG_DEBUG(printk("pktgen: entering pktgen_run_all_threads.\n")); thread_lock(); - while (t) { + list_for_each_entry(t, &pktgen_threads, th_list) t->control |= (T_RUN); - t = t->next; - } + thread_unlock(); schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */ @@ -2693,24 +2688,12 @@ static void pktgen_rem_thread(struct pktgen_thread *t) { /* Remove from the thread list */ - struct pktgen_thread *tmp = pktgen_threads; - remove_proc_entry(t->name, pg_proc_dir); thread_lock(); - if (tmp == t) - pktgen_threads = tmp->next; - else { - while (tmp) { - if (tmp->next == t) { - tmp->next = t->next; - t->next = NULL; - break; - } - tmp = tmp->next; - } - } + list_del(&t->th_list); + thread_unlock(); } @@ -2969,6 +2952,8 @@ static void pktgen_thread_worker(struct pktgen_thread *t) PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name)); pktgen_rem_thread(t); + + t->removed = 1; } static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, @@ -3081,19 +3066,18 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) static struct pktgen_thread *__init pktgen_find_thread(const char *name) { - struct pktgen_thread *t = NULL; + struct pktgen_thread *t; thread_lock(); - t = pktgen_threads; - while (t) { - if (strcmp(t->name, name) == 0) - break; + list_for_each_entry(t, &pktgen_threads, th_list) + if (strcmp(t->name, name) == 0) { + thread_unlock(); + return t; + } - t = t->next; - } thread_unlock(); - return t; + return NULL; } static int __init pktgen_create_thread(const char *name, int cpu) @@ -3132,8 +3116,9 @@ static int __init pktgen_create_thread(const char *name, int cpu) pe->proc_fops = &pktgen_thread_fops; pe->data = t; - t->next = pktgen_threads; - pktgen_threads = t; + list_add_tail(&t->th_list, &pktgen_threads); + + t->removed = 0; if (kernel_thread((void *)pktgen_thread_worker, (void *)t, CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0) @@ -3234,17 +3219,18 @@ static int __init pg_init(void) static void __exit pg_cleanup(void) { + struct pktgen_thread *t; + struct list_head *q, *n; wait_queue_head_t queue; init_waitqueue_head(&queue); /* Stop all interfaces & threads */ - while (pktgen_threads) { - struct pktgen_thread *t = pktgen_threads; - pktgen_threads->control |= (T_TERMINATE); + list_for_each_safe(q, n, &pktgen_threads) { + t = list_entry(q, struct pktgen_thread, th_list); + t->control |= (T_TERMINATE); - wait_event_interruptible_timeout(queue, (t != pktgen_threads), - HZ); + wait_event_interruptible_timeout(queue, (t->removed == 1), HZ); } /* Un-register us from receiving netdevice events */ |