aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-05-07 01:07:48 -0400
committerDavid S. Miller <davem@davemloft.net>2010-05-07 01:07:48 -0400
commiteecfd7c4e36ff532d895885971d01d049bd3e014 (patch)
treef75ee9904f29f9fd8d5a019766e41d3c07066903
parent39e0786d3cf39c6d2f47b4818ae2da8b8ebc9ce2 (diff)
rps: Various optimizations
Introduce ____napi_schedule() helper for callers in irq disabled contexts. rps_trigger_softirq() becomes a leaf function. Use container_of() in process_backlog() instead of accessing per_cpu address. Use a custom inlined version of __napi_complete() in process_backlog() to avoid one locked instruction : only current cpu owns and manipulates this napi, and NAPI_STATE_SCHED is the only possible flag set on backlog. we can use a plain write instead of clear_bit(), and we dont need an smp_mb() memory barrier, since RPS is on, backlog is protected by a spinlock. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/core/dev.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 36d53be4fca6..32611c8f1219 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2205,6 +2205,14 @@ int netdev_max_backlog __read_mostly = 1000;
2205int netdev_budget __read_mostly = 300; 2205int netdev_budget __read_mostly = 300;
2206int weight_p __read_mostly = 64; /* old backlog weight */ 2206int weight_p __read_mostly = 64; /* old backlog weight */
2207 2207
2208/* Called with irq disabled */
2209static inline void ____napi_schedule(struct softnet_data *sd,
2210 struct napi_struct *napi)
2211{
2212 list_add_tail(&napi->poll_list, &sd->poll_list);
2213 __raise_softirq_irqoff(NET_RX_SOFTIRQ);
2214}
2215
2208#ifdef CONFIG_RPS 2216#ifdef CONFIG_RPS
2209 2217
2210/* One global table that all flow-based protocols share. */ 2218/* One global table that all flow-based protocols share. */
@@ -2363,7 +2371,7 @@ static void rps_trigger_softirq(void *data)
2363{ 2371{
2364 struct softnet_data *sd = data; 2372 struct softnet_data *sd = data;
2365 2373
2366 __napi_schedule(&sd->backlog); 2374 ____napi_schedule(sd, &sd->backlog);
2367 sd->received_rps++; 2375 sd->received_rps++;
2368} 2376}
2369 2377
@@ -2421,7 +2429,7 @@ enqueue:
2421 /* Schedule NAPI for backlog device */ 2429 /* Schedule NAPI for backlog device */
2422 if (napi_schedule_prep(&sd->backlog)) { 2430 if (napi_schedule_prep(&sd->backlog)) {
2423 if (!rps_ipi_queued(sd)) 2431 if (!rps_ipi_queued(sd))
2424 __napi_schedule(&sd->backlog); 2432 ____napi_schedule(sd, &sd->backlog);
2425 } 2433 }
2426 goto enqueue; 2434 goto enqueue;
2427 } 2435 }
@@ -3280,7 +3288,7 @@ static void net_rps_action_and_irq_enable(struct softnet_data *sd)
3280static int process_backlog(struct napi_struct *napi, int quota) 3288static int process_backlog(struct napi_struct *napi, int quota)
3281{ 3289{
3282 int work = 0; 3290 int work = 0;
3283 struct softnet_data *sd = &__get_cpu_var(softnet_data); 3291 struct softnet_data *sd = container_of(napi, struct softnet_data, backlog);
3284 3292
3285#ifdef CONFIG_RPS 3293#ifdef CONFIG_RPS
3286 /* Check if we have pending ipi, its better to send them now, 3294 /* Check if we have pending ipi, its better to send them now,
@@ -3313,7 +3321,16 @@ static int process_backlog(struct napi_struct *napi, int quota)
3313 &sd->process_queue); 3321 &sd->process_queue);
3314 } 3322 }
3315 if (qlen < quota - work) { 3323 if (qlen < quota - work) {
3316 __napi_complete(napi); 3324 /*
3325 * Inline a custom version of __napi_complete().
3326 * only current cpu owns and manipulates this napi,
3327 * and NAPI_STATE_SCHED is the only possible flag set on backlog.
3328 * we can use a plain write instead of clear_bit(),
3329 * and we dont need an smp_mb() memory barrier.
3330 */
3331 list_del(&napi->poll_list);
3332 napi->state = 0;
3333
3317 quota = work + qlen; 3334 quota = work + qlen;
3318 } 3335 }
3319 rps_unlock(sd); 3336 rps_unlock(sd);
@@ -3334,8 +3351,7 @@ void __napi_schedule(struct napi_struct *n)
3334 unsigned long flags; 3351 unsigned long flags;
3335 3352
3336 local_irq_save(flags); 3353 local_irq_save(flags);
3337 list_add_tail(&n->poll_list, &__get_cpu_var(softnet_data).poll_list); 3354 ____napi_schedule(&__get_cpu_var(softnet_data), n);
3338 __raise_softirq_irqoff(NET_RX_SOFTIRQ);
3339 local_irq_restore(flags); 3355 local_irq_restore(flags);
3340} 3356}
3341EXPORT_SYMBOL(__napi_schedule); 3357EXPORT_SYMBOL(__napi_schedule);