diff options
Diffstat (limited to 'net/core/pktgen.c')
| -rw-r--r-- | net/core/pktgen.c | 212 | 
1 files changed, 110 insertions, 102 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 1dacd7ba8db..10a1ea72010 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -115,6 +115,9 @@   * command by Adit Ranadive <adit.262@gmail.com>   *   */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/sys.h>  #include <linux/types.h>  #include <linux/module.h> @@ -169,11 +172,13 @@  #include <asm/dma.h>  #include <asm/div64.h>		/* do_div */ -#define VERSION 	"2.73" +#define VERSION	"2.74"  #define IP_NAME_SZ 32  #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */  #define MPLS_STACK_BOTTOM htonl(0x00000100) +#define func_enter() pr_debug("entering %s\n", __func__); +  /* Device flag bits */  #define F_IPSRC_RND   (1<<0)	/* IP-Src Random  */  #define F_IPDST_RND   (1<<1)	/* IP-Dst Random  */ @@ -424,7 +429,8 @@ static inline int ktime_lt(const ktime_t cmp1, const ktime_t cmp2)  }  static const char version[] = -	"pktgen " VERSION ": Packet Generator for packet performance testing.\n"; +	"Packet Generator for packet performance testing. " +	"Version: " VERSION "\n";  static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i);  static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); @@ -495,7 +501,7 @@ static ssize_t pgctrl_write(struct file *file, const char __user *buf,  		pktgen_reset_all_threads();  	else -		printk(KERN_WARNING "pktgen: Unknown command: %s\n", data); +		pr_warning("Unknown command: %s\n", data);  	err = count; @@ -840,7 +846,7 @@ static ssize_t pktgen_if_write(struct file *file,  			       const char __user * user_buffer, size_t count,  			       loff_t * offset)  { -	struct seq_file *seq = (struct seq_file *)file->private_data; +	struct seq_file *seq = file->private_data;  	struct pktgen_dev *pkt_dev = seq->private;  	int i = 0, max, len;  	char name[16], valstr[32]; @@ -852,14 +858,14 @@ static ssize_t pktgen_if_write(struct file *file,  	pg_result = &(pkt_dev->result[0]);  	if (count < 1) { -		printk(KERN_WARNING "pktgen: wrong command format\n"); +		pr_warning("wrong command format\n");  		return -EINVAL;  	}  	max = count - i;  	tmp = count_trail_chars(&user_buffer[i], max);  	if (tmp < 0) { -		printk(KERN_WARNING "pktgen: illegal format\n"); +		pr_warning("illegal format\n");  		return tmp;  	}  	i += tmp; @@ -980,6 +986,36 @@ static ssize_t pktgen_if_write(struct file *file,  			(unsigned long long) pkt_dev->delay);  		return count;  	} +	if (!strcmp(name, "rate")) { +		len = num_arg(&user_buffer[i], 10, &value); +		if (len < 0) +			return len; + +		i += len; +		if (!value) +			return len; +		pkt_dev->delay = pkt_dev->min_pkt_size*8*NSEC_PER_USEC/value; +		if (debug) +			pr_info("Delay set at: %llu ns\n", pkt_dev->delay); + +		sprintf(pg_result, "OK: rate=%lu", value); +		return count; +	} +	if (!strcmp(name, "ratep")) { +		len = num_arg(&user_buffer[i], 10, &value); +		if (len < 0) +			return len; + +		i += len; +		if (!value) +			return len; +		pkt_dev->delay = NSEC_PER_SEC/value; +		if (debug) +			pr_info("Delay set at: %llu ns\n", pkt_dev->delay); + +		sprintf(pg_result, "OK: rate=%lu", value); +		return count; +	}  	if (!strcmp(name, "udp_src_min")) {  		len = num_arg(&user_buffer[i], 10, &value);  		if (len < 0) @@ -1398,18 +1434,12 @@ static ssize_t pktgen_if_write(struct file *file,  		i += len;  		for (*m = 0; *v && m < pkt_dev->dst_mac + 6; v++) { -			if (*v >= '0' && *v <= '9') { -				*m *= 16; -				*m += *v - '0'; -			} -			if (*v >= 'A' && *v <= 'F') { -				*m *= 16; -				*m += *v - 'A' + 10; -			} -			if (*v >= 'a' && *v <= 'f') { -				*m *= 16; -				*m += *v - 'a' + 10; -			} +			int value; + +			value = hex_to_bin(*v); +			if (value >= 0) +				*m = *m * 16 + value; +  			if (*v == ':') {  				m++;  				*m = 0; @@ -1440,18 +1470,12 @@ static ssize_t pktgen_if_write(struct file *file,  		i += len;  		for (*m = 0; *v && m < pkt_dev->src_mac + 6; v++) { -			if (*v >= '0' && *v <= '9') { -				*m *= 16; -				*m += *v - '0'; -			} -			if (*v >= 'A' && *v <= 'F') { -				*m *= 16; -				*m += *v - 'A' + 10; -			} -			if (*v >= 'a' && *v <= 'f') { -				*m *= 16; -				*m += *v - 'a' + 10; -			} +			int value; + +			value = hex_to_bin(*v); +			if (value >= 0) +				*m = *m * 16 + value; +  			if (*v == ':') {  				m++;  				*m = 0; @@ -1740,7 +1764,7 @@ static ssize_t pktgen_thread_write(struct file *file,  				   const char __user * user_buffer,  				   size_t count, loff_t * offset)  { -	struct seq_file *seq = (struct seq_file *)file->private_data; +	struct seq_file *seq = file->private_data;  	struct pktgen_thread *t = seq->private;  	int i = 0, max, len, ret;  	char name[40]; @@ -1781,7 +1805,7 @@ static ssize_t pktgen_thread_write(struct file *file,  		       name, (unsigned long)count);  	if (!t) { -		printk(KERN_ERR "pktgen: ERROR: No thread\n"); +		pr_err("ERROR: No thread\n");  		ret = -EINVAL;  		goto out;  	} @@ -1874,7 +1898,7 @@ static void pktgen_mark_device(const char *ifname)  	int i = 0;  	mutex_lock(&pktgen_thread_lock); -	pr_debug("pktgen: pktgen_mark_device marking %s for removal\n", ifname); +	pr_debug("%s: marking %s for removal\n", __func__, ifname);  	while (1) { @@ -1883,15 +1907,14 @@ static void pktgen_mark_device(const char *ifname)  			break;	/* success */  		mutex_unlock(&pktgen_thread_lock); -		pr_debug("pktgen: pktgen_mark_device waiting for %s " -				"to disappear....\n", ifname); +		pr_debug("%s: waiting for %s to disappear....\n", +			 __func__, ifname);  		schedule_timeout_interruptible(msecs_to_jiffies(msec_per_try));  		mutex_lock(&pktgen_thread_lock);  		if (++i >= max_tries) { -			printk(KERN_ERR "pktgen_mark_device: timed out after " -			       "waiting %d msec for device %s to be removed\n", -			       msec_per_try * i, ifname); +			pr_err("%s: timed out after waiting %d msec for device %s to be removed\n", +			       __func__, msec_per_try * i, ifname);  			break;  		} @@ -1918,8 +1941,8 @@ static void pktgen_change_name(struct net_device *dev)  							  &pktgen_if_fops,  							  pkt_dev);  			if (!pkt_dev->entry) -				printk(KERN_ERR "pktgen: can't move proc " -				       " entry for '%s'\n", dev->name); +				pr_err("can't move proc entry for '%s'\n", +				       dev->name);  			break;  		}  	} @@ -1983,15 +2006,15 @@ static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname)  	odev = pktgen_dev_get_by_name(pkt_dev, ifname);  	if (!odev) { -		printk(KERN_ERR "pktgen: no such netdevice: \"%s\"\n", ifname); +		pr_err("no such netdevice: \"%s\"\n", ifname);  		return -ENODEV;  	}  	if (odev->type != ARPHRD_ETHER) { -		printk(KERN_ERR "pktgen: not an ethernet device: \"%s\"\n", ifname); +		pr_err("not an ethernet device: \"%s\"\n", ifname);  		err = -EINVAL;  	} else if (!netif_running(odev)) { -		printk(KERN_ERR "pktgen: device is down: \"%s\"\n", ifname); +		pr_err("device is down: \"%s\"\n", ifname);  		err = -ENETDOWN;  	} else {  		pkt_dev->odev = odev; @@ -2010,8 +2033,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)  	int ntxq;  	if (!pkt_dev->odev) { -		printk(KERN_ERR "pktgen: ERROR: pkt_dev->odev == NULL in " -		       "setup_inject.\n"); +		pr_err("ERROR: pkt_dev->odev == NULL in setup_inject\n");  		sprintf(pkt_dev->result,  			"ERROR: pkt_dev->odev == NULL in setup_inject.\n");  		return; @@ -2021,19 +2043,15 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)  	ntxq = pkt_dev->odev->real_num_tx_queues;  	if (ntxq <= pkt_dev->queue_map_min) { -		printk(KERN_WARNING "pktgen: WARNING: Requested " -		       "queue_map_min (zero-based) (%d) exceeds valid range " -		       "[0 - %d] for (%d) queues on %s, resetting\n", -		       pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, -		       pkt_dev->odevname); +		pr_warning("WARNING: Requested queue_map_min (zero-based) (%d) exceeds valid range [0 - %d] for (%d) queues on %s, resetting\n", +			   pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, +			   pkt_dev->odevname);  		pkt_dev->queue_map_min = ntxq - 1;  	}  	if (pkt_dev->queue_map_max >= ntxq) { -		printk(KERN_WARNING "pktgen: WARNING: Requested " -		       "queue_map_max (zero-based) (%d) exceeds valid range " -		       "[0 - %d] for (%d) queues on %s, resetting\n", -		       pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, -		       pkt_dev->odevname); +		pr_warning("WARNING: Requested queue_map_max (zero-based) (%d) exceeds valid range [0 - %d] for (%d) queues on %s, resetting\n", +			   pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, +			   pkt_dev->odevname);  		pkt_dev->queue_map_max = ntxq - 1;  	} @@ -2093,8 +2111,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)  			}  			rcu_read_unlock();  			if (err) -				printk(KERN_ERR "pktgen: ERROR: IPv6 link " -				       "address not availble.\n"); +				pr_err("ERROR: IPv6 link address not available\n");  		}  #endif  	} else { @@ -2142,15 +2159,15 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)  	hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);  	hrtimer_set_expires(&t.timer, spin_until); -	remaining = ktime_to_us(hrtimer_expires_remaining(&t.timer)); +	remaining = ktime_to_ns(hrtimer_expires_remaining(&t.timer));  	if (remaining <= 0) {  		pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay);  		return;  	}  	start_time = ktime_now(); -	if (remaining < 100) -		udelay(remaining); 	/* really small just spin */ +	if (remaining < 100000) +		ndelay(remaining);	/* really small just spin */  	else {  		/* see do_nanosleep */  		hrtimer_init_sleeper(&t, current); @@ -2528,8 +2545,8 @@ static int process_ipsec(struct pktgen_dev *pkt_dev,  			if (nhead > 0) {  				ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);  				if (ret < 0) { -					printk(KERN_ERR "Error expanding " -					       "ipsec packet %d\n", ret); +					pr_err("Error expanding ipsec packet %d\n", +					       ret);  					goto err;  				}  			} @@ -2538,8 +2555,7 @@ static int process_ipsec(struct pktgen_dev *pkt_dev,  			skb_pull(skb, ETH_HLEN);  			ret = pktgen_output_ipsec(skb, pkt_dev);  			if (ret) { -				printk(KERN_ERR "Error creating ipsec " -				       "packet %d\n", ret); +				pr_err("Error creating ipsec packet %d\n", ret);  				goto err;  			}  			/* restore ll */ @@ -3015,8 +3031,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,  	if (datalen < sizeof(struct pktgen_hdr)) {  		datalen = sizeof(struct pktgen_hdr);  		if (net_ratelimit()) -			printk(KERN_INFO "pktgen: increased datalen to %d\n", -			       datalen); +			pr_info("increased datalen to %d\n", datalen);  	}  	udph->source = htons(pkt_dev->cur_udp_src); @@ -3143,7 +3158,7 @@ static void pktgen_run(struct pktgen_thread *t)  	struct pktgen_dev *pkt_dev;  	int started = 0; -	pr_debug("pktgen: entering pktgen_run. %p\n", t); +	func_enter();  	if_lock(t);  	list_for_each_entry(pkt_dev, &t->if_list, list) { @@ -3176,7 +3191,7 @@ static void pktgen_stop_all_threads_ifs(void)  {  	struct pktgen_thread *t; -	pr_debug("pktgen: entering pktgen_stop_all_threads_ifs.\n"); +	func_enter();  	mutex_lock(&pktgen_thread_lock); @@ -3241,7 +3256,7 @@ static void pktgen_run_all_threads(void)  {  	struct pktgen_thread *t; -	pr_debug("pktgen: entering pktgen_run_all_threads.\n"); +	func_enter();  	mutex_lock(&pktgen_thread_lock); @@ -3260,7 +3275,7 @@ static void pktgen_reset_all_threads(void)  {  	struct pktgen_thread *t; -	pr_debug("pktgen: entering pktgen_reset_all_threads.\n"); +	func_enter();  	mutex_lock(&pktgen_thread_lock); @@ -3310,8 +3325,8 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev)  	int nr_frags = pkt_dev->skb ? skb_shinfo(pkt_dev->skb)->nr_frags : -1;  	if (!pkt_dev->running) { -		printk(KERN_WARNING "pktgen: interface: %s is already " -		       "stopped\n", pkt_dev->odevname); +		pr_warning("interface: %s is already stopped\n", +			   pkt_dev->odevname);  		return -EINVAL;  	} @@ -3347,7 +3362,7 @@ static void pktgen_stop(struct pktgen_thread *t)  {  	struct pktgen_dev *pkt_dev; -	pr_debug("pktgen: entering pktgen_stop\n"); +	func_enter();  	if_lock(t); @@ -3367,7 +3382,7 @@ static void pktgen_rem_one_if(struct pktgen_thread *t)  	struct list_head *q, *n;  	struct pktgen_dev *cur; -	pr_debug("pktgen: entering pktgen_rem_one_if\n"); +	func_enter();  	if_lock(t); @@ -3393,9 +3408,10 @@ static void pktgen_rem_all_ifs(struct pktgen_thread *t)  	struct list_head *q, *n;  	struct pktgen_dev *cur; +	func_enter(); +  	/* Remove all devices, free mem */ -	pr_debug("pktgen: entering pktgen_rem_all_ifs\n");  	if_lock(t);  	list_for_each_safe(q, n, &t->if_list) { @@ -3477,8 +3493,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)  		pkt_dev->skb = fill_packet(odev, pkt_dev);  		if (pkt_dev->skb == NULL) { -			printk(KERN_ERR "pktgen: ERROR: couldn't " -			       "allocate skb in fill_packet.\n"); +			pr_err("ERROR: couldn't allocate skb in fill_packet\n");  			schedule();  			pkt_dev->clone_count--;	/* back out increment, OOM */  			return; @@ -3558,8 +3573,7 @@ static int pktgen_thread_worker(void *arg)  	init_waitqueue_head(&t->queue);  	complete(&t->start_done); -	pr_debug("pktgen: starting pktgen/%d:  pid=%d\n", -		 cpu, task_pid_nr(current)); +	pr_debug("starting pktgen/%d:  pid=%d\n", cpu, task_pid_nr(current));  	set_current_state(TASK_INTERRUPTIBLE); @@ -3612,13 +3626,13 @@ static int pktgen_thread_worker(void *arg)  		set_current_state(TASK_INTERRUPTIBLE);  	} -	pr_debug("pktgen: %s stopping all device\n", t->tsk->comm); +	pr_debug("%s stopping all device\n", t->tsk->comm);  	pktgen_stop(t); -	pr_debug("pktgen: %s removing all device\n", t->tsk->comm); +	pr_debug("%s removing all device\n", t->tsk->comm);  	pktgen_rem_all_ifs(t); -	pr_debug("pktgen: %s removing thread.\n", t->tsk->comm); +	pr_debug("%s removing thread\n", t->tsk->comm);  	pktgen_rem_thread(t);  	return 0; @@ -3642,7 +3656,7 @@ static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,  		}  	if_unlock(t); -	pr_debug("pktgen: find_dev(%s) returning %p\n", ifname, pkt_dev); +	pr_debug("find_dev(%s) returning %p\n", ifname, pkt_dev);  	return pkt_dev;  } @@ -3658,8 +3672,7 @@ static int add_dev_to_thread(struct pktgen_thread *t,  	if_lock(t);  	if (pkt_dev->pg_thread) { -		printk(KERN_ERR "pktgen: ERROR: already assigned " -		       "to a thread.\n"); +		pr_err("ERROR: already assigned to a thread\n");  		rv = -EBUSY;  		goto out;  	} @@ -3685,7 +3698,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)  	pkt_dev = __pktgen_NN_threads(ifname, FIND);  	if (pkt_dev) { -		printk(KERN_ERR "pktgen: ERROR: interface already used.\n"); +		pr_err("ERROR: interface already used\n");  		return -EBUSY;  	} @@ -3730,7 +3743,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)  	pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir,  					  &pktgen_if_fops, pkt_dev);  	if (!pkt_dev->entry) { -		printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n", +		pr_err("cannot create %s/%s procfs entry\n",  		       PG_PROC_DIR, ifname);  		err = -EINVAL;  		goto out2; @@ -3761,8 +3774,7 @@ static int __init pktgen_create_thread(int cpu)  	t = kzalloc_node(sizeof(struct pktgen_thread), GFP_KERNEL,  			 cpu_to_node(cpu));  	if (!t) { -		printk(KERN_ERR "pktgen: ERROR: out of memory, can't " -		       "create new thread.\n"); +		pr_err("ERROR: out of memory, can't create new thread\n");  		return -ENOMEM;  	} @@ -3776,8 +3788,7 @@ static int __init pktgen_create_thread(int cpu)  	p = kthread_create(pktgen_thread_worker, t, "kpktgend_%d", cpu);  	if (IS_ERR(p)) { -		printk(KERN_ERR "pktgen: kernel_thread() failed " -		       "for cpu %d\n", t->cpu); +		pr_err("kernel_thread() failed for cpu %d\n", t->cpu);  		list_del(&t->th_list);  		kfree(t);  		return PTR_ERR(p); @@ -3788,7 +3799,7 @@ static int __init pktgen_create_thread(int cpu)  	pe = proc_create_data(t->tsk->comm, 0600, pg_proc_dir,  			      &pktgen_thread_fops, t);  	if (!pe) { -		printk(KERN_ERR "pktgen: cannot create %s/%s procfs entry.\n", +		pr_err("cannot create %s/%s procfs entry\n",  		       PG_PROC_DIR, t->tsk->comm);  		kthread_stop(p);  		list_del(&t->th_list); @@ -3822,11 +3833,10 @@ static int pktgen_remove_device(struct pktgen_thread *t,  				struct pktgen_dev *pkt_dev)  { -	pr_debug("pktgen: remove_device pkt_dev=%p\n", pkt_dev); +	pr_debug("remove_device pkt_dev=%p\n", pkt_dev);  	if (pkt_dev->running) { -		printk(KERN_WARNING "pktgen: WARNING: trying to remove a " -		       "running interface, stopping it now.\n"); +		pr_warning("WARNING: trying to remove a running interface, stopping it now\n");  		pktgen_stop_device(pkt_dev);  	} @@ -3857,7 +3867,7 @@ static int __init pg_init(void)  	int cpu;  	struct proc_dir_entry *pe; -	printk(KERN_INFO "%s", version); +	pr_info("%s", version);  	pg_proc_dir = proc_mkdir(PG_PROC_DIR, init_net.proc_net);  	if (!pg_proc_dir) @@ -3865,8 +3875,7 @@ static int __init pg_init(void)  	pe = proc_create(PGCTRL, 0600, pg_proc_dir, &pktgen_fops);  	if (pe == NULL) { -		printk(KERN_ERR "pktgen: ERROR: cannot create %s " -		       "procfs entry.\n", PGCTRL); +		pr_err("ERROR: cannot create %s procfs entry\n", PGCTRL);  		proc_net_remove(&init_net, PG_PROC_DIR);  		return -EINVAL;  	} @@ -3879,13 +3888,12 @@ static int __init pg_init(void)  		err = pktgen_create_thread(cpu);  		if (err) -			printk(KERN_WARNING "pktgen: WARNING: Cannot create " -			       "thread for cpu %d (%d)\n", cpu, err); +			pr_warning("WARNING: Cannot create thread for cpu %d (%d)\n", +				   cpu, err);  	}  	if (list_empty(&pktgen_threads)) { -		printk(KERN_ERR "pktgen: ERROR: Initialization failed for " -		       "all threads\n"); +		pr_err("ERROR: Initialization failed for all threads\n");  		unregister_netdevice_notifier(&pktgen_notifier_block);  		remove_proc_entry(PGCTRL, pg_proc_dir);  		proc_net_remove(&init_net, PG_PROC_DIR);  | 
