aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-05-09 22:26:06 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-09 22:26:06 -0400
commit3e3b34685ac1a96b3c7f9c085aea053f7e11fee6 (patch)
tree1a4ed4a6daafe1c1c2cc8da74f3e8432e7aa4a11
parent4d95b72f61432cb2cb5bc0f65018d0a6c2201c81 (diff)
parent62f64aed622b6055b5fc447e3e421c9351563fc8 (diff)
Merge branch 'pktgen-next'
Jesper Dangaard Brouer says: ==================== The following series introduce some pktgen changes Patch01: Cleanup my own work when I introduced NO_TIMESTAMP. Patch02: Took over patch from Alexei, and addressed my own concerns, as Alexie is too busy with other work, and this will provide an easy tool for measuring ingress path performance, which is a hot topic ATM. Changes were primarily user interface related. Introduced a separate "xmit_mode" setting, instead of stealing one of the dev flags like Alexei did. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/networking/pktgen.txt9
-rw-r--r--net/core/pktgen.c85
2 files changed, 89 insertions, 5 deletions
diff --git a/Documentation/networking/pktgen.txt b/Documentation/networking/pktgen.txt
index 0344f1d45b37..747faccc4120 100644
--- a/Documentation/networking/pktgen.txt
+++ b/Documentation/networking/pktgen.txt
@@ -145,6 +145,7 @@ Examples:
145 UDPCSUM, 145 UDPCSUM,
146 IPSEC # IPsec encapsulation (needs CONFIG_XFRM) 146 IPSEC # IPsec encapsulation (needs CONFIG_XFRM)
147 NODE_ALLOC # node specific memory allocation 147 NODE_ALLOC # node specific memory allocation
148 NO_TIMESTAMP # disable timestamping
148 149
149 pgset spi SPI_VALUE Set specific SA used to transform packet. 150 pgset spi SPI_VALUE Set specific SA used to transform packet.
150 151
@@ -192,6 +193,10 @@ Examples:
192 pgset "rate 300M" set rate to 300 Mb/s 193 pgset "rate 300M" set rate to 300 Mb/s
193 pgset "ratep 1000000" set rate to 1Mpps 194 pgset "ratep 1000000" set rate to 1Mpps
194 195
196 pgset "xmit_mode netif_receive" RX inject into stack netif_receive_skb()
197 Works with "burst" but not with "clone_skb".
198 Default xmit_mode is "start_xmit".
199
195Sample scripts 200Sample scripts
196============== 201==============
197 202
@@ -287,6 +292,7 @@ flag
287 UDPCSUM 292 UDPCSUM
288 IPSEC 293 IPSEC
289 NODE_ALLOC 294 NODE_ALLOC
295 NO_TIMESTAMP
290 296
291dst_min 297dst_min
292dst_max 298dst_max
@@ -308,6 +314,9 @@ flowlen
308rate 314rate
309ratep 315ratep
310 316
317xmit_mode <start_xmit|netif_receive>
318
319
311References: 320References:
312ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/ 321ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/
313ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/examples/ 322ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/examples/
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 508155b283dd..8f2687da058e 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -210,6 +210,10 @@
210#define T_REMDEVALL (1<<2) /* Remove all devs */ 210#define T_REMDEVALL (1<<2) /* Remove all devs */
211#define T_REMDEV (1<<3) /* Remove one dev */ 211#define T_REMDEV (1<<3) /* Remove one dev */
212 212
213/* Xmit modes */
214#define M_START_XMIT 0 /* Default normal TX */
215#define M_NETIF_RECEIVE 1 /* Inject packets into stack */
216
213/* If lock -- protects updating of if_list */ 217/* If lock -- protects updating of if_list */
214#define if_lock(t) spin_lock(&(t->if_lock)); 218#define if_lock(t) spin_lock(&(t->if_lock));
215#define if_unlock(t) spin_unlock(&(t->if_lock)); 219#define if_unlock(t) spin_unlock(&(t->if_lock));
@@ -251,13 +255,14 @@ struct pktgen_dev {
251 * we will do a random selection from within the range. 255 * we will do a random selection from within the range.
252 */ 256 */
253 __u32 flags; 257 __u32 flags;
254 int removal_mark; /* non-zero => the device is marked for 258 int xmit_mode;
255 * removal by worker thread */
256
257 int min_pkt_size; 259 int min_pkt_size;
258 int max_pkt_size; 260 int max_pkt_size;
259 int pkt_overhead; /* overhead for MPLS, VLANs, IPSEC etc */ 261 int pkt_overhead; /* overhead for MPLS, VLANs, IPSEC etc */
260 int nfrags; 262 int nfrags;
263 int removal_mark; /* non-zero => the device is marked for
264 * removal by worker thread */
265
261 struct page *page; 266 struct page *page;
262 u64 delay; /* nano-seconds */ 267 u64 delay; /* nano-seconds */
263 268
@@ -620,6 +625,9 @@ static int pktgen_if_show(struct seq_file *seq, void *v)
620 if (pkt_dev->node >= 0) 625 if (pkt_dev->node >= 0)
621 seq_printf(seq, " node: %d\n", pkt_dev->node); 626 seq_printf(seq, " node: %d\n", pkt_dev->node);
622 627
628 if (pkt_dev->xmit_mode == M_NETIF_RECEIVE)
629 seq_puts(seq, " xmit_mode: netif_receive\n");
630
623 seq_puts(seq, " Flags: "); 631 seq_puts(seq, " Flags: ");
624 632
625 if (pkt_dev->flags & F_IPV6) 633 if (pkt_dev->flags & F_IPV6)
@@ -1081,7 +1089,8 @@ static ssize_t pktgen_if_write(struct file *file,
1081 if (len < 0) 1089 if (len < 0)
1082 return len; 1090 return len;
1083 if ((value > 0) && 1091 if ((value > 0) &&
1084 (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))) 1092 ((pkt_dev->xmit_mode == M_NETIF_RECEIVE) ||
1093 !(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING)))
1085 return -ENOTSUPP; 1094 return -ENOTSUPP;
1086 i += len; 1095 i += len;
1087 pkt_dev->clone_skb = value; 1096 pkt_dev->clone_skb = value;
@@ -1134,7 +1143,7 @@ static ssize_t pktgen_if_write(struct file *file,
1134 return len; 1143 return len;
1135 1144
1136 i += len; 1145 i += len;
1137 if ((value > 1) && 1146 if ((value > 1) && (pkt_dev->xmit_mode == M_START_XMIT) &&
1138 (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))) 1147 (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING)))
1139 return -ENOTSUPP; 1148 return -ENOTSUPP;
1140 pkt_dev->burst = value < 1 ? 1 : value; 1149 pkt_dev->burst = value < 1 ? 1 : value;
@@ -1160,6 +1169,35 @@ static ssize_t pktgen_if_write(struct file *file,
1160 sprintf(pg_result, "ERROR: node not possible"); 1169 sprintf(pg_result, "ERROR: node not possible");
1161 return count; 1170 return count;
1162 } 1171 }
1172 if (!strcmp(name, "xmit_mode")) {
1173 char f[32];
1174
1175 memset(f, 0, 32);
1176 len = strn_len(&user_buffer[i], sizeof(f) - 1);
1177 if (len < 0)
1178 return len;
1179
1180 if (copy_from_user(f, &user_buffer[i], len))
1181 return -EFAULT;
1182 i += len;
1183
1184 if (strcmp(f, "start_xmit") == 0) {
1185 pkt_dev->xmit_mode = M_START_XMIT;
1186 } else if (strcmp(f, "netif_receive") == 0) {
1187 /* clone_skb set earlier, not supported in this mode */
1188 if (pkt_dev->clone_skb > 0)
1189 return -ENOTSUPP;
1190
1191 pkt_dev->xmit_mode = M_NETIF_RECEIVE;
1192 } else {
1193 sprintf(pg_result,
1194 "xmit_mode -:%s:- unknown\nAvailable modes: %s",
1195 f, "start_xmit, netif_receive\n");
1196 return count;
1197 }
1198 sprintf(pg_result, "OK: xmit_mode=%s", f);
1199 return count;
1200 }
1163 if (!strcmp(name, "flag")) { 1201 if (!strcmp(name, "flag")) {
1164 char f[32]; 1202 char f[32];
1165 memset(f, 0, 32); 1203 memset(f, 0, 32);
@@ -1267,6 +1305,9 @@ static ssize_t pktgen_if_write(struct file *file,
1267 else if (strcmp(f, "NO_TIMESTAMP") == 0) 1305 else if (strcmp(f, "NO_TIMESTAMP") == 0)
1268 pkt_dev->flags |= F_NO_TIMESTAMP; 1306 pkt_dev->flags |= F_NO_TIMESTAMP;
1269 1307
1308 else if (strcmp(f, "!NO_TIMESTAMP") == 0)
1309 pkt_dev->flags &= ~F_NO_TIMESTAMP;
1310
1270 else { 1311 else {
1271 sprintf(pg_result, 1312 sprintf(pg_result,
1272 "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s", 1313 "Flag -:%s:- unknown\nAvailable flags, (prepend ! to un-set flag):\n%s",
@@ -3317,6 +3358,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
3317 unsigned int burst = ACCESS_ONCE(pkt_dev->burst); 3358 unsigned int burst = ACCESS_ONCE(pkt_dev->burst);
3318 struct net_device *odev = pkt_dev->odev; 3359 struct net_device *odev = pkt_dev->odev;
3319 struct netdev_queue *txq; 3360 struct netdev_queue *txq;
3361 struct sk_buff *skb;
3320 int ret; 3362 int ret;
3321 3363
3322 /* If device is offline, then don't send */ 3364 /* If device is offline, then don't send */
@@ -3354,6 +3396,38 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
3354 if (pkt_dev->delay && pkt_dev->last_ok) 3396 if (pkt_dev->delay && pkt_dev->last_ok)
3355 spin(pkt_dev, pkt_dev->next_tx); 3397 spin(pkt_dev, pkt_dev->next_tx);
3356 3398
3399 if (pkt_dev->xmit_mode == M_NETIF_RECEIVE) {
3400 skb = pkt_dev->skb;
3401 skb->protocol = eth_type_trans(skb, skb->dev);
3402 atomic_add(burst, &skb->users);
3403 local_bh_disable();
3404 do {
3405 ret = netif_receive_skb(skb);
3406 if (ret == NET_RX_DROP)
3407 pkt_dev->errors++;
3408 pkt_dev->sofar++;
3409 pkt_dev->seq_num++;
3410 if (atomic_read(&skb->users) != burst) {
3411 /* skb was queued by rps/rfs or taps,
3412 * so cannot reuse this skb
3413 */
3414 atomic_sub(burst - 1, &skb->users);
3415 /* get out of the loop and wait
3416 * until skb is consumed
3417 */
3418 pkt_dev->last_ok = 1;
3419 break;
3420 }
3421 /* skb was 'freed' by stack, so clean few
3422 * bits and reuse it
3423 */
3424#ifdef CONFIG_NET_CLS_ACT
3425 skb->tc_verd = 0; /* reset reclass/redir ttl */
3426#endif
3427 } while (--burst > 0);
3428 goto out; /* Skips xmit_mode M_START_XMIT */
3429 }
3430
3357 txq = skb_get_tx_queue(odev, pkt_dev->skb); 3431 txq = skb_get_tx_queue(odev, pkt_dev->skb);
3358 3432
3359 local_bh_disable(); 3433 local_bh_disable();
@@ -3401,6 +3475,7 @@ xmit_more:
3401unlock: 3475unlock:
3402 HARD_TX_UNLOCK(odev, txq); 3476 HARD_TX_UNLOCK(odev, txq);
3403 3477
3478out:
3404 local_bh_enable(); 3479 local_bh_enable();
3405 3480
3406 /* If pkt_dev->count is zero, then run forever */ 3481 /* If pkt_dev->count is zero, then run forever */