Commit cdcdbe0b authored by Luiz Capitulino's avatar Luiz Capitulino Committed by David S. Miller

[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: default avatarLuiz Capitulino <lcapitulino@mandriva.com.br>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 222f1806
...@@ -125,6 +125,7 @@ ...@@ -125,6 +125,7 @@
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/list.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
...@@ -330,7 +331,8 @@ struct pktgen_hdr { ...@@ -330,7 +331,8 @@ struct pktgen_hdr {
struct pktgen_thread { struct pktgen_thread {
spinlock_t if_lock; spinlock_t if_lock;
struct pktgen_dev *if_list; /* All device here */ struct pktgen_dev *if_list; /* All device here */
struct pktgen_thread *next; struct list_head th_list;
int removed;
char name[32]; char name[32];
char result[512]; char result[512];
u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */ u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
...@@ -492,7 +494,7 @@ static int pg_clone_skb_d; ...@@ -492,7 +494,7 @@ static int pg_clone_skb_d;
static int debug; static int debug;
static DECLARE_MUTEX(pktgen_sem); static DECLARE_MUTEX(pktgen_sem);
static struct pktgen_thread *pktgen_threads = NULL; static LIST_HEAD(pktgen_threads);
static struct notifier_block pktgen_notifier_block = { static struct notifier_block pktgen_notifier_block = {
.notifier_call = pktgen_device_event, .notifier_call = pktgen_device_event,
...@@ -1522,9 +1524,7 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove) ...@@ -1522,9 +1524,7 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove)
struct pktgen_thread *t; struct pktgen_thread *t;
struct pktgen_dev *pkt_dev = NULL; struct pktgen_dev *pkt_dev = NULL;
t = pktgen_threads; list_for_each_entry(t, &pktgen_threads, th_list) {
while (t) {
pkt_dev = pktgen_find_dev(t, ifname); pkt_dev = pktgen_find_dev(t, ifname);
if (pkt_dev) { if (pkt_dev) {
if (remove) { if (remove) {
...@@ -1535,7 +1535,6 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove) ...@@ -1535,7 +1535,6 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove)
} }
break; break;
} }
t = t->next;
} }
return pkt_dev; return pkt_dev;
} }
...@@ -2455,15 +2454,15 @@ static void pktgen_run(struct pktgen_thread *t) ...@@ -2455,15 +2454,15 @@ static void pktgen_run(struct pktgen_thread *t)
static void pktgen_stop_all_threads_ifs(void) 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")); PG_DEBUG(printk("pktgen: entering pktgen_stop_all_threads_ifs.\n"));
thread_lock(); thread_lock();
while (t) {
list_for_each_entry(t, &pktgen_threads, th_list)
t->control |= T_STOP; t->control |= T_STOP;
t = t->next;
}
thread_unlock(); thread_unlock();
} }
...@@ -2503,40 +2502,36 @@ static int pktgen_wait_thread_run(struct pktgen_thread *t) ...@@ -2503,40 +2502,36 @@ static int pktgen_wait_thread_run(struct pktgen_thread *t)
static int pktgen_wait_all_threads_run(void) static int pktgen_wait_all_threads_run(void)
{ {
struct pktgen_thread *t = pktgen_threads; struct pktgen_thread *t;
int sig = 1; int sig = 1;
while (t) { thread_lock();
list_for_each_entry(t, &pktgen_threads, th_list) {
sig = pktgen_wait_thread_run(t); sig = pktgen_wait_thread_run(t);
if (sig == 0) if (sig == 0)
break; break;
thread_lock();
t = t->next;
thread_unlock();
} }
if (sig == 0) {
thread_lock(); if (sig == 0)
while (t) { list_for_each_entry(t, &pktgen_threads, th_list)
t->control |= (T_STOP); t->control |= (T_STOP);
t = t->next;
}
thread_unlock(); thread_unlock();
}
return sig; return sig;
} }
static void pktgen_run_all_threads(void) 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")); PG_DEBUG(printk("pktgen: entering pktgen_run_all_threads.\n"));
thread_lock(); thread_lock();
while (t) { list_for_each_entry(t, &pktgen_threads, th_list)
t->control |= (T_RUN); t->control |= (T_RUN);
t = t->next;
}
thread_unlock(); thread_unlock();
schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */ schedule_timeout_interruptible(msecs_to_jiffies(125)); /* Propagate thread->control */
...@@ -2693,24 +2688,12 @@ static void pktgen_rem_thread(struct pktgen_thread *t) ...@@ -2693,24 +2688,12 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
{ {
/* Remove from the thread list */ /* Remove from the thread list */
struct pktgen_thread *tmp = pktgen_threads;
remove_proc_entry(t->name, pg_proc_dir); remove_proc_entry(t->name, pg_proc_dir);
thread_lock(); thread_lock();
if (tmp == t) list_del(&t->th_list);
pktgen_threads = tmp->next;
else {
while (tmp) {
if (tmp->next == t) {
tmp->next = t->next;
t->next = NULL;
break;
}
tmp = tmp->next;
}
}
thread_unlock(); thread_unlock();
} }
...@@ -2969,6 +2952,8 @@ static void pktgen_thread_worker(struct pktgen_thread *t) ...@@ -2969,6 +2952,8 @@ static void pktgen_thread_worker(struct pktgen_thread *t)
PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name)); PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name));
pktgen_rem_thread(t); pktgen_rem_thread(t);
t->removed = 1;
} }
static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, 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) ...@@ -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) static struct pktgen_thread *__init pktgen_find_thread(const char *name)
{ {
struct pktgen_thread *t = NULL; struct pktgen_thread *t;
thread_lock(); thread_lock();
t = pktgen_threads; list_for_each_entry(t, &pktgen_threads, th_list)
while (t) { if (strcmp(t->name, name) == 0) {
if (strcmp(t->name, name) == 0)
break;
t = t->next;
}
thread_unlock(); thread_unlock();
return t; return t;
}
thread_unlock();
return NULL;
} }
static int __init pktgen_create_thread(const char *name, int cpu) 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) ...@@ -3132,8 +3116,9 @@ static int __init pktgen_create_thread(const char *name, int cpu)
pe->proc_fops = &pktgen_thread_fops; pe->proc_fops = &pktgen_thread_fops;
pe->data = t; pe->data = t;
t->next = pktgen_threads; list_add_tail(&t->th_list, &pktgen_threads);
pktgen_threads = t;
t->removed = 0;
if (kernel_thread((void *)pktgen_thread_worker, (void *)t, if (kernel_thread((void *)pktgen_thread_worker, (void *)t,
CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0) CLONE_FS | CLONE_FILES | CLONE_SIGHAND) < 0)
...@@ -3234,17 +3219,18 @@ static int __init pg_init(void) ...@@ -3234,17 +3219,18 @@ static int __init pg_init(void)
static void __exit pg_cleanup(void) static void __exit pg_cleanup(void)
{ {
struct pktgen_thread *t;
struct list_head *q, *n;
wait_queue_head_t queue; wait_queue_head_t queue;
init_waitqueue_head(&queue); init_waitqueue_head(&queue);
/* Stop all interfaces & threads */ /* Stop all interfaces & threads */
while (pktgen_threads) { list_for_each_safe(q, n, &pktgen_threads) {
struct pktgen_thread *t = pktgen_threads; t = list_entry(q, struct pktgen_thread, th_list);
pktgen_threads->control |= (T_TERMINATE); t->control |= (T_TERMINATE);
wait_event_interruptible_timeout(queue, (t != pktgen_threads), wait_event_interruptible_timeout(queue, (t->removed == 1), HZ);
HZ);
} }
/* Un-register us from receiving netdevice events */ /* Un-register us from receiving netdevice events */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment