aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/pktgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/pktgen.c')
-rw-r--r--net/core/pktgen.c83
1 files changed, 75 insertions, 8 deletions
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index c7d484f7e1c4..a756847e3814 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -168,7 +168,7 @@
168#include <asm/div64.h> /* do_div */ 168#include <asm/div64.h> /* do_div */
169#include <asm/timex.h> 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#define IP_NAME_SZ 32 173#define IP_NAME_SZ 32
174#define MAX_MPLS_LABELS 16 /* This is the max label stack depth */ 174#define MAX_MPLS_LABELS 16 /* This is the max label stack depth */
@@ -189,6 +189,7 @@
189#define F_FLOW_SEQ (1<<11) /* Sequential flows */ 189#define F_FLOW_SEQ (1<<11) /* Sequential flows */
190#define F_IPSEC_ON (1<<12) /* ipsec on for flows */ 190#define F_IPSEC_ON (1<<12) /* ipsec on for flows */
191#define F_QUEUE_MAP_RND (1<<13) /* queue map Random */ 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/* Thread control flag bits */ 194/* Thread control flag bits */
194#define T_TERMINATE (1<<0) 195#define T_TERMINATE (1<<0)
@@ -621,6 +622,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
621 if (pkt_dev->flags & F_QUEUE_MAP_RND) 622 if (pkt_dev->flags & F_QUEUE_MAP_RND)
622 seq_printf(seq, "QUEUE_MAP_RND "); 623 seq_printf(seq, "QUEUE_MAP_RND ");
623 624
625 if (pkt_dev->flags & F_QUEUE_MAP_CPU)
626 seq_printf(seq, "QUEUE_MAP_CPU ");
627
624 if (pkt_dev->cflows) { 628 if (pkt_dev->cflows) {
625 if (pkt_dev->flags & F_FLOW_SEQ) 629 if (pkt_dev->flags & F_FLOW_SEQ)
626 seq_printf(seq, "FLOW_SEQ "); /*in sequence flows*/ 630 seq_printf(seq, "FLOW_SEQ "); /*in sequence flows*/
@@ -1134,6 +1138,12 @@ static ssize_t pktgen_if_write(struct file *file,
1134 1138
1135 else if (strcmp(f, "!QUEUE_MAP_RND") == 0) 1139 else if (strcmp(f, "!QUEUE_MAP_RND") == 0)
1136 pkt_dev->flags &= ~F_QUEUE_MAP_RND; 1140 pkt_dev->flags &= ~F_QUEUE_MAP_RND;
1141
1142 else if (strcmp(f, "QUEUE_MAP_CPU") == 0)
1143 pkt_dev->flags |= F_QUEUE_MAP_CPU;
1144
1145 else if (strcmp(f, "!QUEUE_MAP_CPU") == 0)
1146 pkt_dev->flags &= ~F_QUEUE_MAP_CPU;
1137#ifdef CONFIG_XFRM 1147#ifdef CONFIG_XFRM
1138 else if (strcmp(f, "IPSEC") == 0) 1148 else if (strcmp(f, "IPSEC") == 0)
1139 pkt_dev->flags |= F_IPSEC_ON; 1149 pkt_dev->flags |= F_IPSEC_ON;
@@ -1895,6 +1905,23 @@ static int pktgen_device_event(struct notifier_block *unused,
1895 return NOTIFY_DONE; 1905 return NOTIFY_DONE;
1896} 1906}
1897 1907
1908static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev, const char *ifname)
1909{
1910 char b[IFNAMSIZ+5];
1911 int i = 0;
1912
1913 for(i=0; ifname[i] != '@'; i++) {
1914 if(i == IFNAMSIZ)
1915 break;
1916
1917 b[i] = ifname[i];
1918 }
1919 b[i] = 0;
1920
1921 return dev_get_by_name(&init_net, b);
1922}
1923
1924
1898/* Associate pktgen_dev with a device. */ 1925/* Associate pktgen_dev with a device. */
1899 1926
1900static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname) 1927static 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 pkt_dev->odev = NULL; 1935 pkt_dev->odev = NULL;
1909 } 1936 }
1910 1937
1911 odev = dev_get_by_name(&init_net, ifname); 1938 odev = pktgen_dev_get_by_name(pkt_dev, ifname);
1912 if (!odev) { 1939 if (!odev) {
1913 printk(KERN_ERR "pktgen: no such netdevice: \"%s\"\n", ifname); 1940 printk(KERN_ERR "pktgen: no such netdevice: \"%s\"\n", ifname);
1914 return -ENODEV; 1941 return -ENODEV;
@@ -1934,6 +1961,8 @@ static int pktgen_setup_dev(struct pktgen_dev *pkt_dev, const char *ifname)
1934 */ 1961 */
1935static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) 1962static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
1936{ 1963{
1964 int ntxq;
1965
1937 if (!pkt_dev->odev) { 1966 if (!pkt_dev->odev) {
1938 printk(KERN_ERR "pktgen: ERROR: pkt_dev->odev == NULL in " 1967 printk(KERN_ERR "pktgen: ERROR: pkt_dev->odev == NULL in "
1939 "setup_inject.\n"); 1968 "setup_inject.\n");
@@ -1942,6 +1971,33 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
1942 return; 1971 return;
1943 } 1972 }
1944 1973
1974 /* make sure that we don't pick a non-existing transmit queue */
1975 ntxq = pkt_dev->odev->real_num_tx_queues;
1976 if (ntxq <= num_online_cpus() && (pkt_dev->flags & F_QUEUE_MAP_CPU)) {
1977 printk(KERN_WARNING "pktgen: WARNING: QUEUE_MAP_CPU "
1978 "disabled because CPU count (%d) exceeds number ",
1979 num_online_cpus());
1980 printk(KERN_WARNING "pktgen: WARNING: of tx queues "
1981 "(%d) on %s \n", ntxq, pkt_dev->odev->name);
1982 pkt_dev->flags &= ~F_QUEUE_MAP_CPU;
1983 }
1984 if (ntxq <= pkt_dev->queue_map_min) {
1985 printk(KERN_WARNING "pktgen: WARNING: Requested "
1986 "queue_map_min (%d) exceeds number of tx\n",
1987 pkt_dev->queue_map_min);
1988 printk(KERN_WARNING "pktgen: WARNING: queues (%d) on "
1989 "%s, resetting\n", ntxq, pkt_dev->odev->name);
1990 pkt_dev->queue_map_min = ntxq - 1;
1991 }
1992 if (ntxq <= pkt_dev->queue_map_max) {
1993 printk(KERN_WARNING "pktgen: WARNING: Requested "
1994 "queue_map_max (%d) exceeds number of tx\n",
1995 pkt_dev->queue_map_max);
1996 printk(KERN_WARNING "pktgen: WARNING: queues (%d) on "
1997 "%s, resetting\n", ntxq, pkt_dev->odev->name);
1998 pkt_dev->queue_map_max = ntxq - 1;
1999 }
2000
1945 /* Default to the interface's mac if not explicitly set. */ 2001 /* Default to the interface's mac if not explicitly set. */
1946 2002
1947 if (is_zero_ether_addr(pkt_dev->src_mac)) 2003 if (is_zero_ether_addr(pkt_dev->src_mac))
@@ -2085,15 +2141,19 @@ static inline int f_pick(struct pktgen_dev *pkt_dev)
2085 if (pkt_dev->flows[flow].count >= pkt_dev->lflow) { 2141 if (pkt_dev->flows[flow].count >= pkt_dev->lflow) {
2086 /* reset time */ 2142 /* reset time */
2087 pkt_dev->flows[flow].count = 0; 2143 pkt_dev->flows[flow].count = 0;
2144 pkt_dev->flows[flow].flags = 0;
2088 pkt_dev->curfl += 1; 2145 pkt_dev->curfl += 1;
2089 if (pkt_dev->curfl >= pkt_dev->cflows) 2146 if (pkt_dev->curfl >= pkt_dev->cflows)
2090 pkt_dev->curfl = 0; /*reset */ 2147 pkt_dev->curfl = 0; /*reset */
2091 } 2148 }
2092 } else { 2149 } else {
2093 flow = random32() % pkt_dev->cflows; 2150 flow = random32() % pkt_dev->cflows;
2151 pkt_dev->curfl = flow;
2094 2152
2095 if (pkt_dev->flows[flow].count > pkt_dev->lflow) 2153 if (pkt_dev->flows[flow].count > pkt_dev->lflow) {
2096 pkt_dev->flows[flow].count = 0; 2154 pkt_dev->flows[flow].count = 0;
2155 pkt_dev->flows[flow].flags = 0;
2156 }
2097 } 2157 }
2098 2158
2099 return pkt_dev->curfl; 2159 return pkt_dev->curfl;
@@ -2125,7 +2185,11 @@ static void get_ipsec_sa(struct pktgen_dev *pkt_dev, int flow)
2125#endif 2185#endif
2126static void set_cur_queue_map(struct pktgen_dev *pkt_dev) 2186static void set_cur_queue_map(struct pktgen_dev *pkt_dev)
2127{ 2187{
2128 if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) { 2188
2189 if (pkt_dev->flags & F_QUEUE_MAP_CPU)
2190 pkt_dev->cur_queue_map = smp_processor_id();
2191
2192 else if (pkt_dev->queue_map_min < pkt_dev->queue_map_max) {
2129 __u16 t; 2193 __u16 t;
2130 if (pkt_dev->flags & F_QUEUE_MAP_RND) { 2194 if (pkt_dev->flags & F_QUEUE_MAP_RND) {
2131 t = random32() % 2195 t = random32() %
@@ -2162,7 +2226,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
2162 mc = random32() % pkt_dev->src_mac_count; 2226 mc = random32() % pkt_dev->src_mac_count;
2163 else { 2227 else {
2164 mc = pkt_dev->cur_src_mac_offset++; 2228 mc = pkt_dev->cur_src_mac_offset++;
2165 if (pkt_dev->cur_src_mac_offset > 2229 if (pkt_dev->cur_src_mac_offset >=
2166 pkt_dev->src_mac_count) 2230 pkt_dev->src_mac_count)
2167 pkt_dev->cur_src_mac_offset = 0; 2231 pkt_dev->cur_src_mac_offset = 0;
2168 } 2232 }
@@ -2189,7 +2253,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
2189 2253
2190 else { 2254 else {
2191 mc = pkt_dev->cur_dst_mac_offset++; 2255 mc = pkt_dev->cur_dst_mac_offset++;
2192 if (pkt_dev->cur_dst_mac_offset > 2256 if (pkt_dev->cur_dst_mac_offset >=
2193 pkt_dev->dst_mac_count) { 2257 pkt_dev->dst_mac_count) {
2194 pkt_dev->cur_dst_mac_offset = 0; 2258 pkt_dev->cur_dst_mac_offset = 0;
2195 } 2259 }
@@ -3305,6 +3369,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
3305 3369
3306 txq = netdev_get_tx_queue(odev, queue_map); 3370 txq = netdev_get_tx_queue(odev, queue_map);
3307 if (netif_tx_queue_stopped(txq) || 3371 if (netif_tx_queue_stopped(txq) ||
3372 netif_tx_queue_frozen(txq) ||
3308 need_resched()) { 3373 need_resched()) {
3309 idle_start = getCurUs(); 3374 idle_start = getCurUs();
3310 3375
@@ -3320,7 +3385,8 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
3320 3385
3321 pkt_dev->idle_acc += getCurUs() - idle_start; 3386 pkt_dev->idle_acc += getCurUs() - idle_start;
3322 3387
3323 if (netif_tx_queue_stopped(txq)) { 3388 if (netif_tx_queue_stopped(txq) ||
3389 netif_tx_queue_frozen(txq)) {
3324 pkt_dev->next_tx_us = getCurUs(); /* TODO */ 3390 pkt_dev->next_tx_us = getCurUs(); /* TODO */
3325 pkt_dev->next_tx_ns = 0; 3391 pkt_dev->next_tx_ns = 0;
3326 goto out; /* Try the next interface */ 3392 goto out; /* Try the next interface */
@@ -3352,7 +3418,8 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
3352 txq = netdev_get_tx_queue(odev, queue_map); 3418 txq = netdev_get_tx_queue(odev, queue_map);
3353 3419
3354 __netif_tx_lock_bh(txq); 3420 __netif_tx_lock_bh(txq);
3355 if (!netif_tx_queue_stopped(txq)) { 3421 if (!netif_tx_queue_stopped(txq) &&
3422 !netif_tx_queue_frozen(txq)) {
3356 3423
3357 atomic_inc(&(pkt_dev->skb->users)); 3424 atomic_inc(&(pkt_dev->skb->users));
3358 retry_now: 3425 retry_now: