Commit e6fce5b9 authored by Robert Olsson's avatar Robert Olsson Committed by David S. Miller

pktgen: multiqueue etc.

Sofar far pktgen have had a restriction to only use one device per kernel 
thread. With the new multiqueue architecture this is no longer adequate.

The patch below is an effort to remove this by in pktgen configuration 
adding a tag to  the device name a la eth0@0 etc. The tag is used for 
usual device config just as before. Also a new flag is introduced to mirror 
queue_map with sending threads smp_processor_id() QUEUE_MAP_CPU.

An example: We use 4 CPU's to send to one 10g interface (eth0)
 and we use the new tagging to send a mix of packet sizes, 64, 576 and
 1500 bytes. Also we use TX queues according to smp_processor_id()

 PGDEV=/proc/net/pktgen/kpktgend_0
 pgset "add_device eth0@0" 

 PGDEV=/proc/net/pktgen/kpktgend_1
 pgset "add_device eth0@1" 

 PGDEV=/proc/net/pktgen/kpktgend_2
 pgset "add_device eth0@2" 

 PGDEV=/proc/net/pktgen/kpktgend_3
 pgset "add_device eth0@3" 
....
PGDEV=/proc/net/pktgen/eth0@0 
pgset "pkt_size 64"
pgset "flag QUEUE_MAP_CPU"

PGDEV=/proc/net/pktgen/eth0@1
pgset "pkt_size 572"
pgset "flag QUEUE_MAP_CPU"

PGDEV=/proc/net/pktgen/eth0@2
pgset "pkt_size 1496"

PGDEV=/proc/net/pktgen/eth0@3
pgset "pkt_size 1496"
pgset "flag QUEUE_MAP_CPU"
Signed-off-by: default avatarRobert Olsson <robert.olsson@its.uu.se>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 32bb93b0
...@@ -168,7 +168,7 @@ ...@@ -168,7 +168,7 @@
#include <asm/div64.h> /* do_div */ #include <asm/div64.h> /* do_div */
#include <asm/timex.h> #include <asm/timex.h>
#define VERSION "pktgen v2.69: Packet Generator for packet performance testing.\n" #define VERSION "pktgen v2.70: Packet Generator for packet performance testing.\n"
#define IP_NAME_SZ 32 #define IP_NAME_SZ 32
#define MAX_MPLS_LABELS 16 /* This is the max label stack depth */ #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */
...@@ -189,6 +189,7 @@ ...@@ -189,6 +189,7 @@
#define F_FLOW_SEQ (1<<11) /* Sequential flows */ #define F_FLOW_SEQ (1<<11) /* Sequential flows */
#define F_IPSEC_ON (1<<12) /* ipsec on for flows */ #define F_IPSEC_ON (1<<12) /* ipsec on for flows */
#define F_QUEUE_MAP_RND (1<<13) /* queue map Random */ #define F_QUEUE_MAP_RND (1<<13) /* queue map Random */
#define F_QUEUE_MAP_CPU (1<<14) /* queue map mirrors smp_processor_id() */
/* Thread control flag bits */ /* Thread control flag bits */
#define T_TERMINATE (1<<0) #define T_TERMINATE (1<<0)
...@@ -621,6 +622,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v) ...@@ -621,6 +622,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
if (pkt_dev->flags & F_QUEUE_MAP_RND) if (pkt_dev->flags & F_QUEUE_MAP_RND)
seq_printf(seq, "QUEUE_MAP_RND "); seq_printf(seq, "QUEUE_MAP_RND ");
if (pkt_dev->flags & F_QUEUE_MAP_CPU)
seq_printf(seq, "QUEUE_MAP_CPU ");
if (pkt_dev->cflows) { if (pkt_dev->cflows) {
if (pkt_dev->flags & F_FLOW_SEQ) if (pkt_dev->flags & F_FLOW_SEQ)
seq_printf(seq, "FLOW_SEQ "); /*in sequence flows*/ seq_printf(seq, "FLOW_SEQ "); /*in sequence flows*/
...@@ -1134,6 +1138,12 @@ static ssize_t pktgen_if_write(struct file *file, ...@@ -1134,6 +1138,12 @@ static ssize_t pktgen_if_write(struct file *file,
else if (strcmp(f, "!QUEUE_MAP_RND") == 0) else if (strcmp(f, "!QUEUE_MAP_RND") == 0)
pkt_dev->flags &= ~F_QUEUE_MAP_RND; pkt_dev->flags &= ~F_QUEUE_MAP_RND;
else if (strcmp(f, "QUEUE_MAP_CPU") == 0)
pkt_dev->flags |= F_QUEUE_MAP_CPU;
else if (strcmp(f, "!QUEUE_MAP_CPU") == 0)
pkt_dev->flags &= ~F_QUEUE_MAP_CPU;
#ifdef CONFIG_XFRM #ifdef CONFIG_XFRM
else if (strcmp(f, "IPSEC") == 0) else if (strcmp(f, "IPSEC") == 0)
pkt_dev->flags |= F_IPSEC_ON; pkt_dev->flags |= F_IPSEC_ON;
...@@ -1895,6 +1905,23 @@ static int pktgen_device_event(struct notifier_block *unused, ...@@ -1895,6 +1905,23 @@ static int pktgen_device_event(struct notifier_block *unused,
return NOTIFY_DONE; return NOTIFY_DONE;
} }
static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev, const char *ifname)
{
char b[IFNAMSIZ+5];
int i = 0;
for(i=0; ifname[i] != '@'; i++) {
if(i == IFNAMSIZ)
break;
b[i] = ifname[i];
}
b[i] = 0;
return dev_get_by_name(&init_net, b);
}
/* Associate pktgen_dev with a device. */ /* Associate pktgen_dev with a device. */
static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname) static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname)
...@@ -1908,7 +1935,7 @@ static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname) ...@@ -1908,7 +1935,7 @@ static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname)
pkt_dev->odev = NULL; pkt_dev->odev = NULL;
} }
odev = dev_get_by_name(&init_net, ifname); odev = pktgen_dev_get_by_name(pkt_dev, ifname);
if (!odev) { if (!odev) {
printk(KERN_ERR "pktgen: no such netdevice: \"%s\"\n", ifname); printk(KERN_ERR "pktgen: no such netdevice: \"%s\"\n", ifname);
return -ENODEV; return -ENODEV;
...@@ -2129,7 +2156,11 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow) ...@@ -2129,7 +2156,11 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
#endif #endif
static void set_cur_queue_map(struct pktgen_dev *pkt_dev) static void set_cur_queue_map(struct pktgen_dev *pkt_dev)
{ {
if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) {
if (pkt_dev->flags & F_QUEUE_MAP_CPU)
pkt_dev->cur_queue_map = smp_processor_id();
else if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) {
__u16 t; __u16 t;
if (pkt_dev->flags & F_QUEUE_MAP_RND) { if (pkt_dev->flags & F_QUEUE_MAP_RND) {
t = random32() % t = random32() %
......
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