From: Eric Dumazet <eric.dumazet@gmail.com>
To: Changli Gao <xiaosuo@gmail.com>,
David Miller <davem@davemloft.net>,
Tom Herbert <therbert@google.com>
Cc: netdev <netdev@vger.kernel.org>
Subject: [PATCH net-next-2.6] rps: shortcut net_rps_action()
Date: Mon, 19 Apr 2010 17:07:33 +0200 [thread overview]
Message-ID: <1271689653.3845.73.camel@edumazet-laptop> (raw)
In-Reply-To: <1271686957.3845.49.camel@edumazet-laptop>
Le lundi 19 avril 2010 à 16:22 +0200, Eric Dumazet a écrit :
>
> Hmm, I just read again, and I now remember Tom used a single bitmap,
> then we had to add a second set because of a possible race.
>
> A list would be enough.
>
Here is the updated patch, using a single list instead of bitmap
RFC status becomes official patch ;)
Thanks Changli for your array suggestion !
[PATCH net-next-2.6] rps: shortcut net_rps_action()
net_rps_action() is a bit expensive on NR_CPUS=64..4096 kernels, even if
RPS is not active.
Tom Herbert used two bitmasks to hold information needed to send IPI,
but a single LIFO list seems more appropriate.
Move all RPS logic into net_rps_action() to cleanup net_rx_action() code
(remove two ifdefs)
Move rps_remote_softirq_cpus into softnet_data to share its first cache
line, filling an existing hole.
In a future patch, we could call net_rps_action() from process_backlog()
to make sure we send IPI before handling this cpu backlog.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
include/linux/netdevice.h | 9 ++--
net/core/dev.c | 79 ++++++++++++++----------------------
2 files changed, 38 insertions(+), 50 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 649a025..83ab3da 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1381,17 +1381,20 @@ static inline int unregister_gifconf(unsigned int family)
}
/*
- * Incoming packets are placed on per-cpu queues so that
- * no locking is needed.
+ * Incoming packets are placed on per-cpu queues
*/
struct softnet_data {
struct Qdisc *output_queue;
struct list_head poll_list;
struct sk_buff *completion_queue;
- /* Elements below can be accessed between CPUs for RPS */
#ifdef CONFIG_RPS
+ struct softnet_data *rps_ipi_list;
+
+ /* Elements below can be accessed between CPUs for RPS */
struct call_single_data csd ____cacheline_aligned_in_smp;
+ struct softnet_data *rps_ipi_next;
+ unsigned int cpu;
unsigned int input_queue_head;
#endif
struct sk_buff_head input_pkt_queue;
diff --git a/net/core/dev.c b/net/core/dev.c
index 7abf959..f6ff2cf 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2346,21 +2346,6 @@ done:
return cpu;
}
-/*
- * This structure holds the per-CPU mask of CPUs for which IPIs are scheduled
- * to be sent to kick remote softirq processing. There are two masks since
- * the sending of IPIs must be done with interrupts enabled. The select field
- * indicates the current mask that enqueue_backlog uses to schedule IPIs.
- * select is flipped before net_rps_action is called while still under lock,
- * net_rps_action then uses the non-selected mask to send the IPIs and clears
- * it without conflicting with enqueue_backlog operation.
- */
-struct rps_remote_softirq_cpus {
- cpumask_t mask[2];
- int select;
-};
-static DEFINE_PER_CPU(struct rps_remote_softirq_cpus, rps_remote_softirq_cpus);
-
/* Called from hardirq (IPI) context */
static void trigger_softirq(void *data)
{
@@ -2403,10 +2388,12 @@ enqueue:
if (napi_schedule_prep(&queue->backlog)) {
#ifdef CONFIG_RPS
if (cpu != smp_processor_id()) {
- struct rps_remote_softirq_cpus *rcpus =
- &__get_cpu_var(rps_remote_softirq_cpus);
+ struct softnet_data *myqueue;
+
+ myqueue = &__get_cpu_var(softnet_data);
+ queue->rps_ipi_next = myqueue->rps_ipi_list;
+ myqueue->rps_ipi_list = queue;
- cpu_set(cpu, rcpus->mask[rcpus->select]);
__raise_softirq_irqoff(NET_RX_SOFTIRQ);
goto enqueue;
}
@@ -2911,7 +2898,9 @@ int netif_receive_skb(struct sk_buff *skb)
}
EXPORT_SYMBOL(netif_receive_skb);
-/* Network device is going away, flush any packets still pending */
+/* Network device is going away, flush any packets still pending
+ * Called with irqs disabled.
+ */
static void flush_backlog(void *arg)
{
struct net_device *dev = arg;
@@ -3340,24 +3329,33 @@ void netif_napi_del(struct napi_struct *napi)
}
EXPORT_SYMBOL(netif_napi_del);
-#ifdef CONFIG_RPS
/*
- * net_rps_action sends any pending IPI's for rps. This is only called from
- * softirq and interrupts must be enabled.
+ * net_rps_action sends any pending IPI's for rps.
+ * Note: called with local irq disabled, but exits with local irq enabled.
*/
-static void net_rps_action(cpumask_t *mask)
+static void net_rps_action(void)
{
- int cpu;
+#ifdef CONFIG_RPS
+ struct softnet_data *locqueue = &__get_cpu_var(softnet_data);
+ struct softnet_data *remqueue = locqueue->rps_ipi_list;
- /* Send pending IPI's to kick RPS processing on remote cpus. */
- for_each_cpu_mask_nr(cpu, *mask) {
- struct softnet_data *queue = &per_cpu(softnet_data, cpu);
- if (cpu_online(cpu))
- __smp_call_function_single(cpu, &queue->csd, 0);
- }
- cpus_clear(*mask);
-}
+ if (remqueue) {
+ locqueue->rps_ipi_list = NULL;
+
+ local_irq_enable();
+
+ /* Send pending IPI's to kick RPS processing on remote cpus. */
+ while (remqueue) {
+ struct softnet_data *next = remqueue->rps_ipi_next;
+ if (cpu_online(remqueue->cpu))
+ __smp_call_function_single(remqueue->cpu,
+ &remqueue->csd, 0);
+ remqueue = next;
+ }
+ } else
#endif
+ local_irq_enable();
+}
static void net_rx_action(struct softirq_action *h)
{
@@ -3365,10 +3363,6 @@ static void net_rx_action(struct softirq_action *h)
unsigned long time_limit = jiffies + 2;
int budget = netdev_budget;
void *have;
-#ifdef CONFIG_RPS
- int select;
- struct rps_remote_softirq_cpus *rcpus;
-#endif
local_irq_disable();
@@ -3431,17 +3425,7 @@ static void net_rx_action(struct softirq_action *h)
netpoll_poll_unlock(have);
}
out:
-#ifdef CONFIG_RPS
- rcpus = &__get_cpu_var(rps_remote_softirq_cpus);
- select = rcpus->select;
- rcpus->select ^= 1;
-
- local_irq_enable();
-
- net_rps_action(&rcpus->mask[select]);
-#else
- local_irq_enable();
-#endif
+ net_rps_action();
#ifdef CONFIG_NET_DMA
/*
@@ -5841,6 +5825,7 @@ static int __init net_dev_init(void)
queue->csd.func = trigger_softirq;
queue->csd.info = queue;
queue->csd.flags = 0;
+ queue->cpu = i;
#endif
queue->backlog.poll = process_backlog;
next prev parent reply other threads:[~2010-04-19 15:07 UTC|newest]
Thread overview: 86+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-07 18:42 rps: question jamal
2010-02-08 5:58 ` Tom Herbert
2010-02-08 15:09 ` jamal
2010-04-14 11:53 ` rps perfomance WAS(Re: " jamal
2010-04-14 17:31 ` Tom Herbert
2010-04-14 18:04 ` Eric Dumazet
2010-04-14 18:53 ` jamal
2010-04-14 19:44 ` Stephen Hemminger
2010-04-14 19:58 ` Eric Dumazet
2010-04-15 8:51 ` David Miller
2010-04-14 20:22 ` jamal
2010-04-14 20:27 ` Eric Dumazet
2010-04-14 20:38 ` jamal
2010-04-14 20:45 ` Tom Herbert
2010-04-14 20:57 ` Eric Dumazet
2010-04-14 22:51 ` Changli Gao
2010-04-14 23:02 ` Stephen Hemminger
2010-04-15 2:40 ` Eric Dumazet
2010-04-15 2:50 ` Changli Gao
2010-04-15 8:57 ` David Miller
2010-04-15 12:10 ` jamal
2010-04-15 12:32 ` Changli Gao
2010-04-15 12:50 ` jamal
2010-04-15 23:51 ` Changli Gao
2010-04-15 8:51 ` David Miller
2010-04-14 20:34 ` Andi Kleen
2010-04-15 8:50 ` David Miller
2010-04-15 8:48 ` David Miller
2010-04-15 11:55 ` jamal
2010-04-15 16:41 ` Rick Jones
2010-04-15 20:16 ` jamal
2010-04-15 20:25 ` Rick Jones
2010-04-15 23:56 ` Changli Gao
2010-04-16 5:18 ` Eric Dumazet
2010-04-16 6:02 ` Changli Gao
2010-04-16 6:28 ` Tom Herbert
2010-04-16 6:32 ` Eric Dumazet
2010-04-16 13:42 ` jamal
2010-04-16 7:15 ` Andi Kleen
2010-04-16 13:27 ` jamal
2010-04-16 13:37 ` Andi Kleen
2010-04-16 13:58 ` jamal
2010-04-16 13:21 ` jamal
2010-04-16 13:34 ` Changli Gao
2010-04-16 13:49 ` jamal
2010-04-16 14:10 ` Changli Gao
2010-04-16 14:43 ` jamal
2010-04-16 14:58 ` Changli Gao
2010-04-19 12:48 ` jamal
2010-04-17 7:35 ` Eric Dumazet
2010-04-17 8:43 ` Tom Herbert
2010-04-17 9:23 ` Eric Dumazet
2010-04-17 14:27 ` Eric Dumazet
2010-04-17 17:26 ` Tom Herbert
2010-04-17 14:17 ` [PATCH net-next-2.6] net: remove time limit in process_backlog() Eric Dumazet
2010-04-18 9:36 ` David Miller
2010-04-17 17:31 ` rps perfomance WAS(Re: rps: question jamal
2010-04-18 9:39 ` Eric Dumazet
2010-04-18 11:34 ` Eric Dumazet
2010-04-19 2:09 ` jamal
2010-04-19 9:37 ` [RFC] rps: shortcut net_rps_action() Eric Dumazet
2010-04-19 9:48 ` Changli Gao
2010-04-19 12:14 ` Eric Dumazet
2010-04-19 12:28 ` Changli Gao
2010-04-19 13:27 ` Eric Dumazet
2010-04-19 14:22 ` Eric Dumazet
2010-04-19 15:07 ` Eric Dumazet [this message]
2010-04-19 16:02 ` [PATCH net-next-2.6] " Tom Herbert
2010-04-19 20:21 ` David Miller
2010-04-20 7:17 ` [PATCH net-next-2.6] rps: cleanups Eric Dumazet
2010-04-20 8:18 ` David Miller
2010-04-19 23:56 ` [PATCH net-next-2.6] rps: shortcut net_rps_action() Changli Gao
2010-04-20 0:32 ` Changli Gao
2010-04-20 5:55 ` Eric Dumazet
2010-04-20 12:02 ` rps perfomance WAS(Re: rps: question jamal
2010-04-20 13:13 ` Eric Dumazet
[not found] ` <1271853570.4032.21.camel@bigi>
2010-04-21 19:01 ` Eric Dumazet
2010-04-22 1:27 ` Changli Gao
2010-04-22 12:12 ` jamal
2010-04-25 2:31 ` Changli Gao
2010-04-26 11:35 ` jamal
2010-04-26 13:35 ` Changli Gao
2010-04-21 21:53 ` Rick Jones
2010-04-16 15:57 ` Tom Herbert
2010-04-14 18:53 ` Stephen Hemminger
2010-04-15 8:42 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1271689653.3845.73.camel@edumazet-laptop \
--to=eric.dumazet@gmail.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=therbert@google.com \
--cc=xiaosuo@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox