netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/14] pktgen update for net-next (2.6.32)
@ 2009-08-27 23:55 Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 01/14] pktgen: minor cleanup Stephen Hemminger
                   ` (15 more replies)
  0 siblings, 16 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

The biggest change is switching to monotonic clock (ktime) and
high resolution timers for the interpacket delay.

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 01/14] pktgen: minor cleanup
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 02/14] pktgen: change inlining Stephen Hemminger
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-fseen.patch --]
[-- Type: text/plain, Size: 1870 bytes --]

A couple of minor functions can be written more compactly.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 net/core/pktgen.c |   25 +++++++++----------------
 1 file changed, 9 insertions(+), 16 deletions(-)

--- a/net/core/pktgen.c	2009-08-27 11:03:07.270217291 -0700
+++ b/net/core/pktgen.c	2009-08-27 11:57:14.759765248 -0700
@@ -509,7 +509,7 @@ static const struct file_operations pktg
 
 static int pktgen_if_show(struct seq_file *seq, void *v)
 {
-	struct pktgen_dev *pkt_dev = seq->private;
+	const struct pktgen_dev *pkt_dev = seq->private;
 	__u64 sa;
 	__u64 stopped;
 	__u64 now = getCurUs();
@@ -1670,7 +1670,7 @@ static const struct file_operations pktg
 static int pktgen_thread_show(struct seq_file *seq, void *v)
 {
 	struct pktgen_thread *t = seq->private;
-	struct pktgen_dev *pkt_dev;
+	const struct pktgen_dev *pkt_dev;
 
 	BUG_ON(!t);
 
@@ -2120,13 +2120,9 @@ static inline void set_pkt_overhead(stru
 	pkt_dev->pkt_overhead += SVLAN_TAG_SIZE(pkt_dev);
 }
 
-static inline int f_seen(struct pktgen_dev *pkt_dev, int flow)
+static inline int f_seen(const struct pktgen_dev *pkt_dev, int flow)
 {
-
-	if (pkt_dev->flows[flow].flags & F_INIT)
-		return 1;
-	else
-		return 0;
+	return !!(pkt_dev->flows[flow].flags & F_INIT);
 }
 
 static inline int f_pick(struct pktgen_dev *pkt_dev)
@@ -3101,17 +3097,14 @@ static void pktgen_stop_all_threads_ifs(
 	mutex_unlock(&pktgen_thread_lock);
 }
 
-static int thread_is_running(struct pktgen_thread *t)
+static int thread_is_running(const struct pktgen_thread *t)
 {
-	struct pktgen_dev *pkt_dev;
-	int res = 0;
+	const struct pktgen_dev *pkt_dev;
 
 	list_for_each_entry(pkt_dev, &t->if_list, list)
-		if (pkt_dev->running) {
-			res = 1;
-			break;
-		}
-	return res;
+		if (pkt_dev->running)
+			return 1;
+	return 0;
 }
 
 static int pktgen_wait_thread_run(struct pktgen_thread *t)

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 02/14] pktgen: change inlining
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 01/14] pktgen: minor cleanup Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 03/14] pktgen: mark read-only/mostly variables Stephen Hemminger
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-deinline.patch --]
[-- Type: text/plain, Size: 2372 bytes --]

Don't force inlining where not needed. Gcc does better job
of deciding to inline local functions.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


---
 net/core/pktgen.c |   15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

--- a/net/core/pktgen.c	2009-08-27 11:30:10.108520235 -0700
+++ b/net/core/pktgen.c	2009-08-27 11:57:13.510686707 -0700
@@ -2438,7 +2438,7 @@ error:
 	return err;
 }
 
-static inline void free_SAs(struct pktgen_dev *pkt_dev)
+static void free_SAs(struct pktgen_dev *pkt_dev)
 {
 	if (pkt_dev->cflows) {
 		/* let go of the SAs if we have them */
@@ -2453,7 +2453,7 @@ static inline void free_SAs(struct pktge
 	}
 }
 
-static inline int process_ipsec(struct pktgen_dev *pkt_dev,
+static int process_ipsec(struct pktgen_dev *pkt_dev,
 			      struct sk_buff *skb, __be16 protocol)
 {
 	if (pkt_dev->flags & F_IPSEC_ON) {
@@ -3029,8 +3029,8 @@ static struct sk_buff *fill_packet_ipv6(
 	return skb;
 }
 
-static inline struct sk_buff *fill_packet(struct net_device *odev,
-					  struct pktgen_dev *pkt_dev)
+static struct sk_buff *fill_packet(struct net_device *odev,
+				   struct pktgen_dev *pkt_dev)
 {
 	if (pkt_dev->flags & F_IPV6)
 		return fill_packet_ipv6(odev, pkt_dev);
@@ -3341,13 +3341,12 @@ static void pktgen_rem_thread(struct pkt
 	mutex_unlock(&pktgen_thread_lock);
 }
 
-static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
+static void pktgen_xmit(struct pktgen_dev *pkt_dev)
 {
 	struct net_device *odev = pkt_dev->odev;
 	int (*xmit)(struct sk_buff *, struct net_device *)
 		= odev->netdev_ops->ndo_start_xmit;
 	struct netdev_queue *txq;
-	__u64 idle_start = 0;
 	u16 queue_map;
 	int ret;
 
@@ -3379,7 +3378,7 @@ static __inline__ void pktgen_xmit(struc
 	if (netif_tx_queue_stopped(txq) ||
 	    netif_tx_queue_frozen(txq) ||
 	    need_resched()) {
-		idle_start = getCurUs();
+		u64 idle_start = getCurUs();
 
 		if (!netif_running(odev)) {
 			pktgen_stop_device(pkt_dev);
@@ -3475,7 +3474,7 @@ static __inline__ void pktgen_xmit(struc
 	/* If pkt_dev->count is zero, then run forever */
 	if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
 		if (atomic_read(&(pkt_dev->skb->users)) != 1) {
-			idle_start = getCurUs();
+			u64 idle_start = getCurUs();
 			while (atomic_read(&(pkt_dev->skb->users)) != 1) {
 				if (signal_pending(current)) {
 					break;

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 03/14] pktgen: mark read-only/mostly variables
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 01/14] pktgen: minor cleanup Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 02/14] pktgen: change inlining Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 04/14] pktgen: stop_device cleanup Stephen Hemminger
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-ro.patch --]
[-- Type: text/plain, Size: 1134 bytes --]

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


---
 net/core/pktgen.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

--- a/net/core/pktgen.c	2009-08-27 11:30:11.932524803 -0700
+++ b/net/core/pktgen.c	2009-08-27 11:57:12.299687034 -0700
@@ -414,7 +414,7 @@ static __u64 getCurUs(void)
 
 /* old include end */
 
-static char version[] __initdata = VERSION;
+static const char version[] __initconst = VERSION;
 
 static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i);
 static int pktgen_add_device(struct pktgen_thread *t, const char *ifname);
@@ -432,10 +432,10 @@ static unsigned int scan_ip6(const char 
 static unsigned int fmt_ip6(char *s, const char ip[16]);
 
 /* Module parameters, defaults. */
-static int pg_count_d = 1000;	/* 1000 pkts by default */
-static int pg_delay_d;
-static int pg_clone_skb_d;
-static int debug;
+static int pg_count_d __read_mostly = 1000;
+static int pg_delay_d __read_mostly;
+static int pg_clone_skb_d  __read_mostly;
+static int debug  __read_mostly;
 
 static DEFINE_MUTEX(pktgen_thread_lock);
 static LIST_HEAD(pktgen_threads);

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 04/14] pktgen: stop_device cleanup
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (2 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 03/14] pktgen: mark read-only/mostly variables Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 05/14] pktgen: xmit logic reorganization Stephen Hemminger
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-stop-dev.patch --]
[-- Type: text/plain, Size: 1863 bytes --]

All the callers were freeing skb after stopping device.
Remove unneeded forward decl.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


---
 net/core/pktgen.c |   12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

--- a/net/core/pktgen.c	2009-08-27 11:35:23.949541813 -0700
+++ b/net/core/pktgen.c	2009-08-27 11:57:11.370662155 -0700
@@ -424,7 +424,7 @@ static int pktgen_device_event(struct no
 static void pktgen_run_all_threads(void);
 static void pktgen_reset_all_threads(void);
 static void pktgen_stop_all_threads_ifs(void);
-static int pktgen_stop_device(struct pktgen_dev *pkt_dev);
+
 static void pktgen_stop(struct pktgen_thread *t);
 static void pktgen_clear_counters(struct pktgen_dev *pkt_dev);
 
@@ -3221,7 +3221,6 @@ static void show_results(struct pktgen_d
 }
 
 /* Set stopped-at timer, remove from running list, do counters & statistics */
-
 static int pktgen_stop_device(struct pktgen_dev *pkt_dev)
 {
 	int nr_frags = pkt_dev->skb ? skb_shinfo(pkt_dev->skb)->nr_frags : -1;
@@ -3232,6 +3231,8 @@ static int pktgen_stop_device(struct pkt
 		return -EINVAL;
 	}
 
+	kfree_skb(pkt_dev->skb);
+	pkt_dev->skb = NULL;
 	pkt_dev->stopped_at = getCurUs();
 	pkt_dev->running = 0;
 
@@ -3268,9 +3269,6 @@ static void pktgen_stop(struct pktgen_th
 
 	list_for_each_entry(pkt_dev, &t->if_list, list) {
 		pktgen_stop_device(pkt_dev);
-		kfree_skb(pkt_dev->skb);
-
-		pkt_dev->skb = NULL;
 	}
 
 	if_unlock(t);
@@ -3382,8 +3380,6 @@ static void pktgen_xmit(struct pktgen_de
 
 		if (!netif_running(odev)) {
 			pktgen_stop_device(pkt_dev);
-			kfree_skb(pkt_dev->skb);
-			pkt_dev->skb = NULL;
 			goto out;
 		}
 		if (need_resched())
@@ -3486,8 +3482,6 @@ static void pktgen_xmit(struct pktgen_de
 
 		/* Done with this */
 		pktgen_stop_device(pkt_dev);
-		kfree_skb(pkt_dev->skb);
-		pkt_dev->skb = NULL;
 	}
 out:;
 }

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 05/14] pktgen: xmit logic reorganization
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (3 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 04/14] pktgen: stop_device cleanup Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 06/14] pktgen: cleanup clone count test Stephen Hemminger
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-reorg1.patch --]
[-- Type: text/plain, Size: 3236 bytes --]

Do some reorganization of transmit logic path:
   * move transmit queue full idle to separate routine
   * add a cpu_relax()
   * eliminate some of the uneeded goto's
   * if queue is still stopped, go back to main thread loop.
   * don't give up transmitting if quantum is exhausted (be greedy)

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


---
 net/core/pktgen.c |   55 +++++++++++++++++++++++-------------------------------
 1 file changed, 24 insertions(+), 31 deletions(-)

--- a/net/core/pktgen.c	2009-08-27 11:35:23.959966151 -0700
+++ b/net/core/pktgen.c	2009-08-27 11:57:10.525500312 -0700
@@ -3339,6 +3339,18 @@ static void pktgen_rem_thread(struct pkt
 	mutex_unlock(&pktgen_thread_lock);
 }
 
+static void idle(struct pktgen_dev *pkt_dev)
+{
+	u64 idle_start = getCurUs();
+
+	if (need_resched())
+		schedule();
+	else
+		cpu_relax();
+
+	pkt_dev->idle_acc += getCurUs() - idle_start;
+}
+
 static void pktgen_xmit(struct pktgen_dev *pkt_dev)
 {
 	struct net_device *odev = pkt_dev->odev;
@@ -3361,7 +3373,7 @@ static void pktgen_xmit(struct pktgen_de
 		if (pkt_dev->delay_us == 0x7FFFFFFF) {
 			pkt_dev->next_tx_us = getCurUs() + pkt_dev->delay_us;
 			pkt_dev->next_tx_ns = pkt_dev->delay_ns;
-			goto out;
+			return;
 		}
 	}
 
@@ -3373,26 +3385,14 @@ static void pktgen_xmit(struct pktgen_de
 	}
 
 	txq = netdev_get_tx_queue(odev, queue_map);
-	if (netif_tx_queue_stopped(txq) ||
-	    netif_tx_queue_frozen(txq) ||
-	    need_resched()) {
-		u64 idle_start = getCurUs();
-
-		if (!netif_running(odev)) {
+	/* Did we saturate the queue already? */
+	if (netif_tx_queue_stopped(txq) || netif_tx_queue_frozen(txq)) {
+		/* If device is down, then all queues are permnantly frozen */
+		if (netif_running(odev))
+			idle(pkt_dev);
+		else
 			pktgen_stop_device(pkt_dev);
-			goto out;
-		}
-		if (need_resched())
-			schedule();
-
-		pkt_dev->idle_acc += getCurUs() - idle_start;
-
-		if (netif_tx_queue_stopped(txq) ||
-		    netif_tx_queue_frozen(txq)) {
-			pkt_dev->next_tx_us = getCurUs();	/* TODO */
-			pkt_dev->next_tx_ns = 0;
-			goto out;	/* Try the next interface */
-		}
+		return;
 	}
 
 	if (pkt_dev->last_ok || !pkt_dev->skb) {
@@ -3407,7 +3407,7 @@ static void pktgen_xmit(struct pktgen_de
 				       "allocate skb in fill_packet.\n");
 				schedule();
 				pkt_dev->clone_count--;	/* back out increment, OOM */
-				goto out;
+				return;
 			}
 			pkt_dev->allocated_skbs++;
 			pkt_dev->clone_count = 0;	/* reset counter */
@@ -3419,9 +3419,9 @@ static void pktgen_xmit(struct pktgen_de
 	txq = netdev_get_tx_queue(odev, queue_map);
 
 	__netif_tx_lock_bh(txq);
-	if (!netif_tx_queue_stopped(txq) &&
-	    !netif_tx_queue_frozen(txq)) {
-
+	if (unlikely(netif_tx_queue_stopped(txq) || netif_tx_queue_frozen(txq)))
+		pkt_dev->last_ok = 0;
+	else {
 		atomic_inc(&(pkt_dev->skb->users));
 	      retry_now:
 		ret = (*xmit)(pkt_dev->skb, odev);
@@ -3458,13 +3458,6 @@ static void pktgen_xmit(struct pktgen_de
 			pkt_dev->next_tx_ns -= 1000;
 		}
 	}
-
-	else {			/* Retry it next time */
-		pkt_dev->last_ok = 0;
-		pkt_dev->next_tx_us = getCurUs();	/* TODO */
-		pkt_dev->next_tx_ns = 0;
-	}
-
 	__netif_tx_unlock_bh(txq);
 
 	/* If pkt_dev->count is zero, then run forever */

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 06/14] pktgen: cleanup clone count test
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (4 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 05/14] pktgen: xmit logic reorganization Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 07/14] pktgen: use netdev_alloc_skb Stephen Hemminger
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-clone-count.patch --]
[-- Type: text/plain, Size: 1690 bytes --]

The if statement to test for "should a new packet be used"
can be simplified.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


---
 net/core/pktgen.c |   32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

--- a/net/core/pktgen.c	2009-08-27 11:35:26.831941925 -0700
+++ b/net/core/pktgen.c	2009-08-27 11:57:09.804814960 -0700
@@ -3395,23 +3395,22 @@ static void pktgen_xmit(struct pktgen_de
 		return;
 	}
 
-	if (pkt_dev->last_ok || !pkt_dev->skb) {
-		if ((++pkt_dev->clone_count >= pkt_dev->clone_skb)
-		    || (!pkt_dev->skb)) {
-			/* build a new pkt */
-			kfree_skb(pkt_dev->skb);
-
-			pkt_dev->skb = fill_packet(odev, pkt_dev);
-			if (pkt_dev->skb == NULL) {
-				printk(KERN_ERR "pktgen: ERROR: couldn't "
-				       "allocate skb in fill_packet.\n");
-				schedule();
-				pkt_dev->clone_count--;	/* back out increment, OOM */
-				return;
-			}
-			pkt_dev->allocated_skbs++;
-			pkt_dev->clone_count = 0;	/* reset counter */
+	if (!pkt_dev->skb || (pkt_dev->last_ok &&
+			      ++pkt_dev->clone_count >= pkt_dev->clone_skb)) {
+		/* build a new pkt */
+		kfree_skb(pkt_dev->skb);
+
+		pkt_dev->skb = fill_packet(odev, pkt_dev);
+		if (pkt_dev->skb == NULL) {
+			printk(KERN_ERR "pktgen: ERROR: couldn't "
+			       "allocate skb in fill_packet.\n");
+			schedule();
+			pkt_dev->clone_count--;	/* back out increment, OOM */
+			return;
 		}
+
+		pkt_dev->allocated_skbs++;
+		pkt_dev->clone_count = 0;	/* reset counter */
 	}
 
 	/* fill_packet() might have changed the queue */
@@ -3476,7 +3475,6 @@ static void pktgen_xmit(struct pktgen_de
 		/* Done with this */
 		pktgen_stop_device(pkt_dev);
 	}
-out:;
 }
 
 /*

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 07/14] pktgen: use netdev_alloc_skb
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (5 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 06/14] pktgen: cleanup clone count test Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 08/14] pktgen: reorganize transmit loop Stephen Hemminger
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-netdev-alloc.patch --]
[-- Type: text/plain, Size: 1240 bytes --]

netdev_alloc_skb is NUMA node aware.
Also, don't exhaust atomic emergency pool. Don't want pktgen
to cause OOM behaviour.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


---
 net/core/pktgen.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

--- a/net/core/pktgen.c	2009-08-27 11:45:39.080959255 -0700
+++ b/net/core/pktgen.c	2009-08-27 11:57:08.683814034 -0700
@@ -2539,8 +2539,9 @@ static struct sk_buff *fill_packet_ipv4(
 	mod_cur_headers(pkt_dev);
 
 	datalen = (odev->hard_header_len + 16) & ~0xf;
-	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + datalen +
-			pkt_dev->pkt_overhead, GFP_ATOMIC);
+	skb = __netdev_alloc_skb(odev,
+				 pkt_dev->cur_pkt_size + 64
+				 + datalen + pkt_dev->pkt_overhead, GFP_NOWAIT);
 	if (!skb) {
 		sprintf(pkt_dev->result, "No memory");
 		return NULL;
@@ -2878,8 +2879,9 @@ static struct sk_buff *fill_packet_ipv6(
 	queue_map = pkt_dev->cur_queue_map;
 	mod_cur_headers(pkt_dev);
 
-	skb = alloc_skb(pkt_dev->cur_pkt_size + 64 + 16 +
-			pkt_dev->pkt_overhead, GFP_ATOMIC);
+	skb = __netdev_alloc_skb(odev,
+				 pkt_dev->cur_pkt_size + 64
+				 + 16 + pkt_dev->pkt_overhead, GFP_NOWAIT);
 	if (!skb) {
 		sprintf(pkt_dev->result, "No memory");
 		return NULL;

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 08/14] pktgen: reorganize transmit loop
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (6 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 07/14] pktgen: use netdev_alloc_skb Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-28  3:52   ` Ben Greear
  2009-08-27 23:55 ` [PATCH 09/14] pktgen: avoid calling gettimeofday Stephen Hemminger
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-reorg2.patch --]
[-- Type: text/plain, Size: 1448 bytes --]

Handle standard (and non-standard) return values in a switch.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


---
 net/core/pktgen.c |   26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

--- a/net/core/pktgen.c	2009-08-27 11:45:40.162808571 -0700
+++ b/net/core/pktgen.c	2009-08-27 11:56:46.356874524 -0700
@@ -3424,27 +3424,29 @@ static void pktgen_xmit(struct pktgen_de
 		pkt_dev->last_ok = 0;
 	else {
 		atomic_inc(&(pkt_dev->skb->users));
-	      retry_now:
+
+	retry_now:
 		ret = (*xmit)(pkt_dev->skb, odev);
-		if (likely(ret == NETDEV_TX_OK)) {
+		switch (ret) {
+		case NETDEV_TX_OK:
 			txq_trans_update(txq);
 			pkt_dev->last_ok = 1;
 			pkt_dev->sofar++;
 			pkt_dev->seq_num++;
 			pkt_dev->tx_bytes += pkt_dev->cur_pkt_size;
-
-		} else if (ret == NETDEV_TX_LOCKED
-			   && (odev->features & NETIF_F_LLTX)) {
+			break;
+		case NETDEV_TX_LOCKED:
 			cpu_relax();
 			goto retry_now;
-		} else {	/* Retry it next time */
-
-			atomic_dec(&(pkt_dev->skb->users));
-
-			if (debug && net_ratelimit())
-				printk(KERN_INFO "pktgen: Hard xmit error\n");
-
+		default: /* Drivers are not supposed to return other values! */
+			if (net_ratelimit())
+				pr_info("pktgen: %s xmit error: %d\n",
+					odev->name, ret);
 			pkt_dev->errors++;
+			/* fallthru */
+		case NETDEV_TX_BUSY:
+			/* Retry it next time */
+			atomic_dec(&(pkt_dev->skb->users));
 			pkt_dev->last_ok = 0;
 		}
 

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 09/14] pktgen: avoid calling gettimeofday
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (7 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 08/14] pktgen: reorganize transmit loop Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 10/14] pktgen: convert to use ktime_t Stephen Hemminger
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-delay2.patch --]
[-- Type: text/plain, Size: 1155 bytes --]

If not using delay then no need to update next_tx after
each packet sent. This allows pktgen to send faster especially
on systems with slower clock sources.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


---
 net/core/pktgen.c |   20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

--- a/net/core/pktgen.c	2009-08-27 11:45:41.488749725 -0700
+++ b/net/core/pktgen.c	2009-08-27 11:56:42.101504858 -0700
@@ -3450,15 +3450,17 @@ static void pktgen_xmit(struct pktgen_de
 			pkt_dev->last_ok = 0;
 		}
 
-		pkt_dev->next_tx_us = getCurUs();
-		pkt_dev->next_tx_ns = 0;
-
-		pkt_dev->next_tx_us += pkt_dev->delay_us;
-		pkt_dev->next_tx_ns += pkt_dev->delay_ns;
-
-		if (pkt_dev->next_tx_ns > 1000) {
-			pkt_dev->next_tx_us++;
-			pkt_dev->next_tx_ns -= 1000;
+		if (pkt_dev->delay_us || pkt_dev->delay_ns) {
+			pkt_dev->next_tx_us = getCurUs();
+			pkt_dev->next_tx_ns = 0;
+
+			pkt_dev->next_tx_us += pkt_dev->delay_us;
+			pkt_dev->next_tx_ns += pkt_dev->delay_ns;
+
+			if (pkt_dev->next_tx_ns > 1000) {
+				pkt_dev->next_tx_us++;
+				pkt_dev->next_tx_ns -= 1000;
+			}
 		}
 	}
 	__netif_tx_unlock_bh(txq);

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 10/14] pktgen: convert to use ktime_t
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (8 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 09/14] pktgen: avoid calling gettimeofday Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 11/14] pktgen: spin using hrtimer Stephen Hemminger
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-ktime.patch --]
[-- Type: text/plain, Size: 10921 bytes --]

The kernel ktime_t is a nice generic infrastructure for mananging
high resolution times, as is done in pktgen.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


---
 net/core/pktgen.c |  185 ++++++++++++++++++++++++------------------------------
 1 file changed, 85 insertions(+), 100 deletions(-)

--- a/net/core/pktgen.c	2009-08-27 12:04:15.087541783 -0700
+++ b/net/core/pktgen.c	2009-08-27 12:43:35.843546115 -0700
@@ -246,16 +246,14 @@ struct pktgen_dev {
 	int max_pkt_size;	/* = ETH_ZLEN; */
 	int pkt_overhead;	/* overhead for MPLS, VLANs, IPSEC etc */
 	int nfrags;
-	__u32 delay_us;		/* Default delay */
-	__u32 delay_ns;
+	u64 delay;		/* nano-seconds */
+
 	__u64 count;		/* Default No packets to send */
 	__u64 sofar;		/* How many pkts we've sent so far */
 	__u64 tx_bytes;		/* How many bytes we've transmitted */
 	__u64 errors;		/* Errors when trying to transmit, pkts will be re-sent */
 
 	/* runtime counters relating to clone_skb */
-	__u64 next_tx_us;	/* timestamp of when to tx next */
-	__u32 next_tx_ns;
 
 	__u64 allocated_skbs;
 	__u32 clone_count;
@@ -263,9 +261,11 @@ struct pktgen_dev {
 				 * Or a failed transmit of some sort?  This will keep
 				 * sequence numbers in order, for example.
 				 */
-	__u64 started_at;	/* micro-seconds */
-	__u64 stopped_at;	/* micro-seconds */
-	__u64 idle_acc;		/* micro-seconds */
+	ktime_t next_tx;
+	ktime_t started_at;
+	ktime_t stopped_at;
+	u64	idle_acc;	/* nano-seconds */
+
 	__u32 seq_num;
 
 	int clone_skb;		/* Use multiple SKBs during packet gen.  If this number
@@ -397,23 +397,20 @@ struct pktgen_thread {
 #define REMOVE 1
 #define FIND   0
 
-/** Convert to micro-seconds */
-static inline __u64 tv_to_us(const struct timeval *tv)
+static inline ktime_t ktime_now(void)
 {
-	__u64 us = tv->tv_usec;
-	us += (__u64) tv->tv_sec * (__u64) 1000000;
-	return us;
+	struct timespec ts;
+	ktime_get_ts(&ts);
+
+	return timespec_to_ktime(ts);
 }
 
-static __u64 getCurUs(void)
+/* This works even if 32 bit because of careful byte order choice */
+static inline int ktime_lt(const ktime_t cmp1, const ktime_t cmp2)
 {
-	struct timeval tv;
-	do_gettimeofday(&tv);
-	return tv_to_us(&tv);
+	return cmp1.tv64 < cmp2.tv64;
 }
 
-/* old include end */
-
 static const char version[] __initconst = VERSION;
 
 static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i);
@@ -510,9 +507,8 @@ static const struct file_operations pktg
 static int pktgen_if_show(struct seq_file *seq, void *v)
 {
 	const struct pktgen_dev *pkt_dev = seq->private;
-	__u64 sa;
-	__u64 stopped;
-	__u64 now = getCurUs();
+	ktime_t stopped;
+	u64 idle;
 
 	seq_printf(seq,
 		   "Params: count %llu  min_pkt_size: %u  max_pkt_size: %u\n",
@@ -520,9 +516,8 @@ static int pktgen_if_show(struct seq_fil
 		   pkt_dev->max_pkt_size);
 
 	seq_printf(seq,
-		   "     frags: %d  delay: %u  clone_skb: %d  ifname: %s\n",
-		   pkt_dev->nfrags,
-		   1000 * pkt_dev->delay_us + pkt_dev->delay_ns,
+		   "     frags: %d  delay: %llu  clone_skb: %d  ifname: %s\n",
+		   pkt_dev->nfrags, (unsigned long long) pkt_dev->delay,
 		   pkt_dev->clone_skb, pkt_dev->odev->name);
 
 	seq_printf(seq, "     flows: %u flowlen: %u\n", pkt_dev->cflows,
@@ -654,17 +649,21 @@ static int pktgen_if_show(struct seq_fil
 
 	seq_puts(seq, "\n");
 
-	sa = pkt_dev->started_at;
-	stopped = pkt_dev->stopped_at;
-	if (pkt_dev->running)
-		stopped = now;	/* not really stopped, more like last-running-at */
+	/* not really stopped, more like last-running-at */
+	stopped = pkt_dev->running ? ktime_now() : pkt_dev->stopped_at;
+	idle = pkt_dev->idle_acc;
+	do_div(idle, NSEC_PER_USEC);
 
 	seq_printf(seq,
-		   "Current:\n     pkts-sofar: %llu  errors: %llu\n     started: %lluus  stopped: %lluus idle: %lluus\n",
+		   "Current:\n     pkts-sofar: %llu  errors: %llu\n",
 		   (unsigned long long)pkt_dev->sofar,
-		   (unsigned long long)pkt_dev->errors, (unsigned long long)sa,
-		   (unsigned long long)stopped,
-		   (unsigned long long)pkt_dev->idle_acc);
+		   (unsigned long long)pkt_dev->errors);
+
+	seq_printf(seq,
+		   "     started: %lluus  stopped: %lluus idle: %lluus\n",
+		   (unsigned long long) ktime_to_us(pkt_dev->started_at),
+		   (unsigned long long) ktime_to_us(stopped),
+		   (unsigned long long) idle);
 
 	seq_printf(seq,
 		   "     seq_num: %d  cur_dst_mac_offset: %d  cur_src_mac_offset: %d\n",
@@ -950,15 +949,13 @@ static ssize_t pktgen_if_write(struct fi
 			return len;
 		}
 		i += len;
-		if (value == 0x7FFFFFFF) {
-			pkt_dev->delay_us = 0x7FFFFFFF;
-			pkt_dev->delay_ns = 0;
-		} else {
-			pkt_dev->delay_us = value / 1000;
-			pkt_dev->delay_ns = value % 1000;
-		}
-		sprintf(pg_result, "OK: delay=%u",
-			1000 * pkt_dev->delay_us + pkt_dev->delay_ns);
+		if (value == 0x7FFFFFFF)
+			pkt_dev->delay = ULLONG_MAX;
+		else
+			pkt_dev->delay = (u64)value * NSEC_PER_USEC;
+
+		sprintf(pg_result, "OK: delay=%llu",
+			(unsigned long long) pkt_dev->delay);
 		return count;
 	}
 	if (!strcmp(name, "udp_src_min")) {
@@ -2089,27 +2086,33 @@ static void pktgen_setup_inject(struct p
 	pkt_dev->nflows = 0;
 }
 
-static void spin(struct pktgen_dev *pkt_dev, __u64 spin_until_us)
+static inline s64 delta_ns(ktime_t a, ktime_t b)
+{
+	return ktime_to_ns(ktime_sub(a, b));
+}
+
+static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
 {
-	__u64 start;
-	__u64 now;
+	ktime_t start, now;
+	s64 dt;
 
-	start = now = getCurUs();
-	while (now < spin_until_us) {
+	start = now = ktime_now();
+
+	while ((dt = delta_ns(spin_until, now)) > 0) {
 		/* TODO: optimize sleeping behavior */
-		if (spin_until_us - now > jiffies_to_usecs(1) + 1)
+		if (dt > TICK_NSEC)
 			schedule_timeout_interruptible(1);
-		else if (spin_until_us - now > 100) {
+		else if (dt > 100*NSEC_PER_USEC) {
 			if (!pkt_dev->running)
 				return;
 			if (need_resched())
 				schedule();
 		}
 
-		now = getCurUs();
+		now = ktime_now();
 	}
 
-	pkt_dev->idle_acc += now - start;
+	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(now, start));
 }
 
 static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
@@ -3070,9 +3073,9 @@ static void pktgen_run(struct pktgen_thr
 			pktgen_clear_counters(pkt_dev);
 			pkt_dev->running = 1;	/* Cranke yeself! */
 			pkt_dev->skb = NULL;
-			pkt_dev->started_at = getCurUs();
-			pkt_dev->next_tx_us = getCurUs();	/* Transmit immediately */
-			pkt_dev->next_tx_ns = 0;
+			pkt_dev->started_at =
+				pkt_dev->next_tx = ktime_now();
+
 			set_pkt_overhead(pkt_dev);
 
 			strcpy(pkt_dev->result, "Starting");
@@ -3188,28 +3191,21 @@ static void pktgen_reset_all_threads(voi
 
 static void show_results(struct pktgen_dev *pkt_dev, int nr_frags)
 {
-	__u64 total_us, bps, mbps, pps, idle;
+	__u64 bps, mbps, pps;
 	char *p = pkt_dev->result;
-
-	total_us = pkt_dev->stopped_at - pkt_dev->started_at;
-
-	idle = pkt_dev->idle_acc;
-
-	p += sprintf(p, "OK: %llu(c%llu+d%llu) usec, %llu (%dbyte,%dfrags)\n",
-		     (unsigned long long)total_us,
-		     (unsigned long long)(total_us - idle),
-		     (unsigned long long)idle,
+	ktime_t elapsed = ktime_sub(pkt_dev->stopped_at,
+				    pkt_dev->started_at);
+	ktime_t idle = ns_to_ktime(pkt_dev->idle_acc);
+
+	p += sprintf(p, "OK: %llu(c%llu+d%llu) nsec, %llu (%dbyte,%dfrags)\n",
+		     (unsigned long long)ktime_to_us(elapsed),
+		     (unsigned long long)ktime_to_us(ktime_sub(elapsed, idle)),
+		     (unsigned long long)ktime_to_us(idle),
 		     (unsigned long long)pkt_dev->sofar,
 		     pkt_dev->cur_pkt_size, nr_frags);
 
-	pps = pkt_dev->sofar * USEC_PER_SEC;
-
-	while ((total_us >> 32) != 0) {
-		pps >>= 1;
-		total_us >>= 1;
-	}
-
-	do_div(pps, total_us);
+	pps = div64_u64(pkt_dev->sofar * NSEC_PER_SEC,
+			ktime_to_ns(elapsed));
 
 	bps = pps * 8 * pkt_dev->cur_pkt_size;
 
@@ -3235,7 +3231,7 @@ static int pktgen_stop_device(struct pkt
 
 	kfree_skb(pkt_dev->skb);
 	pkt_dev->skb = NULL;
-	pkt_dev->stopped_at = getCurUs();
+	pkt_dev->stopped_at = ktime_now();
 	pkt_dev->running = 0;
 
 	show_results(pkt_dev, nr_frags);
@@ -3254,7 +3250,7 @@ static struct pktgen_dev *next_to_run(st
 			continue;
 		if (best == NULL)
 			best = pkt_dev;
-		else if (pkt_dev->next_tx_us < best->next_tx_us)
+		else if (ktime_lt(pkt_dev->next_tx, best->next_tx))
 			best = pkt_dev;
 	}
 	if_unlock(t);
@@ -3343,16 +3339,17 @@ static void pktgen_rem_thread(struct pkt
 
 static void idle(struct pktgen_dev *pkt_dev)
 {
-	u64 idle_start = getCurUs();
+	ktime_t idle_start = ktime_now();
 
 	if (need_resched())
 		schedule();
 	else
 		cpu_relax();
 
-	pkt_dev->idle_acc += getCurUs() - idle_start;
+	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(), idle_start));
 }
 
+
 static void pktgen_xmit(struct pktgen_dev *pkt_dev)
 {
 	struct net_device *odev = pkt_dev->odev;
@@ -3362,19 +3359,15 @@ static void pktgen_xmit(struct pktgen_de
 	u16 queue_map;
 	int ret;
 
-	if (pkt_dev->delay_us || pkt_dev->delay_ns) {
-		u64 now;
-
-		now = getCurUs();
-		if (now < pkt_dev->next_tx_us)
-			spin(pkt_dev, pkt_dev->next_tx_us);
+	if (pkt_dev->delay) {
+		if (ktime_lt(ktime_now(), pkt_dev->next_tx))
+			spin(pkt_dev, pkt_dev->next_tx);
 
 		/* This is max DELAY, this has special meaning of
 		 * "never transmit"
 		 */
-		if (pkt_dev->delay_us == 0x7FFFFFFF) {
-			pkt_dev->next_tx_us = getCurUs() + pkt_dev->delay_us;
-			pkt_dev->next_tx_ns = pkt_dev->delay_ns;
+		if (pkt_dev->delay == ULLONG_MAX) {
+			pkt_dev->next_tx = ktime_add_ns(ktime_now(), ULONG_MAX);
 			return;
 		}
 	}
@@ -3450,32 +3443,24 @@ static void pktgen_xmit(struct pktgen_de
 			pkt_dev->last_ok = 0;
 		}
 
-		if (pkt_dev->delay_us || pkt_dev->delay_ns) {
-			pkt_dev->next_tx_us = getCurUs();
-			pkt_dev->next_tx_ns = 0;
-
-			pkt_dev->next_tx_us += pkt_dev->delay_us;
-			pkt_dev->next_tx_ns += pkt_dev->delay_ns;
-
-			if (pkt_dev->next_tx_ns > 1000) {
-				pkt_dev->next_tx_us++;
-				pkt_dev->next_tx_ns -= 1000;
-			}
-		}
+		if (pkt_dev->delay)
+			pkt_dev->next_tx = ktime_add_ns(ktime_now(),
+							pkt_dev->delay);
 	}
 	__netif_tx_unlock_bh(txq);
 
 	/* If pkt_dev->count is zero, then run forever */
 	if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
 		if (atomic_read(&(pkt_dev->skb->users)) != 1) {
-			u64 idle_start = getCurUs();
+			ktime_t idle_start = ktime_now();
 			while (atomic_read(&(pkt_dev->skb->users)) != 1) {
 				if (signal_pending(current)) {
 					break;
 				}
 				schedule();
 			}
-			pkt_dev->idle_acc += getCurUs() - idle_start;
+			pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(),
+								   idle_start));
 		}
 
 		/* Done with this */
@@ -3634,8 +3619,7 @@ static int pktgen_add_device(struct pktg
 	pkt_dev->max_pkt_size = ETH_ZLEN;
 	pkt_dev->nfrags = 0;
 	pkt_dev->clone_skb = pg_clone_skb_d;
-	pkt_dev->delay_us = pg_delay_d / 1000;
-	pkt_dev->delay_ns = pg_delay_d % 1000;
+	pkt_dev->delay = pg_delay_d;
 	pkt_dev->count = pg_count_d;
 	pkt_dev->sofar = 0;
 	pkt_dev->udp_src_min = 9;	/* sink port */

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 11/14] pktgen: spin using hrtimer
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (9 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 10/14] pktgen: convert to use ktime_t Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 12/14] pktgen: use common idle routine Stephen Hemminger
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-hrtimer-spin.patch --]
[-- Type: text/plain, Size: 2972 bytes --]

This changes how the pktgen thread spins/waits between
packets if delay is configured. It uses a high res timer to
wait for time to arrive.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 kernel/hrtimer.c  |    1 +
 net/core/pktgen.c |   49 ++++++++++++++++++++++++++++---------------------
 2 files changed, 29 insertions(+), 21 deletions(-)

--- a/net/core/pktgen.c	2009-08-27 16:00:52.538250235 -0700
+++ b/net/core/pktgen.c	2009-08-27 16:28:17.520270294 -0700
@@ -131,6 +131,7 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/capability.h>
+#include <linux/hrtimer.h>
 #include <linux/freezer.h>
 #include <linux/delay.h>
 #include <linux/timer.h>
@@ -2086,33 +2087,40 @@ static void pktgen_setup_inject(struct p
 	pkt_dev->nflows = 0;
 }
 
-static inline s64 delta_ns(ktime_t a, ktime_t b)
-{
-	return ktime_to_ns(ktime_sub(a, b));
-}
 
 static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
 {
-	ktime_t start, now;
-	s64 dt;
+	ktime_t start;
+	s32 remaining;
+	struct hrtimer_sleeper t;
 
-	start = now = ktime_now();
+	hrtimer_init_on_stack(&t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
+	hrtimer_set_expires(&t.timer, spin_until);
 
-	while ((dt = delta_ns(spin_until, now)) > 0) {
-		/* TODO: optimize sleeping behavior */
-		if (dt > TICK_NSEC)
-			schedule_timeout_interruptible(1);
-		else if (dt > 100*NSEC_PER_USEC) {
-			if (!pkt_dev->running)
-				return;
-			if (need_resched())
+	remaining = ktime_to_us(hrtimer_expires_remaining(&t.timer));
+	if (remaining <= 0)
+		return;
+
+	start = ktime_now();
+	if (remaining < 100)
+		udelay(remaining); 	/* really small just spin */
+	else {
+		/* see do_nanosleep */
+		hrtimer_init_sleeper(&t, current);
+		do {
+			set_current_state(TASK_INTERRUPTIBLE);
+			hrtimer_start_expires(&t.timer, HRTIMER_MODE_ABS);
+			if (!hrtimer_active(&t.timer))
+				t.task = NULL;
+
+			if (likely(t.task))
 				schedule();
-		}
 
-		now = ktime_now();
+			hrtimer_cancel(&t.timer);
+		} while (t.task && pkt_dev->running && !signal_pending(current));
+		__set_current_state(TASK_RUNNING);
 	}
-
-	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(now, start));
+	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(), start));
 }
 
 static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
@@ -3360,8 +3368,7 @@ static void pktgen_xmit(struct pktgen_de
 	int ret;
 
 	if (pkt_dev->delay) {
-		if (ktime_lt(ktime_now(), pkt_dev->next_tx))
-			spin(pkt_dev, pkt_dev->next_tx);
+		spin(pkt_dev, pkt_dev->next_tx);
 
 		/* This is max DELAY, this has special meaning of
 		 * "never transmit"
--- a/kernel/hrtimer.c	2009-08-27 16:00:52.547269763 -0700
+++ b/kernel/hrtimer.c	2009-08-27 16:02:04.543287103 -0700
@@ -1477,6 +1477,7 @@ void hrtimer_init_sleeper(struct hrtimer
 	sl->timer.function = hrtimer_wakeup;
 	sl->task = task;
 }
+EXPORT_SYMBOL_GPL(hrtimer_init_sleeper);
 
 static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mode)
 {

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 12/14] pktgen: use common idle routine
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (10 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 11/14] pktgen: spin using hrtimer Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 13/14] pktgen: cleanup checkpatch warnings Stephen Hemminger
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-idle-common.patch --]
[-- Type: text/plain, Size: 976 bytes --]

Simpler to have one place that spins and accounts for delays,
this will also make the last packet be detected faster for more
repeatable timing.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

--- a/net/core/pktgen.c	2009-08-27 16:28:17.520270294 -0700
+++ b/net/core/pktgen.c	2009-08-27 16:29:53.826372401 -0700
@@ -3458,16 +3458,10 @@ static void pktgen_xmit(struct pktgen_de
 
 	/* If pkt_dev->count is zero, then run forever */
 	if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
-		if (atomic_read(&(pkt_dev->skb->users)) != 1) {
-			ktime_t idle_start = ktime_now();
-			while (atomic_read(&(pkt_dev->skb->users)) != 1) {
-				if (signal_pending(current)) {
-					break;
-				}
-				schedule();
-			}
-			pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(),
-								   idle_start));
+		while (atomic_read(&(pkt_dev->skb->users)) != 1) {
+			if (signal_pending(current))
+				break;
+			idle(pkt_dev);
 		}
 
 		/* Done with this */

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 13/14] pktgen: cleanup checkpatch warnings
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (11 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 12/14] pktgen: use common idle routine Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-27 23:55 ` [PATCH 14/14] pktgen: increase version Stephen Hemminger
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-checkpatch.patch --]
[-- Type: text/plain, Size: 23511 bytes --]

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

