Skip to contentSkip to conversation

pktgen: increasing transmission granularity

PATCH Applied Daniel Turull 3 participants 8 messages Jun 2, 2010 – Jun 12, 2010

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/2 pktgen: increasing transmission granularity

This patch increases the granularity of the rate generated by pktgen. The previous version of pktgen uses micro seconds (udelay) resolution when it was delayed causing gaps in the rates. It is changed to nanosecond (ndelay). Now any rate is possible.

Also it allows to set, the desired rate in Mb/s or packets per second.

The documentation has been updated.

---

Documentation/networking/pktgen.txt +6 -0
index 61bb645..ac0e4ff 100644
@@ -78,6 +78,9 @@ Examples:
 
  pgset "delay 5000"      adds delay to hard_start_xmit(). nanoseconds
 
+ pgset "rate 300M"       set rate to 300 Mb/s
+ pgset "ratep 1000000"   set rate to 1Mpps
+
  pgset "dst 10.0.0.1"    sets IP destination address
                          (BEWARE! This generator is very aggressive!)
 
@@ -200,6 +203,9 @@ debug
 frags
 delay
 
+rate
+ratep
+
 src_mac_count
 dst_mac_count
 
net/core/pktgen.c +39 -5

74 lines not on this page · raw message

maintainer
#1 lore raw

From: Daniel Turull <[email protected]>
Date: Wed, 02 Jun 2010 13:49:07 +0200

Quoted 10 lines

This patch increases the granularity of the rate generated by pktgen. The previous version of pktgen uses micro seconds (udelay) resolution when it was delayed causing gaps in the rates. It is changed to nanosecond (ndelay). Now any rate is possible.

Also it allows to set, the desired rate in Mb/s or packets per second.

The documentation has been updated.

I like this, however although most of this is adding a new feature, this part:

net/core/pktgen.c static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until) · line 2210

Quoted 9 lines
net/core/pktgen.c +1 -1
@@ -2170,7 +2204,7 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
 	end_time = ktime_now();
 
 	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(end_time, start_time));
-	pkt_dev->next_tx = ktime_add_ns(end_time, pkt_dev->delay);
+	pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay);
 }
 
 static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)

Is a bug fix, since it makes sure the inter-packet interval is accurate.

Can you please submit this part seperately, so I can apply it to
net-2.6 Then you can submit the nanosecond feature parts
relative to this, which I'll apply to net-next-2.6

Thanks!

#2 lore raw

This patch correct a bug in the delay of pktgen. It makes sure the inter-packet interval is accurate.

---

net/core/pktgen.c +1 -1
index 2ad68da..1dacd7b 100644
@@ -2170,7 +2170,7 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
 	end_time = ktime_now();
 
 	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(end_time, start_time));
-	pkt_dev->next_tx = ktime_add_ns(end_time, pkt_dev->delay);
+	pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay);
 }
 
 static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
#3 lore raw

Thanks,

So the scheduling of the next transmission is based on the previous transmission rather rather than now() + delay.

Cheers

				--ro
Quoted 19 lines

Daniel Turull wrote: This patch correct a bug in the delay of pktgen. It makes sure the inter-packet interval is accurate.

---

net/core/pktgen.c index renamed from net/core/pktgen.c +0 -0

2ad68da..1dacd7b 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2170,7 +2170,7 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)

	end_time = ktime_now();

	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(end_time,

start_time));

net/core/pktgen.c index renamed from net/core/pktgen.c +1 -1
-	pkt_dev->next_tx = ktime_add_ns(end_time, pkt_dev->delay);
+	pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay);

}

static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)

maintainer Applied
#4 lore raw

From: Robert Olsson <[email protected]>
Date: Thu, 10 Jun 2010 17:44:42 +0200

Quoted 2 lines

So the scheduling of the next transmission is based on the previous transmission rather rather than now() + delay.

...

Quoted 7 lines
Quoted 4 lines

Daniel Turull wrote: This patch correct a bug in the delay of pktgen. It makes sure the inter-packet interval is accurate.

Applied, thanks everyone.

#5 lore raw
In reply to David Miller

This patch increases the granularity of the rate generated by pktgen. The previous version of pktgen uses micro seconds (udelay) resolution when it was delayed causing gaps in the rates. It is changed to nanosecond (ndelay). Now any rate is possible.

Also it allows to set, the desired rate in Mb/s or packets per second.

The documentation has been updated.

---

Documentation/networking/pktgen.txt +5 -0
index 61bb645..75e4fd7 100644
@@ -151,6 +151,8 @@ Examples:
 
  pgset stop    	          aborts injection. Also, ^C aborts generator.
 
+ pgset "rate 300M"        set rate to 300 Mb/s
+ pgset "ratep 1000000"    set rate to 1Mpps
 
 Example scripts
 ===============
@@ -241,6 +243,9 @@ src6
 flows
 flowlen
 
+rate
+ratep
+
 References:
 ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/
 ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/examples/
net/core/pktgen.c +38 -4

66 lines not on this page · raw message

#6 lore raw

Thanks,

So with this improved rate control we could do RFC2544-like testing as well.

Cheers

					--ro
Quoted 110 lines · Daniel Turull

This patch increases the granularity of the rate generated by pktgen. The previous version of pktgen uses micro seconds (udelay) resolution when it was delayed causing gaps in the rates. It is changed to nanosecond (ndelay). Now any rate is possible.

Also it allows to set, the desired rate in Mb/s or packets per second.

The documentation has been updated.

---

Documentation/networking/pktgen.txt +5 -0
index 61bb645..75e4fd7 100644
@@ -151,6 +151,8 @@ Examples:
 
  pgset stop    	          aborts injection. Also, ^C aborts generator.
 
+ pgset "rate 300M"        set rate to 300 Mb/s
+ pgset "ratep 1000000"    set rate to 1Mpps
 
 Example scripts
 ===============
@@ -241,6 +243,9 @@ src6
 flows
 flowlen
 
+rate
+ratep
+
 References:
 ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/
 ftp://robur.slu.se/pub/Linux/net-development/pktgen-testing/examples/
net/core/pktgen.c +38 -4
index 1dacd7b..6428653 100644
@@ -169,7 +169,7 @@
 #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)
@@ -980,6 +980,40 @@ 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)
+			printk(KERN_INFO
+				 "pktgen: 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)
+			printk(KERN_INFO
+				 "pktgen: 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)
@@ -2142,15 +2176,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);