aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Capitulino <lcapitulino@mandriva.com.br>2006-03-21 01:16:40 -0500
committerDavid S. Miller <davem@davemloft.net>2006-03-21 01:16:40 -0500
commitcdcdbe0b179adca0bcf98f660fcc63e208ae4284 (patch)
tree06e20bb4e3dc8f5cacec067c8021aab2976c5971
parent222f18065868b04df92df476b19c99c28740e00f (diff)
[PKTGEN]: Ports thread list to Kernel list implementation.
The final result is a simpler and smaller code. Note that I'm adding a new member in the struct pktgen_thread called 'removed'. The reason is that I didn't find a better wait condition to be used in the place of the replaced one. Signed-off-by: Luiz Capitulino <lcapitulino@mandriva.com.br> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/pktgen.c96
1 files changed, 41 insertions, 55 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index e49b006a7654..f2c0e965c139 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -125,6 +125,7 @@
125#include <linux/capability.h> 125#include <linux/capability.h>
126#include <linux/delay.h> 126#include <linux/delay.h>
127#include <linux/timer.h> 127#include <linux/timer.h>
128#include <linux/list.h>
128#include <linux/init.h> 129#include <linux/init.h>
129#include <linux/skbuff.h> 130#include <linux/skbuff.h>
130#include <linux/netdevice.h> 131#include <linux/netdevice.h>
@@ -330,7 +331,8 @@ struct pktgen_hdr {
330struct pktgen_thread { 331struct pktgen_thread {
331 spinlock_t if_lock; 332 spinlock_t if_lock;
332 struct pktgen_dev *if_list; /* All device here */ 333 struct pktgen_dev *if_list; /* All device here */
333 struct pktgen_thread *next; 334 struct list_head th_list;
335 int removed;
334 char name[32]; 336 char name[32];
335 char result[512]; 337 char result[512];
336 u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */ 338 u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
@@ -492,7 +494,7 @@ static int pg_clone_skb_d;
492static int debug; 494static int debug;
493 495
494static DECLARE_MUTEX(pktgen_sem); 496static DECLARE_MUTEX(pktgen_sem);
495static struct pktgen_thread *pktgen_threads = NULL; 497static LIST_HEAD(pktgen_threads);
496 498
497static struct notifier_block pktgen_notifier_block = { 499static struct notifier_block pktgen_notifier_block = {
498 .notifier_call = pktgen_device_event, 500 .notifier_call = pktgen_device_event,
@@ -1522,9 +1524,7 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove)
1522 struct pktgen_thread *t; 1524 struct pktgen_thread *t;
1523 struct pktgen_dev *pkt_dev = NULL; 1525 struct pktgen_dev *pkt_dev = NULL;
1524 1526
1525 t = pktgen_threads; 1527 list_for_each_entry(t, &pktgen_threads, th_list) {
1526
1527 while (t) {
1528 pkt_dev = pktgen_find_dev(t, ifname); 1528 pkt_dev = pktgen_find_dev(t, ifname);
1529 if (pkt_dev) { 1529 if (pkt_dev) {
1530 if (remove) { 1530 if (remove) {
@@ -1535,7 +1535,6 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove)
1535 } 1535 }
1536 break; 1536 break;
1537 } 1537 }
1538 t = t->next;
1539 } 1538 }
1540 return pkt_dev; 1539 return pkt_dev;
1541} 1540}
@@ -2455,15 +2454,15 @@ static void pktgen_run(struct pktgen_thread *t)
2455 2454
2456static void pktgen_stop_all_threads_ifs(void) 2455static void pktgen_stop_all_threads_ifs(void)
2457{ 2456{
2458 struct pktgen_thread *t = pktgen_threads; 2457 struct pktgen_thread *t;
2459 2458
2460 PG_DEBUG(printk("pktgen: entering pktgen_stop_all_threads_ifs.\n")); 2459 PG_DEBUG(printk("pktgen: entering pktgen_stop_all_threads_ifs.\n"));
2461 2460
2462 thread_lock(); 2461 thread_lock();
2463 while (t) { 2462
2463 list_for_each_entry(t, &pktgen_threads, th_list)
2464 t->control |= T_STOP; 2464 t->control |= T_STOP;
2465 t = t->next; 2465
2466 }
2467 thread_unlock(); 2466 thread_unlock();
2468} 2467}
2469 2468
@@ -2503,40 +2502,36 @@ signal:
2503 2502
2504static int pktgen_wait_all_threads_run(void) 2503static int pktgen_wait_all_threads_run(void)
2505{ 2504{
2506 struct pktgen_thread *t = pktgen_threads; 2505 struct pktgen_thread *t;
2507 int sig = 1; 2506 int sig = 1;
2508 2507
2509 while (t) { 2508 thread_lock();
2509
2510 list_for_each_entry(t, &pktgen_threads, th_list) {
2510 sig = pktgen_wait_thread_run(t); 2511 sig = pktgen_wait_thread_run(t);
2511 if (sig == 0) 2512 if (sig == 0)
2512 break; 2513 break;
2513 thread_lock();
2514 t = t->next;
2515 thread_unlock();
2516 } 2514 }
2517 if (sig == 0) { 2515
2518 thread_lock(); 2516 if (sig == 0)
2519 while (t) { 2517 list_for_each_entry(t, &pktgen_threads, th_list)
2520 t->control |= (T_STOP); 2518 t->control |= (T_STOP);
2521 t = t->next; 2519
2522 } 2520 thread_unlock();
2523 thread_unlock();
2524 }
2525 return sig; 2521 return sig;
2526} 2522}
2527 2523
2528static void pktgen_run_all_threads(void) 2524static void pktgen_run_all_threads(void)
2529{ 2525{
2530 struct pktgen_thread *t = pktgen_threads; 2526 struct pktgen_thread *t;
2531 2527
2532 PG_DEBUG(printk("pktgen: entering pktgen_run_all_threads.\n")); 2528 PG_DEBUG(printk("pktgen: entering pktgen_run_all_threads.\n"));
2533 2529
2534 thread_lock(); 2530 thread_lock();
2535 2531
2536 while (t) { 2532 list_for_each_entry(t, &pktgen_threads, th_list)
2537 t->control |= (T_RUN); 2533 t->control |= (T_RUN);
2538 t = t->next; 2534
2539 }
2540 thread_unlock(); 2535 thread_unlock();
2541 2536
2542 schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */ 2537 schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */
@@ -2693,24 +2688,12 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
2693{ 2688{
2694 /* Remove from the thread list */ 2689 /* Remove from the thread list */
2695 2690
2696 struct pktgen_thread *tmp = pktgen_threads;
2697
2698 remove_proc_entry(t->name, pg_proc_dir); 2691 remove_proc_entry(t->name, pg_proc_dir);
2699 2692
2700 thread_lock(); 2693 thread_lock();
2701 2694
2702 if (tmp == t) 2695 list_del(&t->th_list);
2703 pktgen_threads = tmp->next; 2696
2704 else {
2705 while (tmp) {
2706 if (tmp->next == t) {
2707 tmp->next = t->next;
2708 t->next = NULL;
2709 break;
2710 }
2711 tmp = tmp->next;
2712 }
2713 }
2714 thread_unlock(); 2697 thread_unlock();
2715} 2698}
2716 2699
@@ -2969,6 +2952,8 @@ static void pktgen_thread_worker(struct pktgen_thread *t)
2969 2952
2970 PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name)); 2953 PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name));
2971 pktgen_rem_thread(t); 2954 pktgen_rem_thread(t);
2955
2956 t->removed = 1;
2972} 2957}
2973 2958
2974static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, 2959static 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)
3081 3066
3082static struct pktgen_thread *__init pktgen_find_thread(const char *name) 3067static struct pktgen_thread *__init pktgen_find_thread(const char *name)
3083{ 3068{
3084 struct pktgen_thread *t = NULL; 3069 struct pktgen_thread *t;
3085 3070
3086 thread_lock(); 3071 thread_lock();
3087 3072
3088 t = pktgen_threads; 3073 list_for_each_entry(t, &pktgen_threads, th_list)
3089 while (t) { 3074 if (strcmp(t->name, name) == 0) {
3090 if (strcmp(t->name, name) == 0) 3075 thread_unlock();
3091 break; 3076 return t;
3077 }
3092 3078
3093 t = t->next;
3094 }
3095 thread_unlock(); 3079 thread_unlock();
3096 return t; 3080 return NULL;
3097} 3081}
3098 3082
3099static int __init pktgen_create_thread(const char *name, int cpu) 3083static 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)
3132 pe->proc_fops = &pktgen_thread_fops; 3116 pe->proc_fops = &pktgen_thread_fops;
3133 pe->data = t; 3117 pe->data = t;
3134 3118
3135 t->next = pktgen_threads; 3119 list_add_tail(&t->th_list, &pktgen_threads);
3136 pktgen_threads = t; 3120
3121 t->removed = 0;
3137 3122
3138 if (kernel_thread((void *)pktgen_thread_worker, (void *)t, 3123 if (kernel_thread((void *)pktgen_thread_worker, (void *)t,
3139 CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0) 3124 CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0)
@@ -3234,17 +3219,18 @@ static int __init pg_init(void)
3234 3219
3235static void __exit pg_cleanup(void) 3220static void __exit pg_cleanup(void)
3236{ 3221{
3222 struct pktgen_thread *t;
3223 struct list_head *q, *n;
3237 wait_queue_head_t queue; 3224 wait_queue_head_t queue;
3238 init_waitqueue_head(&queue); 3225 init_waitqueue_head(&queue);
3239 3226
3240 /* Stop all interfaces & threads */ 3227 /* Stop all interfaces & threads */
3241 3228
3242 while (pktgen_threads) { 3229 list_for_each_safe(q, n, &pktgen_threads) {
3243 struct pktgen_thread *t = pktgen_threads; 3230 t = list_entry(q, struct pktgen_thread, th_list);
3244 pktgen_threads->control |= (T_TERMINATE); 3231 t->control |= (T_TERMINATE);
3245 3232
3246 wait_event_interruptible_timeout(queue, (t != pktgen_threads), 3233 wait_event_interruptible_timeout(queue, (t->removed == 1), HZ);
3247 HZ);
3248 } 3234 }
3249 3235
3250 /* Un-register us from receiving netdevice events */ 3236 /* Un-register us from receiving netdevice events */