pktgen: Ports thread list to Kernel list implementation.
Subsystems (2)
PATCH 2/4 pktgen: Ports thread list to Kernel list implementation.
Ports the thread list to use the Linux Kernel linked 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. Suggestions are very welcome.
Signed-off-by Luiz Capitulino <[email protected]>
---
net/core/pktgen.c | 96 +++++++++++++++++++++++------------------------------ 1 files changed, 41 insertions(+), 55 deletions(-)
3679f7d860ed28c86f0c8e1d6c1b4d9ee1e716d7
net/core/pktgen.c +41 -55
@@ -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>
@@ -327,7 +328,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. */
@@ -489,7 +491,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_thstruct 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) {
@@ -1534,7 +1534,6 @@ static struct pktgen_dev *__pktgen_NN_th }break ; } - t = t->next; }return pkt_dev; }
@@ -2422,15 +2421,15 @@ static void pktgen_run(struct pktgen_thrstatic 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.\n" ));thread_lock (); -while (t) { + +list_for_each_entry (t, &pktgen_threads, th_list)pktgen_stop (t); - t = t->next; - } +thread_unlock (); }
@@ -2472,40 +2471,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 */
@@ -2625,24 +2620,12 @@ static void pktgen_rem_thread(struct pkt {/* 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 (); }
@@ -2890,6 +2873,8 @@ static void pktgen_thread_worker(structPG_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,
@@ -3001,19 +2986,18 @@ static int pktgen_add_device(struct pktgstatic 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)
@@ -3052,8 +3036,9 @@ static int __init pktgen_create_thread(c 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 )
@@ -3154,17 +3139,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 */
Signature · 5 lines
1.1.5.g3480 -- Luiz Fernando N. Capitulino