Loading net/core/pktgen.c +48 −108 Original line number Diff line number Diff line Loading @@ -148,6 +148,7 @@ #include <linux/seq_file.h> #include <linux/wait.h> #include <linux/etherdevice.h> #include <linux/kthread.h> #include <net/checksum.h> #include <net/ipv6.h> #include <net/addrconf.h> Loading Loading @@ -360,8 +361,7 @@ struct pktgen_thread { spinlock_t if_lock; struct list_head if_list; /* All device here */ struct list_head th_list; int removed; char name[32]; struct task_struct *tsk; char result[512]; u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */ Loading Loading @@ -1689,7 +1689,7 @@ static int pktgen_thread_show(struct seq_file *seq, void *v) BUG_ON(!t); seq_printf(seq, "Name: %s max_before_softirq: %d\n", t->name, t->max_before_softirq); t->tsk->comm, t->max_before_softirq); seq_printf(seq, "Running: "); Loading Loading @@ -3112,7 +3112,7 @@ static void pktgen_rem_thread(struct pktgen_thread *t) { /* Remove from the thread list */ remove_proc_entry(t->name, pg_proc_dir); remove_proc_entry(t->tsk->comm, pg_proc_dir); mutex_lock(&pktgen_thread_lock); Loading Loading @@ -3260,58 +3260,40 @@ out:; * Main loop of the thread goes here */ static void pktgen_thread_worker(struct pktgen_thread *t) static int pktgen_thread_worker(void *arg) { DEFINE_WAIT(wait); struct pktgen_thread *t = arg; struct pktgen_dev *pkt_dev = NULL; int cpu = t->cpu; sigset_t tmpsig; u32 max_before_softirq; u32 tx_since_softirq = 0; daemonize("pktgen/%d", cpu); /* Block all signals except SIGKILL, SIGSTOP and SIGTERM */ spin_lock_irq(¤t->sighand->siglock); tmpsig = current->blocked; siginitsetinv(¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGTERM)); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); /* Migrate to the right CPU */ set_cpus_allowed(current, cpumask_of_cpu(cpu)); if (smp_processor_id() != cpu) BUG(); BUG_ON(smp_processor_id() != cpu); init_waitqueue_head(&t->queue); t->control &= ~(T_TERMINATE); t->control &= ~(T_RUN); t->control &= ~(T_STOP); t->control &= ~(T_REMDEVALL); t->control &= ~(T_REMDEV); t->pid = current->pid; PG_DEBUG(printk("pktgen: starting pktgen/%d: pid=%d\n", cpu, current->pid)); max_before_softirq = t->max_before_softirq; __set_current_state(TASK_INTERRUPTIBLE); mb(); set_current_state(TASK_INTERRUPTIBLE); while (1) { __set_current_state(TASK_RUNNING); while (!kthread_should_stop()) { pkt_dev = next_to_run(t); /* * Get next dev to xmit -- if any. */ if (!pkt_dev && (t->control & (T_STOP | T_RUN | T_REMDEVALL | T_REMDEV)) == 0) { prepare_to_wait(&(t->queue), &wait, TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); finish_wait(&(t->queue), &wait); } pkt_dev = next_to_run(t); __set_current_state(TASK_RUNNING); if (pkt_dev) { Loading @@ -3329,21 +3311,8 @@ static void pktgen_thread_worker(struct pktgen_thread *t) do_softirq(); tx_since_softirq = 0; } } else { prepare_to_wait(&(t->queue), &wait, TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); finish_wait(&(t->queue), &wait); } /* * Back from sleep, either due to the timeout or signal. * We check if we have any "posted" work for us. */ if (t->control & T_TERMINATE || signal_pending(current)) /* we received a request to terminate ourself */ break; if (t->control & T_STOP) { pktgen_stop(t); t->control &= ~(T_STOP); Loading @@ -3364,20 +3333,19 @@ static void pktgen_thread_worker(struct pktgen_thread *t) t->control &= ~(T_REMDEV); } if (need_resched()) schedule(); set_current_state(TASK_INTERRUPTIBLE); } PG_DEBUG(printk("pktgen: %s stopping all device\n", t->name)); PG_DEBUG(printk("pktgen: %s stopping all device\n", t->tsk->comm)); pktgen_stop(t); PG_DEBUG(printk("pktgen: %s removing all device\n", t->name)); PG_DEBUG(printk("pktgen: %s removing all device\n", t->tsk->comm)); pktgen_rem_all_ifs(t); PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name)); PG_DEBUG(printk("pktgen: %s removing thread.\n", t->tsk->comm)); pktgen_rem_thread(t); t->removed = 1; return 0; } static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, Loading Loading @@ -3495,37 +3463,11 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) return add_dev_to_thread(t, pkt_dev); } static struct pktgen_thread *__init pktgen_find_thread(const char *name) static int __init pktgen_create_thread(int cpu) { struct pktgen_thread *t; mutex_lock(&pktgen_thread_lock); list_for_each_entry(t, &pktgen_threads, th_list) if (strcmp(t->name, name) == 0) { mutex_unlock(&pktgen_thread_lock); return t; } mutex_unlock(&pktgen_thread_lock); return NULL; } static int __init pktgen_create_thread(const char *name, int cpu) { int err; struct pktgen_thread *t = NULL; struct proc_dir_entry *pe; if (strlen(name) > 31) { printk("pktgen: ERROR: Thread name cannot be more than 31 characters.\n"); return -EINVAL; } if (pktgen_find_thread(name)) { printk("pktgen: ERROR: thread: %s already exists\n", name); return -EINVAL; } struct task_struct *p; t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL); if (!t) { Loading @@ -3533,14 +3475,29 @@ static int __init pktgen_create_thread(const char *name, int cpu) return -ENOMEM; } strcpy(t->name, name); spin_lock_init(&t->if_lock); t->cpu = cpu; pe = create_proc_entry(t->name, 0600, pg_proc_dir); INIT_LIST_HEAD(&t->if_list); list_add_tail(&t->th_list, &pktgen_threads); p = kthread_create(pktgen_thread_worker, t, "kpktgend_%d", cpu); if (IS_ERR(p)) { printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu); list_del(&t->th_list); kfree(t); return PTR_ERR(p); } kthread_bind(p, cpu); t->tsk = p; pe = create_proc_entry(t->tsk->comm, 0600, pg_proc_dir); if (!pe) { printk("pktgen: cannot create %s/%s procfs entry.\n", PG_PROC_DIR, t->name); PG_PROC_DIR, t->tsk->comm); kthread_stop(p); list_del(&t->th_list); kfree(t); return -EINVAL; } Loading @@ -3548,21 +3505,7 @@ static int __init pktgen_create_thread(const char *name, int cpu) pe->proc_fops = &pktgen_thread_fops; pe->data = t; INIT_LIST_HEAD(&t->if_list); list_add_tail(&t->th_list, &pktgen_threads); t->removed = 0; err = kernel_thread((void *)pktgen_thread_worker, (void *)t, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); if (err < 0) { printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu); remove_proc_entry(t->name, pg_proc_dir); list_del(&t->th_list); kfree(t); return err; } wake_up_process(p); return 0; } Loading Loading @@ -3643,10 +3586,8 @@ static int __init pg_init(void) for_each_online_cpu(cpu) { int err; char buf[30]; sprintf(buf, "kpktgend_%i", cpu); err = pktgen_create_thread(buf, cpu); err = pktgen_create_thread(cpu); if (err) printk("pktgen: WARNING: Cannot create thread for cpu %d (%d)\n", cpu, err); Loading Loading @@ -3674,9 +3615,8 @@ static void __exit pg_cleanup(void) 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->removed == 1), HZ); kthread_stop(t->tsk); kfree(t); } /* Un-register us from receiving netdevice events */ Loading Loading
net/core/pktgen.c +48 −108 Original line number Diff line number Diff line Loading @@ -148,6 +148,7 @@ #include <linux/seq_file.h> #include <linux/wait.h> #include <linux/etherdevice.h> #include <linux/kthread.h> #include <net/checksum.h> #include <net/ipv6.h> #include <net/addrconf.h> Loading Loading @@ -360,8 +361,7 @@ struct pktgen_thread { spinlock_t if_lock; struct list_head if_list; /* All device here */ struct list_head th_list; int removed; char name[32]; struct task_struct *tsk; char result[512]; u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */ Loading Loading @@ -1689,7 +1689,7 @@ static int pktgen_thread_show(struct seq_file *seq, void *v) BUG_ON(!t); seq_printf(seq, "Name: %s max_before_softirq: %d\n", t->name, t->max_before_softirq); t->tsk->comm, t->max_before_softirq); seq_printf(seq, "Running: "); Loading Loading @@ -3112,7 +3112,7 @@ static void pktgen_rem_thread(struct pktgen_thread *t) { /* Remove from the thread list */ remove_proc_entry(t->name, pg_proc_dir); remove_proc_entry(t->tsk->comm, pg_proc_dir); mutex_lock(&pktgen_thread_lock); Loading Loading @@ -3260,58 +3260,40 @@ out:; * Main loop of the thread goes here */ static void pktgen_thread_worker(struct pktgen_thread *t) static int pktgen_thread_worker(void *arg) { DEFINE_WAIT(wait); struct pktgen_thread *t = arg; struct pktgen_dev *pkt_dev = NULL; int cpu = t->cpu; sigset_t tmpsig; u32 max_before_softirq; u32 tx_since_softirq = 0; daemonize("pktgen/%d", cpu); /* Block all signals except SIGKILL, SIGSTOP and SIGTERM */ spin_lock_irq(¤t->sighand->siglock); tmpsig = current->blocked; siginitsetinv(¤t->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGTERM)); recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); /* Migrate to the right CPU */ set_cpus_allowed(current, cpumask_of_cpu(cpu)); if (smp_processor_id() != cpu) BUG(); BUG_ON(smp_processor_id() != cpu); init_waitqueue_head(&t->queue); t->control &= ~(T_TERMINATE); t->control &= ~(T_RUN); t->control &= ~(T_STOP); t->control &= ~(T_REMDEVALL); t->control &= ~(T_REMDEV); t->pid = current->pid; PG_DEBUG(printk("pktgen: starting pktgen/%d: pid=%d\n", cpu, current->pid)); max_before_softirq = t->max_before_softirq; __set_current_state(TASK_INTERRUPTIBLE); mb(); set_current_state(TASK_INTERRUPTIBLE); while (1) { __set_current_state(TASK_RUNNING); while (!kthread_should_stop()) { pkt_dev = next_to_run(t); /* * Get next dev to xmit -- if any. */ if (!pkt_dev && (t->control & (T_STOP | T_RUN | T_REMDEVALL | T_REMDEV)) == 0) { prepare_to_wait(&(t->queue), &wait, TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); finish_wait(&(t->queue), &wait); } pkt_dev = next_to_run(t); __set_current_state(TASK_RUNNING); if (pkt_dev) { Loading @@ -3329,21 +3311,8 @@ static void pktgen_thread_worker(struct pktgen_thread *t) do_softirq(); tx_since_softirq = 0; } } else { prepare_to_wait(&(t->queue), &wait, TASK_INTERRUPTIBLE); schedule_timeout(HZ / 10); finish_wait(&(t->queue), &wait); } /* * Back from sleep, either due to the timeout or signal. * We check if we have any "posted" work for us. */ if (t->control & T_TERMINATE || signal_pending(current)) /* we received a request to terminate ourself */ break; if (t->control & T_STOP) { pktgen_stop(t); t->control &= ~(T_STOP); Loading @@ -3364,20 +3333,19 @@ static void pktgen_thread_worker(struct pktgen_thread *t) t->control &= ~(T_REMDEV); } if (need_resched()) schedule(); set_current_state(TASK_INTERRUPTIBLE); } PG_DEBUG(printk("pktgen: %s stopping all device\n", t->name)); PG_DEBUG(printk("pktgen: %s stopping all device\n", t->tsk->comm)); pktgen_stop(t); PG_DEBUG(printk("pktgen: %s removing all device\n", t->name)); PG_DEBUG(printk("pktgen: %s removing all device\n", t->tsk->comm)); pktgen_rem_all_ifs(t); PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name)); PG_DEBUG(printk("pktgen: %s removing thread.\n", t->tsk->comm)); pktgen_rem_thread(t); t->removed = 1; return 0; } static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, Loading Loading @@ -3495,37 +3463,11 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) return add_dev_to_thread(t, pkt_dev); } static struct pktgen_thread *__init pktgen_find_thread(const char *name) static int __init pktgen_create_thread(int cpu) { struct pktgen_thread *t; mutex_lock(&pktgen_thread_lock); list_for_each_entry(t, &pktgen_threads, th_list) if (strcmp(t->name, name) == 0) { mutex_unlock(&pktgen_thread_lock); return t; } mutex_unlock(&pktgen_thread_lock); return NULL; } static int __init pktgen_create_thread(const char *name, int cpu) { int err; struct pktgen_thread *t = NULL; struct proc_dir_entry *pe; if (strlen(name) > 31) { printk("pktgen: ERROR: Thread name cannot be more than 31 characters.\n"); return -EINVAL; } if (pktgen_find_thread(name)) { printk("pktgen: ERROR: thread: %s already exists\n", name); return -EINVAL; } struct task_struct *p; t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL); if (!t) { Loading @@ -3533,14 +3475,29 @@ static int __init pktgen_create_thread(const char *name, int cpu) return -ENOMEM; } strcpy(t->name, name); spin_lock_init(&t->if_lock); t->cpu = cpu; pe = create_proc_entry(t->name, 0600, pg_proc_dir); INIT_LIST_HEAD(&t->if_list); list_add_tail(&t->th_list, &pktgen_threads); p = kthread_create(pktgen_thread_worker, t, "kpktgend_%d", cpu); if (IS_ERR(p)) { printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu); list_del(&t->th_list); kfree(t); return PTR_ERR(p); } kthread_bind(p, cpu); t->tsk = p; pe = create_proc_entry(t->tsk->comm, 0600, pg_proc_dir); if (!pe) { printk("pktgen: cannot create %s/%s procfs entry.\n", PG_PROC_DIR, t->name); PG_PROC_DIR, t->tsk->comm); kthread_stop(p); list_del(&t->th_list); kfree(t); return -EINVAL; } Loading @@ -3548,21 +3505,7 @@ static int __init pktgen_create_thread(const char *name, int cpu) pe->proc_fops = &pktgen_thread_fops; pe->data = t; INIT_LIST_HEAD(&t->if_list); list_add_tail(&t->th_list, &pktgen_threads); t->removed = 0; err = kernel_thread((void *)pktgen_thread_worker, (void *)t, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); if (err < 0) { printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu); remove_proc_entry(t->name, pg_proc_dir); list_del(&t->th_list); kfree(t); return err; } wake_up_process(p); return 0; } Loading Loading @@ -3643,10 +3586,8 @@ static int __init pg_init(void) for_each_online_cpu(cpu) { int err; char buf[30]; sprintf(buf, "kpktgend_%i", cpu); err = pktgen_create_thread(buf, cpu); err = pktgen_create_thread(cpu); if (err) printk("pktgen: WARNING: Cannot create thread for cpu %d (%d)\n", cpu, err); Loading Loading @@ -3674,9 +3615,8 @@ static void __exit pg_cleanup(void) 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->removed == 1), HZ); kthread_stop(t->tsk); kfree(t); } /* Un-register us from receiving netdevice events */ Loading