--- a/net/core/pktgen.c	2009-08-27 16:29:53.826372401 -0700
+++ b/net/core/pktgen.c	2009-08-27 16:30:05.614687981 -0700
@@ -163,13 +163,14 @@
 #include <asm/byteorder.h>
 #include <linux/rcupdate.h>
 #include <linux/bitops.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <linux/timex.h>
+#include <linux/uaccess.h>
 #include <asm/dma.h>
-#include <asm/uaccess.h>
 #include <asm/div64.h>		/* do_div */
-#include <asm/timex.h>
 
-#define VERSION  "pktgen v2.70: 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 MAX_MPLS_LABELS 16 /* This is the max label stack depth */
@@ -207,7 +208,7 @@
 #define PKTGEN_MAGIC 0xbe9be955
 #define PG_PROC_DIR "pktgen"
 #define PGCTRL	    "pgctrl"
-static struct proc_dir_entry *pg_proc_dir = NULL;
+static struct proc_dir_entry *pg_proc_dir;
 
 #define MAX_CFLOWS  65536
 
@@ -232,9 +233,9 @@ struct pktgen_dev {
 	 */
 	struct proc_dir_entry *entry;	/* proc file */
 	struct pktgen_thread *pg_thread;/* the owner */
-	struct list_head list;		/* Used for chaining in the thread's run-queue */
+	struct list_head list;		/* chaining in the thread's run-queue */
 
-	int running;		/* if this changes to false, the test will stop */
+	int running;		/* if false, the test will stop */
 
 	/* If min != max, then we will either do a linear iteration, or
 	 * we will do a random selection from within the range.
@@ -252,15 +253,16 @@ struct pktgen_dev {
 	__u64 count;		/* Default No packets to send */
 	__u64 sofar;		/* How many pkts we've sent so far */
 	__u64 tx_bytes;		/* How many bytes we've transmitted */
-	__u64 errors;		/* Errors when trying to transmit, pkts will be re-sent */
+	__u64 errors;		/* Errors when trying to transmit,
+				   pkts will be re-sent */
 
 	/* runtime counters relating to clone_skb */
 
 	__u64 allocated_skbs;
 	__u32 clone_count;
 	int last_ok;		/* Was last skb sent?
-				 * Or a failed transmit of some sort?  This will keep
-				 * sequence numbers in order, for example.
+				 * Or a failed transmit of some sort?
+				 * This will keep sequence numbers in order
 				 */
 	ktime_t next_tx;
 	ktime_t started_at;
@@ -269,11 +271,14 @@ struct pktgen_dev {
 
 	__u32 seq_num;
 
-	int clone_skb;		/* Use multiple SKBs during packet gen.  If this number
-				 * is greater than 1, then that many copies of the same
-				 * packet will be sent before a new packet is allocated.
-				 * For instance, if you want to send 1024 identical packets
-				 * before creating a new packet, set clone_skb to 1024.
+	int clone_skb;		/*
+				 * Use multiple SKBs during packet gen.
+				 * If this number is greater than 1, then
+				 * that many copies of the same packet will be
+				 * sent before a new packet is allocated.
+				 * If you want to send 1024 identical packets
+				 * before creating a new packet,
+				 * set clone_skb to 1024.
 				 */
 
 	char dst_min[IP_NAME_SZ];	/* IP, ie 1.2.3.4 */
@@ -305,8 +310,10 @@ struct pktgen_dev {
 	__u16 udp_dst_max;	/* exclusive, dest UDP port */
 
 	/* DSCP + ECN */
-	__u8 tos;            /* six most significant bits of (former) IPv4 TOS are for dscp codepoint */
-	__u8 traffic_class;  /* ditto for the (former) Traffic Class in IPv6 (see RFC 3260, sec. 4) */
+	__u8 tos;            /* six MSB of (former) IPv4 TOS
+				are for dscp codepoint */
+	__u8 traffic_class;  /* ditto for the (former) Traffic Class in IPv6
+				(see RFC 3260, sec. 4) */
 
 	/* MPLS */
 	unsigned nr_labels;	/* Depth of stack, 0 = no MPLS */
@@ -347,15 +354,17 @@ struct pktgen_dev {
 	 */
 	__u16 pad;		/* pad out the hh struct to an even 16 bytes */
 
-	struct sk_buff *skb;	/* skb we are to transmit next, mainly used for when we
+	struct sk_buff *skb;	/* skb we are to transmit next, used for when we
 				 * are transmitting the same one multiple times
 				 */
-	struct net_device *odev;	/* The out-going device.  Note that the device should
-					 * have it's pg_info pointer pointing back to this
-					 * device.  This will be set when the user specifies
-					 * the out-going device name (not when the inject is
-					 * started as it used to do.)
-					 */
+	struct net_device *odev; /* The out-going device.
+				  * Note that the device should have it's
+				  * pg_info pointer pointing back to this
+				  * device.
+				  * Set when the user specifies the out-going
+				  * device name (not when the inject is
+				  * started as it used to do.)
+				  */
 	struct flow_state *flows;
 	unsigned cflows;	/* Concurrent flows (config) */
 	unsigned lflow;		/* Flow length  (config) */
@@ -380,13 +389,14 @@ struct pktgen_hdr {
 };
 
 struct pktgen_thread {
-	spinlock_t if_lock;
+	spinlock_t if_lock;		/* for list of devices */
 	struct list_head if_list;	/* All device here */
 	struct list_head th_list;
 	struct task_struct *tsk;
 	char result[512];
 
-	/* Field for thread to receive "posted" events terminate, stop ifs etc. */
+	/* Field for thread to receive "posted" events terminate,
+	   stop ifs etc. */
 
 	u32 control;
 	int cpu;
@@ -453,8 +463,8 @@ static int pgctrl_show(struct seq_file *
 	return 0;
 }
 
-static ssize_t pgctrl_write(struct file *file, const char __user * buf,
-			    size_t count, loff_t * ppos)
+static ssize_t pgctrl_write(struct file *file, const char __user *buf,
+			    size_t count, loff_t *ppos)
 {
 	int err = 0;
 	char data[128];
@@ -545,11 +555,14 @@ static int pktgen_if_show(struct seq_fil
 			   "     daddr: %s  min_daddr: %s  max_daddr: %s\n", b1,
 			   b2, b3);
 
-	} else
+	} else {
+		seq_printf(seq,
+			   "     dst_min: %s  dst_max: %s\n",
+			   pkt_dev->dst_min, pkt_dev->dst_max);
 		seq_printf(seq,
-			   "     dst_min: %s  dst_max: %s\n     src_min: %s  src_max: %s\n",
-			   pkt_dev->dst_min, pkt_dev->dst_max, pkt_dev->src_min,
-			   pkt_dev->src_max);
+			   "        src_min: %s  src_max: %s\n",
+			   pkt_dev->src_min, pkt_dev->src_max);
+	}
 
 	seq_puts(seq, "     src_mac: ");
 
@@ -561,7 +574,8 @@ static int pktgen_if_show(struct seq_fil
 	seq_printf(seq, "%pM\n", pkt_dev->dst_mac);
 
 	seq_printf(seq,
-		   "     udp_src_min: %d  udp_src_max: %d  udp_dst_min: %d  udp_dst_max: %d\n",
+		   "     udp_src_min: %d  udp_src_max: %d"
+		   "  udp_dst_min: %d  udp_dst_max: %d\n",
 		   pkt_dev->udp_src_min, pkt_dev->udp_src_max,
 		   pkt_dev->udp_dst_min, pkt_dev->udp_dst_max);
 
@@ -577,23 +591,21 @@ static int pktgen_if_show(struct seq_fil
 				   i == pkt_dev->nr_labels-1 ? "\n" : ", ");
 	}
 
-	if (pkt_dev->vlan_id != 0xffff) {
+	if (pkt_dev->vlan_id != 0xffff)
 		seq_printf(seq, "     vlan_id: %u  vlan_p: %u  vlan_cfi: %u\n",
-			   pkt_dev->vlan_id, pkt_dev->vlan_p, pkt_dev->vlan_cfi);
-	}
+			   pkt_dev->vlan_id, pkt_dev->vlan_p,
+			   pkt_dev->vlan_cfi);
 
-	if (pkt_dev->svlan_id != 0xffff) {
+	if (pkt_dev->svlan_id != 0xffff)
 		seq_printf(seq, "     svlan_id: %u  vlan_p: %u  vlan_cfi: %u\n",
-			   pkt_dev->svlan_id, pkt_dev->svlan_p, pkt_dev->svlan_cfi);
-	}
+			   pkt_dev->svlan_id, pkt_dev->svlan_p,
+			   pkt_dev->svlan_cfi);
 
-	if (pkt_dev->tos) {
+	if (pkt_dev->tos)
 		seq_printf(seq, "     tos: 0x%02x\n", pkt_dev->tos);
-	}
 
-	if (pkt_dev->traffic_class) {
+	if (pkt_dev->traffic_class)
 		seq_printf(seq, "     traffic_class: 0x%02x\n", pkt_dev->traffic_class);
-	}
 
 	seq_printf(seq, "     Flags: ");
 
@@ -696,7 +708,8 @@ static int pktgen_if_show(struct seq_fil
 }
 
 
-static int hex32_arg(const char __user *user_buffer, unsigned long maxlen, __u32 *num)
+static int hex32_arg(const char __user *user_buffer, unsigned long maxlen,
+		     __u32 *num)
 {
 	int i = 0;
 	*num = 0;
@@ -846,9 +859,9 @@ static ssize_t pktgen_if_write(struct fi
 	/* Read variable name */
 
 	len = strn_len(&user_buffer[i], sizeof(name) - 1);
-	if (len < 0) {
+	if (len < 0)
 		return len;
-	}
+
 	memset(name, 0, sizeof(name));
 	if (copy_from_user(name, &user_buffer[i], len))
 		return -EFAULT;
@@ -872,9 +885,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "min_pkt_size")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value < 14 + 20 + 8)
 			value = 14 + 20 + 8;
@@ -889,9 +902,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "max_pkt_size")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value < 14 + 20 + 8)
 			value = 14 + 20 + 8;
