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: Robert Olsson <robert.olsson@its.uu.se>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Robert Olsson and committed by David S. Miller e6fce5b9 32bb93b0

+34 -3
+34 -3
net/core/pktgen.c
··· 168 168 #include <asm/div64.h> /* do_div */ 169 169 #include <asm/timex.h> 170 170 171 - #define VERSION "pktgen v2.69: Packet Generator for packet performance testing.\n" 171 + #define VERSION "pktgen v2.70: Packet Generator for packet performance testing.\n" 172 172 173 173 #define IP_NAME_SZ 32 174 174 #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */ ··· 189 189 #define F_FLOW_SEQ (1<<11) /* Sequential flows */ 190 190 #define F_IPSEC_ON (1<<12) /* ipsec on for flows */ 191 191 #define F_QUEUE_MAP_RND (1<<13) /* queue map Random */ 192 + #define F_QUEUE_MAP_CPU (1<<14) /* queue map mirrors smp_processor_id() */ 192 193 193 194 /* Thread control flag bits */ 194 195 #define T_TERMINATE (1<<0) ··· 621 620 622 621 if (pkt_dev->flags & F_QUEUE_MAP_RND) 623 622 seq_printf(seq, "QUEUE_MAP_RND "); 623 + 624 + if (pkt_dev->flags & F_QUEUE_MAP_CPU) 625 + seq_printf(seq, "QUEUE_MAP_CPU "); 624 626 625 627 if (pkt_dev->cflows) { 626 628 if (pkt_dev->flags & F_FLOW_SEQ) ··· 1138 1134 1139 1135 else if (strcmp(f, "!QUEUE_MAP_RND") == 0) 1140 1136 pkt_dev->flags &= ~F_QUEUE_MAP_RND; 1137 + 1138 + else if (strcmp(f, "QUEUE_MAP_CPU") == 0) 1139 + pkt_dev->flags |= F_QUEUE_MAP_CPU; 1140 + 1141 + else if (strcmp(f, "!QUEUE_MAP_CPU") == 0) 1142 + pkt_dev->flags &= ~F_QUEUE_MAP_CPU; 1141 1143 #ifdef CONFIG_XFRM 1142 1144 else if (strcmp(f, "IPSEC") == 0) 1143 1145 pkt_dev->flags |= F_IPSEC_ON; ··· 1905 1895 return NOTIFY_DONE; 1906 1896 } 1907 1897 1898 + static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev, const char *ifname) 1899 + { 1900 + char b[IFNAMSIZ+5]; 1901 + int i = 0; 1902 + 1903 + for(i=0; ifname[i] != '@'; i++) { 1904 + if(i == IFNAMSIZ) 1905 + break; 1906 + 1907 + b[i] = ifname[i]; 1908 + } 1909 + b[i] = 0; 1910 + 1911 + return dev_get_by_name(&init_net, b); 1912 + } 1913 + 1914 + 1908 1915 /* Associate pktgen_dev with a device. */ 1909 1916 1910 1917 static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname) ··· 1935 1908 pkt_dev->odev = NULL; 1936 1909 } 1937 1910 1938 - odev = dev_get_by_name(&init_net, ifname); 1911 + odev = pktgen_dev_get_by_name(pkt_dev, ifname); 1939 1912 if (!odev) { 1940 1913 printk(KERN_ERR "pktgen: no such netdevice: \"%s\"\n", ifname); 1941 1914 return -ENODEV; ··· 2156 2129 #endif 2157 2130 static void set_cur_queue_map(struct pktgen_dev *pkt_dev) 2158 2131 { 2159 - if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) { 2132 + 2133 + if (pkt_dev->flags & F_QUEUE_MAP_CPU) 2134 + pkt_dev->cur_queue_map = smp_processor_id(); 2135 + 2136 + else if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) { 2160 2137 __u16 t; 2161 2138 if (pkt_dev->flags & F_QUEUE_MAP_RND) { 2162 2139 t = random32() %