All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH] net: add additional lock to qdisc to increase enqueue/dequeue fairness
@ 2010-03-23 20:25 Alexander Duyck
  2010-03-23 20:31 ` David Miller
                   ` (4 more replies)
  0 siblings, 5 replies; 26+ messages in thread
From: Alexander Duyck @ 2010-03-23 20:25 UTC (permalink / raw)
  To: netdev

The qdisc layer shows a significant issue when you start transmitting from
multiple CPUs.  The issue is that the transmit rate drops significantly, and I
believe it is due to the fact that the spinlock is shared between the 1
dequeue, and n-1 enqueue cpu threads.  In order to improve this situation I am
adding one additional lock which will need to be obtained during the enqueue
portion of the path.  This essentially allows sch_direct_xmit to jump to
near the head of the line when attempting to obtain the lock after
completing a transmit.

Running the script below I saw an increase from 200K packets per second to
1.07M packets per second as a result of this patch.

for j in `seq 0 15`; do
	for i in `seq 0 7`; do
		netperf -H <ip> -t UDP_STREAM -l 600 -N -T $i -- -m 6 &
	done
done

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
---

 include/net/sch_generic.h |    3 ++-
 net/core/dev.c            |    7 ++++++-
 net/sched/sch_generic.c   |    1 +
 3 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 67dc08e..f5088a9 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -51,7 +51,6 @@ struct Qdisc {
 	struct list_head	list;
 	u32			handle;
 	u32			parent;
-	atomic_t		refcnt;
 	struct gnet_stats_rate_est	rate_est;
 	int			(*reshape_fail)(struct sk_buff *skb,
 					struct Qdisc *q);
@@ -65,6 +64,8 @@ struct Qdisc {
 	struct netdev_queue	*dev_queue;
 	struct Qdisc		*next_sched;
 
+	atomic_t		refcnt;
+	spinlock_t		enqueue_lock;
 	struct sk_buff		*gso_skb;
 	/*
 	 * For performance sake on SMP, we put highly modified fields at the end
diff --git a/net/core/dev.c b/net/core/dev.c
index a03aab4..8a2d508 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2006,8 +2006,10 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
 	spinlock_t *root_lock = qdisc_lock(q);
 	int rc;
 
+	spin_lock(&q->enqueue_lock);
 	spin_lock(root_lock);
 	if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
+		spin_unlock(&q->enqueue_lock);
 		kfree_skb(skb);
 		rc = NET_XMIT_DROP;
 	} else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) &&
@@ -2018,7 +2020,9 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
 		 * xmit the skb directly.
 		 */
 		__qdisc_update_bstats(q, skb->len);
-		if (sch_direct_xmit(skb, q, dev, txq, root_lock))
+		spin_unlock(&q->enqueue_lock);
+		rc = sch_direct_xmit(skb, q, dev, txq, root_lock);
+		if (rc)
 			__qdisc_run(q);
 		else
 			clear_bit(__QDISC_STATE_RUNNING, &q->state);
@@ -2026,6 +2030,7 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
 		rc = NET_XMIT_SUCCESS;
 	} else {
 		rc = qdisc_enqueue_root(skb, q);
+		spin_unlock(&q->enqueue_lock);
 		qdisc_run(q);
 	}
 	spin_unlock(root_lock);
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 5173c1e..4b5e125 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -538,6 +538,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 	sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p);
 	sch->padded = (char *) sch - (char *) p;
 
+	spin_lock_init(&sch->enqueue_lock);
 	INIT_LIST_HEAD(&sch->list);
 	skb_queue_head_init(&sch->q);
 	sch->ops = ops;


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

end of thread, other threads:[~2010-06-02 14:52 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-03-23 20:25 [RFC PATCH] net: add additional lock to qdisc to increase enqueue/dequeue fairness Alexander Duyck
2010-03-23 20:31 ` David Miller
2010-03-24  2:12   ` Andi Kleen
2010-03-23 20:40 ` Rick Jones
2010-03-23 20:54 ` Eric Dumazet
2010-03-23 21:18   ` Eric Dumazet
2010-03-23 21:45   ` David Miller
2010-03-23 22:08     ` Duyck, Alexander H
2010-03-24  2:58       ` David Miller
2010-03-24  5:42         ` Eric Dumazet
2010-03-24  6:10           ` David Miller
2010-03-23 22:13     ` Eric Dumazet
2010-05-21 15:43       ` Stephen Hemminger
2010-05-21 16:44         ` Eric Dumazet
2010-05-21 17:38           ` Stephen Hemminger
2010-05-21 17:40           ` Eric Dumazet
2010-06-02  9:48             ` Eric Dumazet
2010-06-02  9:49             ` [PATCH 1/2 net-next-2.6] net: Define accessors to manipulate QDISC_STATE_RUNNING Eric Dumazet
2010-06-02 10:24               ` David Miller
2010-06-02  9:50             ` [PATCH 2/2 net-next-2.6] net: QDISC_STATE_RUNNING dont need atomic bit ops Eric Dumazet
2010-06-02 10:25               ` David Miller
2010-03-24 14:24 ` [RFC PATCH] net: add additional lock to qdisc to increase enqueue/dequeue fairness Eric Dumazet
2010-05-21 15:08 ` [PATCH] net: add additional lock to qdisc to increase throughput Eric Dumazet
2010-05-21 20:04   ` Duyck, Alexander H
2010-06-02 12:10     ` David Miller
2010-06-02 14:52       ` Eric Dumazet

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.