@@ -908,9 +921,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "pkt_size")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value < 14 + 20 + 8)
 			value = 14 + 20 + 8;
@@ -925,9 +938,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "debug")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		debug = value;
 		sprintf(pg_result, "OK: debug=%u", debug);
@@ -936,9 +949,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "frags")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->nfrags = value;
 		sprintf(pg_result, "OK: frags=%u", pkt_dev->nfrags);
@@ -946,9 +959,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "delay")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value == 0x7FFFFFFF)
 			pkt_dev->delay = ULLONG_MAX;
@@ -961,9 +974,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "udp_src_min")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value != pkt_dev->udp_src_min) {
 			pkt_dev->udp_src_min = value;
@@ -974,9 +987,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "udp_dst_min")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value != pkt_dev->udp_dst_min) {
 			pkt_dev->udp_dst_min = value;
@@ -987,9 +1000,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "udp_src_max")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value != pkt_dev->udp_src_max) {
 			pkt_dev->udp_src_max = value;
@@ -1000,9 +1013,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "udp_dst_max")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value != pkt_dev->udp_dst_max) {
 			pkt_dev->udp_dst_max = value;
@@ -1013,9 +1026,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "clone_skb")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->clone_skb = value;
 
@@ -1024,9 +1037,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->count = value;
 		sprintf(pg_result, "OK: count=%llu",
@@ -1035,9 +1048,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "src_mac_count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (pkt_dev->src_mac_count != value) {
 			pkt_dev->src_mac_count = value;
@@ -1049,9 +1062,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "dst_mac_count")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (pkt_dev->dst_mac_count != value) {
 			pkt_dev->dst_mac_count = value;
@@ -1065,9 +1078,9 @@ static ssize_t pktgen_if_write(struct fi
 		char f[32];
 		memset(f, 0, 32);
 		len = strn_len(&user_buffer[i], sizeof(f) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		if (copy_from_user(f, &user_buffer[i], len))
 			return -EFAULT;
 		i += len;
@@ -1166,9 +1179,8 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "dst_min") || !strcmp(name, "dst")) {
 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_min) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
 
 		if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
@@ -1188,9 +1200,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "dst_max")) {
 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->dst_max) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 
 		if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
