* [PATCH 2/4] pktgen: Ports thread list to Kernel list implementation.
@ 2006-01-30 1:21 Luiz Fernando Capitulino
0 siblings, 0 replies; only message in thread
From: Luiz Fernando Capitulino @ 2006-01-30 1:21 UTC (permalink / raw)
To: davem; +Cc: lkml, netdev, robert.olsson
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 <lcapitulino@mandriva.com.br>
---
net/core/pktgen.c | 96 +++++++++++++++++++++++------------------------------
1 files changed, 41 insertions(+), 55 deletions(-)
3679f7d860ed28c86f0c8e1d6c1b4d9ee1e716d7
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index a6a45b9..b9dea09 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>
@@ -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_th
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) {
@@ -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_thr
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.\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(struct
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,
@@ -3001,19 +2986,18 @@ static int pktgen_add_device(struct pktg
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)
@@ -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 */
--
1.1.5.g3480
--
Luiz Fernando N. Capitulino
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2006-01-30 1:24 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-30 1:21 [PATCH 2/4] pktgen: Ports thread list to Kernel list implementation Luiz Fernando Capitulino
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.