@@ -1301,9 +1313,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "src_min")) {
 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_min) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
 		buf[len] = 0;
@@ -1322,9 +1334,9 @@ static ssize_t pktgen_if_write(struct fi
 	}
 	if (!strcmp(name, "src_max")) {
 		len = strn_len(&user_buffer[i], sizeof(pkt_dev->src_max) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		if (copy_from_user(buf, &user_buffer[i], len))
 			return -EFAULT;
 		buf[len] = 0;
@@ -1348,9 +1360,9 @@ static ssize_t pktgen_if_write(struct fi
 		memcpy(old_dmac, pkt_dev->dst_mac, ETH_ALEN);
 
 		len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		memset(valstr, 0, sizeof(valstr));
 		if (copy_from_user(valstr, &user_buffer[i], len))
 			return -EFAULT;
@@ -1390,9 +1402,9 @@ static ssize_t pktgen_if_write(struct fi
 		memcpy(old_smac, pkt_dev->src_mac, ETH_ALEN);
 
 		len = strn_len(&user_buffer[i], sizeof(valstr) - 1);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		memset(valstr, 0, sizeof(valstr));
 		if (copy_from_user(valstr, &user_buffer[i], len))
 			return -EFAULT;
@@ -1433,9 +1445,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "flows")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value > MAX_CFLOWS)
 			value = MAX_CFLOWS;
@@ -1447,9 +1459,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "flowlen")) {
 		len = num_arg(&user_buffer[i], 10, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->lflow = value;
 		sprintf(pg_result, "OK: flowlen=%u", pkt_dev->lflow);
@@ -1458,9 +1470,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "queue_map_min")) {
 		len = num_arg(&user_buffer[i], 5, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->queue_map_min = value;
 		sprintf(pg_result, "OK: queue_map_min=%u", pkt_dev->queue_map_min);
@@ -1469,9 +1481,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "queue_map_max")) {
 		len = num_arg(&user_buffer[i], 5, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		pkt_dev->queue_map_max = value;
 		sprintf(pg_result, "OK: queue_map_max=%u", pkt_dev->queue_map_max);
@@ -1503,9 +1515,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "vlan_id")) {
 		len = num_arg(&user_buffer[i], 4, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (value <= 4095) {
 			pkt_dev->vlan_id = value;  /* turn on VLAN */
@@ -1530,9 +1542,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "vlan_p")) {
 		len = num_arg(&user_buffer[i], 1, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if ((value <= 7) && (pkt_dev->vlan_id != 0xffff)) {
 			pkt_dev->vlan_p = value;
@@ -1545,9 +1557,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "vlan_cfi")) {
 		len = num_arg(&user_buffer[i], 1, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if ((value <= 1) && (pkt_dev->vlan_id != 0xffff)) {
 			pkt_dev->vlan_cfi = value;
@@ -1560,9 +1572,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "svlan_id")) {
 		len = num_arg(&user_buffer[i], 4, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if ((value <= 4095) && ((pkt_dev->vlan_id != 0xffff))) {
 			pkt_dev->svlan_id = value;  /* turn on SVLAN */
@@ -1587,9 +1599,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "svlan_p")) {
 		len = num_arg(&user_buffer[i], 1, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if ((value <= 7) && (pkt_dev->svlan_id != 0xffff)) {
 			pkt_dev->svlan_p = value;
@@ -1602,9 +1614,9 @@ static ssize_t pktgen_if_write(struct fi
 
 	if (!strcmp(name, "svlan_cfi")) {
 		len = num_arg(&user_buffer[i], 1, &value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if ((value <= 1) && (pkt_dev->svlan_id != 0xffff)) {
 			pkt_dev->svlan_cfi = value;
@@ -1618,9 +1630,9 @@ static ssize_t pktgen_if_write(struct fi
 	if (!strcmp(name, "tos")) {
 		__u32 tmp_value = 0;
 		len = hex32_arg(&user_buffer[i], 2, &tmp_value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (len == 2) {
 			pkt_dev->tos = tmp_value;
@@ -1634,9 +1646,9 @@ static ssize_t pktgen_if_write(struct fi
 	if (!strcmp(name, "traffic_class")) {
 		__u32 tmp_value = 0;
 		len = hex32_arg(&user_buffer[i], 2, &tmp_value);
-		if (len < 0) {
+		if (len < 0)
 			return len;
-		}
+
 		i += len;
 		if (len == 2) {
 			pkt_dev->traffic_class = tmp_value;
@@ -1906,13 +1918,14 @@ static int pktgen_device_event(struct no
 	return NOTIFY_DONE;
 }
 
-static struct net_device *pktgen_dev_get_by_name(struct pktgen_dev *pkt_dev, const char *ifname)
+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)
+	for (i = 0; ifname[i] != '@'; i++) {
+		if (i == IFNAMSIZ)
 			break;
 
 		b[i] = ifname[i];
@@ -1979,7 +1992,7 @@ static void pktgen_setup_inject(struct p
 		printk(KERN_WARNING "pktgen: WARNING: Requested "
 		       "queue_map_min (zero-based) (%d) exceeds valid range "
 		       "[0 - %d] for (%d) queues on %s, resetting\n",
-		       pkt_dev->queue_map_min, (ntxq ?: 1)- 1, ntxq,
+		       pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq,
 		       pkt_dev->odev->name);
 		pkt_dev->queue_map_min = ntxq - 1;
 	}
@@ -1987,7 +2000,7 @@ static void pktgen_setup_inject(struct p
 		printk(KERN_WARNING "pktgen: WARNING: Requested "
 		       "queue_map_max (zero-based) (%d) exceeds valid range "
 		       "[0 - %d] for (%d) queues on %s, resetting\n",
-		       pkt_dev->queue_map_max, (ntxq ?: 1)- 1, ntxq,
+		       pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq,
 		       pkt_dev->odev->name);
 		pkt_dev->queue_map_max = ntxq - 1;
 	}
@@ -2028,7 +2041,8 @@ static void pktgen_setup_inject(struct p
 			 */
 
 			rcu_read_lock();
-			if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) {
+			idev = __in6_dev_get(pkt_dev->odev);
+			if (idev) {
 				struct inet6_ifaddr *ifp;
 
 				read_lock_bh(&idev->lock);
@@ -2181,7 +2195,7 @@ static void get_ipsec_sa(struct pktgen_d
 		if (x) {
 			pkt_dev->flows[flow].x = x;
 			set_pkt_overhead(pkt_dev);
-			pkt_dev->pkt_overhead+=x->props.header_len;
+			pkt_dev->pkt_overhead += x->props.header_len;
 		}
 
 	}
@@ -2320,18 +2334,18 @@ static void mod_cur_headers(struct pktge
 
 	if (!(pkt_dev->flags & F_IPV6)) {
 
-		if ((imn = ntohl(pkt_dev->saddr_min)) < (imx =
-							 ntohl(pkt_dev->
-							       saddr_max))) {
+		imn = ntohl(pkt_dev->saddr_min);
+		imx = ntohl(pkt_dev->saddr_max);
+		if (imn < imx) {
 			__u32 t;
 			if (pkt_dev->flags & F_IPSRC_RND)
 				t = random32() % (imx - imn) + imn;
 			else {
 				t = ntohl(pkt_dev->cur_saddr);
 				t++;
-				if (t > imx) {
+				if (t > imx)
 					t = imn;
-				}
+
 			}
 			pkt_dev->cur_saddr = htonl(t);
 		}
@@ -2442,7 +2456,7 @@ static int pktgen_output_ipsec(struct sk
 	if (err)
 		goto error;
 
-	x->curlft.bytes +=skb->len;
+	x->curlft.bytes += skb->len;
 	x->curlft.packets++;
 error:
 	spin_unlock(&x->lock);
@@ -2474,11 +2488,11 @@ static int process_ipsec(struct pktgen_d
 			int ret;
 			__u8 *eth;
 			nhead = x->props.header_len - skb_headroom(skb);
-			if (nhead >0) {
+			if (nhead > 0) {
 				ret = pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
 				if (ret < 0) {
 					printk(KERN_ERR "Error expanding "
-					       "ipsec packet %d\n",ret);
+					       "ipsec packet %d\n", ret);
 					goto err;
 				}
 			}
@@ -2488,13 +2502,13 @@ static int process_ipsec(struct pktgen_d
 			ret = pktgen_output_ipsec(skb, pkt_dev);
 			if (ret) {
 				printk(KERN_ERR "Error creating ipsec "
-				       "packet %d\n",ret);
+				       "packet %d\n", ret);
 				goto err;
 			}
 			/* restore ll */
 			eth = (__u8 *) skb_push(skb, ETH_HLEN);
 			memcpy(eth, pkt_dev->hh, 12);
-			*(u16 *) & eth[12] = protocol;
+			*(u16 *) &eth[12] = protocol;
 		}
 	}
 	return 1;
@@ -2507,9 +2521,9 @@ err:
 static void mpls_push(__be32 *mpls, struct pktgen_dev *pkt_dev)
 {
 	unsigned i;
-	for (i = 0; i < pkt_dev->nr_labels; i++) {
+	for (i = 0; i < pkt_dev->nr_labels; i++)
 		*mpls++ = pkt_dev->labels[i] & ~MPLS_STACK_BOTTOM;
-	}
+
 	mpls--;
 	*mpls |= MPLS_STACK_BOTTOM;
 }
@@ -2676,8 +2690,9 @@ static struct sk_buff *fill_packet_ipv4(
 		}
 	}
 
-	/* Stamp the time, and sequence number, convert them to network byte order */
-
+	/* Stamp the time, and sequence number,
+	 * convert them to network byte order
+	 */
 	if (pgh) {
 		struct timeval timestamp;
 
@@ -2931,7 +2946,7 @@ static struct sk_buff *fill_packet_ipv6(
 	udph = udp_hdr(skb);
 
 	memcpy(eth, pkt_dev->hh, 12);
-	*(__be16 *) & eth[12] = protocol;
+	*(__be16 *) &eth[12] = protocol;
 
 	/* Eth + IPh + UDPh + mpls */
 	datalen = pkt_dev->cur_pkt_size - 14 -
@@ -3025,8 +3040,10 @@ static struct sk_buff *fill_packet_ipv6(
 		}
 	}
 
-	/* Stamp the time, and sequence number, convert them to network byte order */
-	/* should we update cloned packets too ? */
+	/* Stamp the time, and sequence number,
+	 * convert them to network byte order
+	 * should we update cloned packets too ?
+	 */
 	if (pgh) {
 		struct timeval timestamp;
 
@@ -3174,7 +3191,8 @@ static void pktgen_run_all_threads(void)
 
 	mutex_unlock(&pktgen_thread_lock);
 
-	schedule_timeout_interruptible(msecs_to_jiffies(125));	/* Propagate thread->control  */
+	/* Propagate thread->control  */
+	schedule_timeout_interruptible(msecs_to_jiffies(125));
 
 	pktgen_wait_all_threads_run();
 }
@@ -3192,7 +3210,8 @@ static void pktgen_reset_all_threads(voi
 
 	mutex_unlock(&pktgen_thread_lock);
 
-	schedule_timeout_interruptible(msecs_to_jiffies(125));	/* Propagate thread->control  */
+	/* Propagate thread->control  */
+	schedule_timeout_interruptible(msecs_to_jiffies(125));
 
 	pktgen_wait_all_threads_run();
 }
@@ -3485,7 +3504,8 @@ static int pktgen_thread_worker(void *ar
 	init_waitqueue_head(&t->queue);
 	complete(&t->start_done);
 
-	pr_debug("pktgen: starting pktgen/%d:  pid=%d\n", cpu, task_pid_nr(current));
+	pr_debug("pktgen: starting pktgen/%d:  pid=%d\n",
+		 cpu, task_pid_nr(current));
 
 	set_current_state(TASK_INTERRUPTIBLE);
 

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 14/14] pktgen: increase version
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (12 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 13/14] pktgen: cleanup checkpatch warnings Stephen Hemminger
@ 2009-08-27 23:55 ` Stephen Hemminger
  2009-08-29  6:33 ` [PATCH 00/14] pktgen update for net-next (2.6.32) David Miller
  2009-09-08 11:52 ` robert
  15 siblings, 0 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-27 23:55 UTC (permalink / raw)
  To: David Miller, Robert Olsson; +Cc: netdev, Thomas Gleixner

[-- Attachment #1: pktgen-version.patch --]
[-- Type: text/plain, Size: 1929 bytes --]

Increase module version, and cleanup module info.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/net/core/pktgen.c	2009-08-27 16:30:05.614687981 -0700
+++ b/net/core/pktgen.c	2009-08-27 16:34:18.584537961 -0700
@@ -169,9 +169,7 @@
 #include <asm/dma.h>
 #include <asm/div64.h>		/* do_div */
 
-#define VERSION \
-	"pktgen v2.70: Packet Generator for packet performance testing.\n"
-
+#define VERSION 	"2.72"
 #define IP_NAME_SZ 32
 #define MAX_MPLS_LABELS 16 /* This is the max label stack depth */
 #define MPLS_STACK_BOTTOM htonl(0x00000100)
@@ -422,7 +420,8 @@ static inline int ktime_lt(const ktime_t
 	return cmp1.tv64 < cmp2.tv64;
 }
 
-static const char version[] __initconst = VERSION;
+static const char version[] =
+	"pktgen " VERSION ": Packet Generator for packet performance testing.\n";
 
 static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i);
 static int pktgen_add_device(struct pktgen_thread *t, const char *ifname);
@@ -459,7 +458,7 @@ static struct notifier_block pktgen_noti
 
 static int pgctrl_show(struct seq_file *seq, void *v)
 {
-	seq_puts(seq, VERSION);
+	seq_puts(seq, version);
 	return 0;
 }
 
@@ -3852,10 +3851,15 @@ static void __exit pg_cleanup(void)
 module_init(pg_init);
 module_exit(pg_cleanup);
 
-MODULE_AUTHOR("Robert Olsson <robert.olsson@its.uu.se");
+MODULE_AUTHOR("Robert Olsson <robert.olsson@its.uu.se>");
 MODULE_DESCRIPTION("Packet Generator tool");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(VERSION);
 module_param(pg_count_d, int, 0);
+MODULE_PARM_DESC(pg_count_d, "Default number of packets to inject");
 module_param(pg_delay_d, int, 0);
+MODULE_PARM_DESC(pg_delay_d, "Default delay between packets (nanoseconds)");
 module_param(pg_clone_skb_d, int, 0);
+MODULE_PARM_DESC(pg_clone_skb_d, "Default number of copies of the same packet");
 module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "Enable debugging of pktgen module");

-- 


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/14] pktgen: reorganize transmit loop
  2009-08-27 23:55 ` [PATCH 08/14] pktgen: reorganize transmit loop Stephen Hemminger
@ 2009-08-28  3:52   ` Ben Greear
  2009-08-28  5:49     ` Stephen Hemminger
  0 siblings, 1 reply; 28+ messages in thread
From: Ben Greear @ 2009-08-28  3:52 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, Robert Olsson, netdev, Thomas Gleixner

+		default: /* Drivers are not supposed to return other values! */
+			if (net_ratelimit())
+				pr_info("pktgen: %s xmit error: %d\n",
+					odev->name, ret);
 			pkt_dev->errors++;

I believe this is faulty.  Things like vlans can send pkts to qdiscs
of the underlying device and those can return other values.

Patric McHardy put in some patches recently to achieve this in a more
uniform manner:

http://patchwork.ozlabs.org/patch/28340/

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com> 
Candela Technologies Inc  http://www.candelatech.com



^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/14] pktgen: reorganize transmit loop
  2009-08-28  3:52   ` Ben Greear
@ 2009-08-28  5:49     ` Stephen Hemminger
  2009-08-28 16:01       ` Ben Greear
  2009-08-29  6:04       ` David Miller
  0 siblings, 2 replies; 28+ messages in thread
From: Stephen Hemminger @ 2009-08-28  5:49 UTC (permalink / raw)
  To: Ben Greear; +Cc: David Miller, Robert Olsson, netdev, Thomas Gleixner

On Thu, 27 Aug 2009 20:52:32 -0700
Ben Greear <greearb@candelatech.com> wrote:

> +		default: /* Drivers are not supposed to return other
> values! */
> +			if (net_ratelimit())
> +				pr_info("pktgen: %s xmit error:
> %d\n",
> +					odev->name, ret);
>  			pkt_dev->errors++;
> 
> I believe this is faulty.  Things like vlans can send pkts to qdiscs
> of the underlying device and those can return other values.
> 
> Patric McHardy put in some patches recently to achieve this in a more
> uniform manner:
> 
> http://patchwork.ozlabs.org/patch/28340/
> 
> Thanks,
> Ben
> 

Since pktgen has its own way of generating vlan tags, it
makes no sense to use it on top of 8021q vlan driver.


-- 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/14] pktgen: reorganize transmit loop
  2009-08-28  5:49     ` Stephen Hemminger
@ 2009-08-28 16:01       ` Ben Greear
  2009-08-29  6:04       ` David Miller
  1 sibling, 0 replies; 28+ messages in thread
From: Ben Greear @ 2009-08-28 16:01 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, Robert Olsson, netdev, Thomas Gleixner

On 08/27/2009 10:49 PM, Stephen Hemminger wrote:
> On Thu, 27 Aug 2009 20:52:32 -0700
> Ben Greear<greearb@candelatech.com>  wrote:
>
>> +		default: /* Drivers are not supposed to return other
>> values! */
>> +			if (net_ratelimit())
>> +				pr_info("pktgen: %s xmit error:
>> %d\n",
>> +					odev->name, ret);
>>   			pkt_dev->errors++;
>>
>> I believe this is faulty.  Things like vlans can send pkts to qdiscs
>> of the underlying device and those can return other values.
>>
>> Patric McHardy put in some patches recently to achieve this in a more
>> uniform manner:
>>
>> http://patchwork.ozlabs.org/patch/28340/
>>
>> Thanks,
>> Ben
>>
>
> Since pktgen has its own way of generating vlan tags, it
> makes no sense to use it on top of 8021q vlan driver.

Maybe someone wants to test their virtual device driver using pktgen?

Or generate traffic with lots of different vlan IDs & associated
IP, mac-addresses, etc?

Same issue applies to mac-vlans and possibly other virtual devices.

Thanks,
Ben

-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com


^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/14] pktgen: reorganize transmit loop
  2009-08-28  5:49     ` Stephen Hemminger
  2009-08-28 16:01       ` Ben Greear
@ 2009-08-29  6:04       ` David Miller
  2009-09-01 21:30         ` Stephen Hemminger
  1 sibling, 1 reply; 28+ messages in thread
From: David Miller @ 2009-08-29  6:04 UTC (permalink / raw)
  To: shemminger; +Cc: greearb, robert.olsson, netdev, tglx

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Thu, 27 Aug 2009 22:49:02 -0700

> On Thu, 27 Aug 2009 20:52:32 -0700
> Ben Greear <greearb@candelatech.com> wrote:
> 
>> +		default: /* Drivers are not supposed to return other
>> values! */
>> +			if (net_ratelimit())
>> +				pr_info("pktgen: %s xmit error:
>> %d\n",
>> +					odev->name, ret);
>>  			pkt_dev->errors++;
>> 
>> I believe this is faulty.  Things like vlans can send pkts to qdiscs
>> of the underlying device and those can return other values.
>> 
>> Patric McHardy put in some patches recently to achieve this in a more
>> uniform manner:
>> 
>> http://patchwork.ozlabs.org/patch/28340/
>> 
>> Thanks,
>> Ben
>> 
> 
> Since pktgen has its own way of generating vlan tags, it
> makes no sense to use it on top of 8021q vlan driver.

I think Patrick's goals are quite sound, and with his patch we
could let pktgen transmit over vlan just like any other device.

Otherwise we give no way to use pktgen to test the VLAN transmit path.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/14] pktgen update for net-next (2.6.32)
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (13 preceding siblings ...)
  2009-08-27 23:55 ` [PATCH 14/14] pktgen: increase version Stephen Hemminger
@ 2009-08-29  6:33 ` David Miller
  2009-08-29  6:42   ` David Miller
  2009-09-08 11:52 ` robert
  15 siblings, 1 reply; 28+ messages in thread
From: David Miller @ 2009-08-29  6:33 UTC (permalink / raw)
  To: shemminger; +Cc: robert.olsson, netdev, tglx

From: Stephen Hemminger <shemminger@vyatta.com>
Date: Thu, 27 Aug 2009 16:55:06 -0700

> The biggest change is switching to monotonic clock (ktime) and
> high resolution timers for the interpacket delay.

Ok, even though there were some issues with the TX return
values wrt. VLANS, I've applied all of this.

The cleanups were good and hrtimers and ktime_t are definitely
the direction this code should go in.

It would be good if this new stuff got a lot of testing and debugging
though.

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/14] pktgen update for net-next (2.6.32)
  2009-08-29  6:33 ` [PATCH 00/14] pktgen update for net-next (2.6.32) David Miller
@ 2009-08-29  6:42   ` David Miller
  0 siblings, 0 replies; 28+ messages in thread
From: David Miller @ 2009-08-29  6:42 UTC (permalink / raw)
  To: shemminger; +Cc: robert.olsson, netdev, tglx

From: David Miller <davem@davemloft.net>
Date: Fri, 28 Aug 2009 23:33:20 -0700 (PDT)

> From: Stephen Hemminger <shemminger@vyatta.com>
> Date: Thu, 27 Aug 2009 16:55:06 -0700
> 
>> The biggest change is switching to monotonic clock (ktime) and
>> high resolution timers for the interpacket delay.
> 
> Ok, even though there were some issues with the TX return
> values wrt. VLANS, I've applied all of this.
> 
> The cleanups were good and hrtimers and ktime_t are definitely
> the direction this code should go in.
> 
> It would be good if this new stuff got a lot of testing and debugging
> though.

BTW, to make this build in all cases I had to add a symbol export
for hrtimer_init_on_stack().

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/14] pktgen: reorganize transmit loop
  2009-08-29  6:04       ` David Miller
@ 2009-09-01 21:30         ` Stephen Hemminger
  2009-09-02 13:06           ` Patrick McHardy
  0 siblings, 1 reply; 28+ messages in thread
From: Stephen Hemminger @ 2009-09-01 21:30 UTC (permalink / raw)
  To: David Miller; +Cc: greearb, robert.olsson, netdev, tglx

On Fri, 28 Aug 2009 23:04:28 -0700 (PDT)
David Miller <davem@davemloft.net> wrote:

> From: Stephen Hemminger <shemminger@vyatta.com>
> Date: Thu, 27 Aug 2009 22:49:02 -0700
> 
> > On Thu, 27 Aug 2009 20:52:32 -0700
> > Ben Greear <greearb@candelatech.com> wrote:
> > 
> >> +		default: /* Drivers are not supposed to return other
> >> values! */
> >> +			if (net_ratelimit())
> >> +				pr_info("pktgen: %s xmit error:
> >> %d\n",
> >> +					odev->name, ret);
> >>  			pkt_dev->errors++;
> >> 
> >> I believe this is faulty.  Things like vlans can send pkts to qdiscs
> >> of the underlying device and those can return other values.
> >> 
> >> Patric McHardy put in some patches recently to achieve this in a more
> >> uniform manner:
> >> 
> >> http://patchwork.ozlabs.org/patch/28340/
> >> 
> >> Thanks,
> >> Ben
> >> 
> > 
> > Since pktgen has its own way of generating vlan tags, it
> > makes no sense to use it on top of 8021q vlan driver.
> 
> I think Patrick's goals are quite sound, and with his patch we
> could let pktgen transmit over vlan just like any other device.
> 
> Otherwise we give no way to use pktgen to test the VLAN transmit path.

The only valid returns from device are OK, BUSY, or LOCKED
anything else is an error and should never occur.

If the vlan code returns other values, it must translate.

-- 

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 08/14] pktgen: reorganize transmit loop
  2009-09-01 21:30         ` Stephen Hemminger
@ 2009-09-02 13:06           ` Patrick McHardy
  0 siblings, 0 replies; 28+ messages in thread
From: Patrick McHardy @ 2009-09-02 13:06 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, greearb, robert.olsson, netdev, tglx

Stephen Hemminger wrote:
> On Fri, 28 Aug 2009 23:04:28 -0700 (PDT)
> David Miller <davem@davemloft.net> wrote:
> 
>> I think Patrick's goals are quite sound, and with his patch we
>> could let pktgen transmit over vlan just like any other device.
>>
>> Otherwise we give no way to use pktgen to test the VLAN transmit path.
> 
> The only valid returns from device are OK, BUSY, or LOCKED
> anything else is an error and should never occur.
> 
> If the vlan code returns other values, it must translate.

That was part of my patches to allow hard_start_xmit() to return
NETDEV_TX codes, NET_XMIT codes to propagate transmission qdisc state
upwards through virtual devices, as well as errno codes to propagate
errors from virtual devices, like EHOSTUNREACH from an IP tunnel device.

I'll refresh that patch and will post it tonight or tommorrow.


^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH 00/14] pktgen update for net-next (2.6.32)
  2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
                   ` (14 preceding siblings ...)
  2009-08-29  6:33 ` [PATCH 00/14] pktgen update for net-next (2.6.32) David Miller
@ 2009-09-08 11:52 ` robert
  2009-09-08 12:21   ` Jesper Dangaard Brouer
  15 siblings, 1 reply; 28+ messages in thread
From: robert @ 2009-09-08 11:52 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: David Miller, Robert Olsson, netdev, Thomas Gleixner


Stephen Hemminger writes:
 > The biggest change is switching to monotonic clock (ktime) and
 > high resolution timers for the interpacket delay.

Opteron Barcelona 2.3 GHz with net-next 2.6.31-rc5bifrost-x86_64.

Sending different pkt-sizes at maxrate using one CPU-core (of eight) 
with ixgbe driver and Intel's 82598 chip.

      w. patch
64    4761904    3846153
128   4545454    3703703
256   4545454    3703703
512   2380952    2380952
1024  1204819    1204819
1500   826446     826446

We increase max sending rate from 3.8 Mpps to 4.8 Mpps for 64 byte pkts

Thanks a lot Stephen.

Cheers
                                        --ro

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/14] pktgen update for net-next (2.6.32)
  2009-09-08 11:52 ` robert
@ 2009-09-08 12:21   ` Jesper Dangaard Brouer
  2009-09-08 15:41     ` robert
  0 siblings, 1 reply; 28+ messages in thread
From: Jesper Dangaard Brouer @ 2009-09-08 12:21 UTC (permalink / raw)
  To: robert
  Cc: Stephen Hemminger, David Miller, Robert Olsson, netdev,
	Thomas Gleixner


On Tue, 8 Sep 2009, robert@herjulf.net wrote:
> Stephen Hemminger writes:
> > The biggest change is switching to monotonic clock (ktime) and
> > high resolution timers for the interpacket delay.
>
> Opteron Barcelona 2.3 GHz with net-next 2.6.31-rc5bifrost-x86_64.
>
> Sending different pkt-sizes at maxrate using one CPU-core (of eight)
> with ixgbe driver and Intel's 82598 chip.
>
>      w. patch
> 64    4761904    3846153
> 128   4545454    3703703
> 256   4545454    3703703
> 512   2380952    2380952
> 1024  1204819    1204819
> 1500   826446     826446
>
> We increase max sending rate from 3.8 Mpps to 4.8 Mpps for 64 byte pkts

I can also measure a performance improvement.

Generator machine, AMD Phenom 9950 quad core, using a 10GbE Intel 82599 
NIC (6 port 10GbE from Hotlava Systems Inc.).

With patches:
-------------
tx_pkt_sz: 64  TX-pps: 9426724
tx_pkt_sz: 128 TX-pps: 8220396
tx_pkt_sz: 256 TX-pps: 4463415
tx_pkt_sz: 384 TX-pps: 3063025
tx_pkt_sz: 512 TX-pps: 2331636
tx_pkt_sz: 640 TX-pps: 1879640
tx_pkt_sz: 768 TX-pps: 1577957
tx_pkt_sz: 896 TX-pps: 1359122
tx_pkt_sz: 1024 TX-pps: 1193118
tx_pkt_sz: 1152 TX-pps: 1062726
tx_pkt_sz: 1280 TX-pps: 958408
tx_pkt_sz: 1408 TX-pps: 873167
tx_pkt_sz: 1514 TX-pps: 812591

Without patches:
----------------
tx_pkt_sz: 64  TX-pps: 8372361
tx_pkt_sz: 128 TX-pps: 7915717
tx_pkt_sz: 256 TX-pps: 4462400
tx_pkt_sz: 384 TX-pps: 3059712
tx_pkt_sz: 512 TX-pps: 2332164
tx_pkt_sz: 640 TX-pps: 1882343
tx_pkt_sz: 768 TX-pps: 1577543
tx_pkt_sz: 896 TX-pps: 1358061
tx_pkt_sz: 1024 TX-pps: 1192788
tx_pkt_sz: 1152 TX-pps: 1062959
tx_pkt_sz: 1280 TX-pps: 958622
tx_pkt_sz: 1408 TX-pps: 872934
tx_pkt_sz: 1514 TX-pps: 812771

It really makes a difference for small packet sizes.

  64 bytes pkts: 8.4 Mpps to 9.4 Mpps.
128 bytes pkts: 7.9 Mpps to 8.2 Mpps

Notice that the numbers for pkt sizes above 128 bytes are really close to 
wirespeed 10GbE rates, when taking ethernet framing into account.

> Thanks a lot Stephen.

Yes, thanks a lot Stephen! :-)

Cheers,
   Jesper Brouer

--
-------------------------------------------------------------------
MSc. Master of Computer Science
Dept. of Computer Science, University of Copenhagen
Author of http://www.adsl-optimizer.dk
-------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/14] pktgen update for net-next (2.6.32)
  2009-09-08 12:21   ` Jesper Dangaard Brouer
@ 2009-09-08 15:41     ` robert
  2009-09-09  7:53       ` Jesper Dangaard Brouer
  0 siblings, 1 reply; 28+ messages in thread
From: robert @ 2009-09-08 15:41 UTC (permalink / raw)
  To: Jesper Dangaard Brouer
  Cc: robert, Stephen Hemminger, David Miller, Robert Olsson, netdev,
	Thomas Gleixner



On Tue, 8 Sep 2009, robert@herjulf.net wrote:
>>
>> Sending different pkt-sizes at maxrate using one CPU-core (of eight)
>> with ixgbe driver and Intel's 82598 chip.
>>
>>      w. patch
>> 64    4761904    3846153

>I can also measure a performance improvement.

> Generator machine, AMD Phenom 9950 quad core, using a 10GbE Intel 82599 
> NIC (6 port 10GbE from Hotlava Systems Inc.).

> With patches:
> -------------
> tx_pkt_sz: 64  TX-pps: 9426724

Impressive. 82599 seems fast. Didn't you report even higher number
with other CPU's?

Cheers
					--ro

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/14] pktgen update for net-next (2.6.32)
  2009-09-08 15:41     ` robert
@ 2009-09-09  7:53       ` Jesper Dangaard Brouer
  2009-09-11 14:29         ` Jesper Dangaard Brouer
  0 siblings, 1 reply; 28+ messages in thread
From: Jesper Dangaard Brouer @ 2009-09-09  7:53 UTC (permalink / raw)
  To: robert
  Cc: Stephen Hemminger, David Miller, Robert Olsson, netdev,
	Thomas Gleixner

On Tue, 8 Sep 2009, robert@herjulf.net wrote:

>> With patches:
>> -------------
>> tx_pkt_sz: 64  TX-pps: 9426724
>
> Impressive. 82599 seems fast. Didn't you report even higher number
> with other CPU's?

Yes, the Core i7 is even faster... but currently I'm not using it as a 
generator, its the router in my current setup.

Once I have finished my slides and last tests for LinuxCon.  I'll run some 
pktgen tests with the Core i7 and post the results.

Cheers,
   Jesper Brouer

--
-------------------------------------------------------------------
MSc. Master of Computer Science
Dept. of Computer Science, University of Copenhagen
Author of http://www.adsl-optimizer.dk
-------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH 00/14] pktgen update for net-next (2.6.32)
  2009-09-09  7:53       ` Jesper Dangaard Brouer
@ 2009-09-11 14:29         ` Jesper Dangaard Brouer
  0 siblings, 0 replies; 28+ messages in thread
From: Jesper Dangaard Brouer @ 2009-09-11 14:29 UTC (permalink / raw)
  To: robert
  Cc: Stephen Hemminger, David Miller, Robert Olsson, netdev,
	Thomas Gleixner

On Wed, 9 Sep 2009, Jesper Dangaard Brouer wrote:

> On Tue, 8 Sep 2009, robert@herjulf.net wrote:
>
>> >  With patches:
>> >  -------------
>> >  tx_pkt_sz: 64  TX-pps: 9426724
>>
>>  Impressive. 82599 seems fast. Didn't you report even higher number
>>  with other CPU's?
>
> Yes, the Core i7 is even faster... but currently I'm not using it as a 
> generator, its the router in my current setup.
>
> Once I have finished my slides and last tests for LinuxCon.  I'll run some 
> pktgen tests with the Core i7 and post the results.

Here are some quick test results:

One thing I noticed during the tests, is that using the machine during the 
tests gets very sluggy with the pktgen patches applied.

Another thing/bug that sometimes happens is that pktgen stops working and 
the ixgbe driver "says":

[  231.195624] pktgen 2.72: Packet Generator for packet performance testing.
[  233.065639] ixgbe 0000:07:00.1: master disable timed out
[  234.677107] ixgbe 0000:07:00.1: master disable timed out
[  236.284576] ixgbe 0000:07:00.1: master disable timed out
[  237.892045] ixgbe 0000:07:00.1: master disable timed out

The tests, I did complete, gave the following results:

Core i7-920 (with DDR3 at 1600Mhz)
----------------------------------
Without patches (2.6.31-rc2):

  tx_pkt_sz: 64   TX-Mbps: 5704.29    TX-pps: 11141193
  tx_pkt_sz: 128  TX-Mbps: 8415.27    TX-pps: 8218035
  tx_pkt_sz: 256  TX-Mbps: 9146.23    TX-pps: 4465932

With the pktgen patches (2.6.31-rc5):

  tx_pkt_sz: 64   TX-Mbps: 5763.64        TX-pps: 11257313
  tx_pkt_sz: 128  TX-Mbps: 8414.91        TX-pps: 8217709
  tx_pkt_sz: 256  TX-Mbps: 9141.70        TX-pps: 4463720


Cheers,
   Jesper Brouer

--
-------------------------------------------------------------------
MSc. Master of Computer Science
Dept. of Computer Science, University of Copenhagen
Author of http://www.adsl-optimizer.dk
-------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2009-09-11 14:29 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-27 23:55 [PATCH 00/14] pktgen update for net-next (2.6.32) Stephen Hemminger
2009-08-27 23:55 ` [PATCH 01/14] pktgen: minor cleanup Stephen Hemminger
2009-08-27 23:55 ` [PATCH 02/14] pktgen: change inlining Stephen Hemminger
2009-08-27 23:55 ` [PATCH 03/14] pktgen: mark read-only/mostly variables Stephen Hemminger
2009-08-27 23:55 ` [PATCH 04/14] pktgen: stop_device cleanup Stephen Hemminger
2009-08-27 23:55 ` [PATCH 05/14] pktgen: xmit logic reorganization Stephen Hemminger
2009-08-27 23:55 ` [PATCH 06/14] pktgen: cleanup clone count test Stephen Hemminger
2009-08-27 23:55 ` [PATCH 07/14] pktgen: use netdev_alloc_skb Stephen Hemminger
2009-08-27 23:55 ` [PATCH 08/14] pktgen: reorganize transmit loop Stephen Hemminger
2009-08-28  3:52   ` Ben Greear
2009-08-28  5:49     ` Stephen Hemminger
2009-08-28 16:01       ` Ben Greear
2009-08-29  6:04       ` David Miller
2009-09-01 21:30         ` Stephen Hemminger
2009-09-02 13:06           ` Patrick McHardy
2009-08-27 23:55 ` [PATCH 09/14] pktgen: avoid calling gettimeofday Stephen Hemminger
2009-08-27 23:55 ` [PATCH 10/14] pktgen: convert to use ktime_t Stephen Hemminger
2009-08-27 23:55 ` [PATCH 11/14] pktgen: spin using hrtimer Stephen Hemminger
2009-08-27 23:55 ` [PATCH 12/14] pktgen: use common idle routine Stephen Hemminger
2009-08-27 23:55 ` [PATCH 13/14] pktgen: cleanup checkpatch warnings Stephen Hemminger
2009-08-27 23:55 ` [PATCH 14/14] pktgen: increase version Stephen Hemminger
2009-08-29  6:33 ` [PATCH 00/14] pktgen update for net-next (2.6.32) David Miller
2009-08-29  6:42   ` David Miller
2009-09-08 11:52 ` robert
2009-09-08 12:21   ` Jesper Dangaard Brouer
2009-09-08 15:41     ` robert
2009-09-09  7:53       ` Jesper Dangaard Brouer
2009-09-11 14:29         ` Jesper Dangaard Brouer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).