History

smp: Cleanup smp_call_function*()

Get rid of the __call_single_node union and cleanup the API a little to avoid external code relying on the structure layout as much.

Peter Zijlstra committed 6 years ago

Commit 545b8c81 parent 7a9f50a13 files · +60 −94Browse files

Unified · Split

13 files
  1. arch/mips/kernel/process.c +3 −2
  2. arch/mips/kernel/smp.c +6 −19
  3. arch/s390/pci/pci_irq.c +1 −3
  4. arch/x86/kernel/cpuid.c +3 −4
  5. arch/x86/lib/msr-smp.c +3 −4
  6. block/blk-mq.c +1 −3
  7. drivers/cpuidle/coupled.c +1 −2
  8. drivers/net/ethernet/cavium/liquidio/lio_core.c +2 −7
  9. include/linux/smp.h +9 −10
  10. kernel/debug/debug_core.c +3 −3
  11. kernel/sched/core.c +2 −10
  12. kernel/smp.c +25 −25
  13. net/core/dev.c +1 −2
arch/mips/kernel/process.c+3−2
@@ -702,7 +702,6 @@ unsigned long arch_align_stack(unsigned long sp) · 701 unmodified lines
702 return sp & ALMASK;702 return sp & ALMASK;
703}703}
704 704
705static DEFINE_PER_CPU(call_single_data_t, backtrace_csd);
706static struct cpumask backtrace_csd_busy;705static struct cpumask backtrace_csd_busy;
707 706
708static void handle_backtrace(void *info)707static void handle_backtrace(void *info)
@@ -711,6 +710,9 @@ static void handle_backtrace(void *info) · 2 unmodified lines
711 cpumask_clear_cpu(smp_processor_id(), &backtrace_csd_busy);710 cpumask_clear_cpu(smp_processor_id(), &backtrace_csd_busy);
712}711}
713 712
713static DEFINE_PER_CPU(call_single_data_t, backtrace_csd) =
714 CSD_INIT(handle_backtrace, NULL);
715
714static void raise_backtrace(cpumask_t *mask)716static void raise_backtrace(cpumask_t *mask)
715{717{
716 call_single_data_t *csd;718 call_single_data_t *csd;
@@ -730,7 +732,6 @@ static void raise_backtrace(cpumask_t *mask) · 13 unmodified lines
730 }732 }
731 733
732 csd = &per_cpu(backtrace_csd, cpu);734 csd = &per_cpu(backtrace_csd, cpu);
733 csd->func = handle_backtrace;
734 smp_call_function_single_async(cpu, csd);735 smp_call_function_single_async(cpu, csd);
735 }736 }
736}737}
arch/mips/kernel/smp.c+6−19
@@ -687,36 +687,23 @@ EXPORT_SYMBOL(flush_tlb_one); · 686 unmodified lines
687 687
688#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST688#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
689 689
690static DEFINE_PER_CPU(call_single_data_t, tick_broadcast_csd);
691
692void tick_broadcast(const struct cpumask *mask)
693{
694 call_single_data_t *csd;
695 int cpu;
696
697 for_each_cpu(cpu, mask) {
698 csd = &per_cpu(tick_broadcast_csd, cpu);
699 smp_call_function_single_async(cpu, csd);
700 }
701}
702
703static void tick_broadcast_callee(void *info)690static void tick_broadcast_callee(void *info)
704{691{
705 tick_receive_broadcast();692 tick_receive_broadcast();
706}693}
707 694
708static int __init tick_broadcast_init(void)695static DEFINE_PER_CPU(call_single_data_t, tick_broadcast_csd) =
696 CSD_INIT(tick_broadcast_callee, NULL);
697
698void tick_broadcast(const struct cpumask *mask)
709{699{
710 call_single_data_t *csd;700 call_single_data_t *csd;
711 int cpu;701 int cpu;
712 702
713 for (cpu = 0; cpu < NR_CPUS; cpu++) {703 for_each_cpu(cpu, mask) {
714 csd = &per_cpu(tick_broadcast_csd, cpu);704 csd = &per_cpu(tick_broadcast_csd, cpu);
715 csd->func = tick_broadcast_callee;705 smp_call_function_single_async(cpu, csd);
716 }706 }
717
718 return 0;
719}707}
720early_initcall(tick_broadcast_init);
721 708
722#endif /* CONFIG_GENERIC_CLOCKEVENTS_BROADCAST */709#endif /* CONFIG_GENERIC_CLOCKEVENTS_BROADCAST */
arch/s390/pci/pci_irq.c+1−3
@@ -178,9 +178,7 @@ static void zpci_handle_fallback_irq(void) · 177 unmodified lines
178 if (atomic_inc_return(&cpu_data->scheduled) > 1)178 if (atomic_inc_return(&cpu_data->scheduled) > 1)
179 continue;179 continue;
180 180
181 cpu_data->csd.func = zpci_handle_remote_irq;181 INIT_CSD(&cpu_data->csd, zpci_handle_remote_irq, &cpu_data->scheduled);
182 cpu_data->csd.info = &cpu_data->scheduled;
183 cpu_data->csd.flags = 0;
184 smp_call_function_single_async(cpu, &cpu_data->csd);182 smp_call_function_single_async(cpu, &cpu_data->csd);
185 }183 }
186}184}
arch/x86/kernel/cpuid.c+3−4
@@ -74,10 +74,9 @@ static ssize_t cpuid_read(struct file *file, char __user *buf, · 73 unmodified lines
74 74
75 init_completion(&cmd.done);75 init_completion(&cmd.done);
76 for (; count; count -= 16) {76 for (; count; count -= 16) {
77 call_single_data_t csd = {77 call_single_data_t csd;
78 .func = cpuid_smp_cpuid,78
79 .info = &cmd,79 INIT_CSD(&csd, cpuid_smp_cpuid, &cmd);
80 };
81 80
82 cmd.regs.eax = pos;81 cmd.regs.eax = pos;
83 cmd.regs.ecx = pos >> 32;82 cmd.regs.ecx = pos >> 32;
arch/x86/lib/msr-smp.c+3−4
@@ -169,12 +169,11 @@ static void __wrmsr_safe_on_cpu(void *info) · 168 unmodified lines
169int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)169int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
170{170{
171 struct msr_info_completion rv;171 struct msr_info_completion rv;
172 call_single_data_t csd = {172 call_single_data_t csd;
173 .func = __rdmsr_safe_on_cpu,
174 .info = &rv,
175 };
176 int err;173 int err;
177 174
175 INIT_CSD(&csd, __rdmsr_safe_on_cpu, &rv);
176
178 memset(&rv, 0, sizeof(rv));177 memset(&rv, 0, sizeof(rv));
179 init_completion(&rv.done);178 init_completion(&rv.done);
180 rv.msr.msr_no = msr_no;179 rv.msr.msr_no = msr_no;
block/blk-mq.c+1−3
@@ -671,9 +671,7 @@ bool blk_mq_complete_request_remote(struct request *rq) · 670 unmodified lines
671 return false;671 return false;
672 672
673 if (blk_mq_complete_need_ipi(rq)) {673 if (blk_mq_complete_need_ipi(rq)) {
674 rq->csd.func = __blk_mq_complete_request_remote;674 INIT_CSD(&rq->csd, __blk_mq_complete_request_remote, rq);
675 rq->csd.info = rq;
676 rq->csd.flags = 0;
677 smp_call_function_single_async(rq->mq_ctx->cpu, &rq->csd);675 smp_call_function_single_async(rq->mq_ctx->cpu, &rq->csd);
678 } else {676 } else {
679 if (rq->q->nr_hw_queues > 1)677 if (rq->q->nr_hw_queues > 1)
drivers/cpuidle/coupled.c+1−2
@@ -674,8 +674,7 @@ have_coupled: · 673 unmodified lines
674 coupled->refcnt++;674 coupled->refcnt++;
675 675
676 csd = &per_cpu(cpuidle_coupled_poke_cb, dev->cpu);676 csd = &per_cpu(cpuidle_coupled_poke_cb, dev->cpu);
677 csd->func = cpuidle_coupled_handle_poke;677 INIT_CSD(csd, cpuidle_coupled_handle_poke, (void *)(unsigned long)dev->cpu);
678 csd->info = (void *)(unsigned long)dev->cpu;
679 678
680 return 0;679 return 0;
681}680}
drivers/net/ethernet/cavium/liquidio/lio_core.c+2−7
@@ -729,13 +729,8 @@ static void liquidio_napi_drv_callback(void *arg) · 728 unmodified lines
729 droq->cpu_id == this_cpu) {729 droq->cpu_id == this_cpu) {
730 napi_schedule_irqoff(&droq->napi);730 napi_schedule_irqoff(&droq->napi);
731 } else {731 } else {
732 call_single_data_t *csd = &droq->csd;732 INIT_CSD(&droq->csd, napi_schedule_wrapper, &droq->napi);
733 733 smp_call_function_single_async(droq->cpu_id, &droq->csd);
734 csd->func = napi_schedule_wrapper;
735 csd->info = &droq->napi;
736 csd->flags = 0;
737
738 smp_call_function_single_async(droq->cpu_id, csd);
739 }734 }
740}735}
741 736
include/linux/smp.h+9−10
@@ -21,24 +21,23 @@ typedef bool (*smp_cond_func_t)(int cpu, void *info); · 20 unmodified lines
21 * structure shares (partial) layout with struct irq_work21 * structure shares (partial) layout with struct irq_work
22 */22 */
23struct __call_single_data {23struct __call_single_data {
24 union {24 struct __call_single_node node;
25 struct __call_single_node node;
26 struct {
27 struct llist_node llist;
28 unsigned int flags;
29#ifdef CONFIG_64BIT
30 u16 src, dst;
31#endif
32 };
33 };
34 smp_call_func_t func;25 smp_call_func_t func;
35 void *info;26 void *info;
36};27};
37 28
29#define CSD_INIT(_func, _info) \
30 (struct __call_single_data){ .func = (_func), .info = (_info), }
31
38/* Use __aligned() to avoid to use 2 cache lines for 1 csd */32/* Use __aligned() to avoid to use 2 cache lines for 1 csd */
39typedef struct __call_single_data call_single_data_t33typedef struct __call_single_data call_single_data_t
40 __aligned(sizeof(struct __call_single_data));34 __aligned(sizeof(struct __call_single_data));
41 35
36#define INIT_CSD(_csd, _func, _info) \
37do { \
38 *(_csd) = CSD_INIT((_func), (_info)); \
39} while (0)
40
42/*41/*
43 * Enqueue a llist_node on the call_single_queue; be very careful, read42 * Enqueue a llist_node on the call_single_queue; be very careful, read
44 * flush_smp_call_function_queue() in detail.43 * flush_smp_call_function_queue() in detail.
kernel/debug/debug_core.c+3−3
@@ -225,8 +225,6 @@ NOKPROBE_SYMBOL(kgdb_skipexception); · 224 unmodified lines
225 * Default (weak) implementation for kgdb_roundup_cpus225 * Default (weak) implementation for kgdb_roundup_cpus
226 */226 */
227 227
228static DEFINE_PER_CPU(call_single_data_t, kgdb_roundup_csd);
229
230void __weak kgdb_call_nmi_hook(void *ignored)228void __weak kgdb_call_nmi_hook(void *ignored)
231{229{
232 /*230 /*
@@ -241,6 +239,9 @@ void __weak kgdb_call_nmi_hook(void *ignored) · 8 unmodified lines
241}239}
242NOKPROBE_SYMBOL(kgdb_call_nmi_hook);240NOKPROBE_SYMBOL(kgdb_call_nmi_hook);
243 241
242static DEFINE_PER_CPU(call_single_data_t, kgdb_roundup_csd) =
243 CSD_INIT(kgdb_call_nmi_hook, NULL);
244
244void __weak kgdb_roundup_cpus(void)245void __weak kgdb_roundup_cpus(void)
245{246{
246 call_single_data_t *csd;247 call_single_data_t *csd;
@@ -267,7 +268,6 @@ void __weak kgdb_roundup_cpus(void) · 20 unmodified lines
267 continue;268 continue;
268 kgdb_info[cpu].rounding_up = true;269 kgdb_info[cpu].rounding_up = true;
269 270
270 csd->func = kgdb_call_nmi_hook;
271 ret = smp_call_function_single_async(cpu, csd);271 ret = smp_call_function_single_async(cpu, csd);
272 if (ret)272 if (ret)
273 kgdb_info[cpu].rounding_up = false;273 kgdb_info[cpu].rounding_up = false;
kernel/sched/core.c+2−10
@@ -320,14 +320,6 @@ void update_rq_clock(struct rq *rq) · 319 unmodified lines
320 update_rq_clock_task(rq, delta);320 update_rq_clock_task(rq, delta);
321}321}
322 322
323static inline void
324rq_csd_init(struct rq *rq, call_single_data_t *csd, smp_call_func_t func)
325{
326 csd->flags = 0;
327 csd->func = func;
328 csd->info = rq;
329}
330
331#ifdef CONFIG_SCHED_HRTICK323#ifdef CONFIG_SCHED_HRTICK
332/*324/*
333 * Use HR-timers to deliver accurate preemption points.325 * Use HR-timers to deliver accurate preemption points.
@@ -428,7 +420,7 @@ void hrtick_start(struct rq *rq, u64 delay) · 94 unmodified lines
428static void hrtick_rq_init(struct rq *rq)420static void hrtick_rq_init(struct rq *rq)
429{421{
430#ifdef CONFIG_SMP422#ifdef CONFIG_SMP
431 rq_csd_init(rq, &rq->hrtick_csd, __hrtick_start);423 INIT_CSD(&rq->hrtick_csd, __hrtick_start, rq);
432#endif424#endif
433 hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);425 hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);
434 rq->hrtick_timer.function = hrtick;426 rq->hrtick_timer.function = hrtick;
@@ -7774,7 +7766,7 @@ void __init sched_init(void) · 7339 unmodified lines
7774 rq->last_blocked_load_update_tick = jiffies;7766 rq->last_blocked_load_update_tick = jiffies;
7775 atomic_set(&rq->nohz_flags, 0);7767 atomic_set(&rq->nohz_flags, 0);
7776 7768
7777 rq_csd_init(rq, &rq->nohz_csd, nohz_csd_func);7769 INIT_CSD(&rq->nohz_csd, nohz_csd_func, rq);
7778#endif7770#endif
7779#ifdef CONFIG_HOTPLUG_CPU7771#ifdef CONFIG_HOTPLUG_CPU
7780 rcuwait_init(&rq->hotplug_wait);7772 rcuwait_init(&rq->hotplug_wait);
kernel/smp.c+25−25
@@ -27,7 +27,7 @@ · 26 unmodified lines
27#include "smpboot.h"27#include "smpboot.h"
28#include "sched/smp.h"28#include "sched/smp.h"
29 29
30#define CSD_TYPE(_csd) ((_csd)->flags & CSD_FLAG_TYPE_MASK)30#define CSD_TYPE(_csd) ((_csd)->node.u_flags & CSD_FLAG_TYPE_MASK)
31 31
32struct call_function_data {32struct call_function_data {
33 call_single_data_t __percpu *csd;33 call_single_data_t __percpu *csd;
@@ -146,7 +146,7 @@ static __always_inline bool csd_lock_wait_toolong(call_single_data_t *csd, u64 t · 112 unmodified lines
146 bool firsttime;146 bool firsttime;
147 u64 ts2, ts_delta;147 u64 ts2, ts_delta;
148 call_single_data_t *cpu_cur_csd;148 call_single_data_t *cpu_cur_csd;
149 unsigned int flags = READ_ONCE(csd->flags);149 unsigned int flags = READ_ONCE(csd->node.u_flags);
150 150
151 if (!(flags & CSD_FLAG_LOCK)) {151 if (!(flags & CSD_FLAG_LOCK)) {
152 if (!unlikely(*bug_id))152 if (!unlikely(*bug_id))
@@ -224,14 +224,14 @@ static void csd_lock_record(call_single_data_t *csd) · 71 unmodified lines
224 224
225static __always_inline void csd_lock_wait(call_single_data_t *csd)225static __always_inline void csd_lock_wait(call_single_data_t *csd)
226{226{
227 smp_cond_load_acquire(&csd->flags, !(VAL & CSD_FLAG_LOCK));227 smp_cond_load_acquire(&csd->node.u_flags, !(VAL & CSD_FLAG_LOCK));
228}228}
229#endif229#endif
230 230
231static __always_inline void csd_lock(call_single_data_t *csd)231static __always_inline void csd_lock(call_single_data_t *csd)
232{232{
233 csd_lock_wait(csd);233 csd_lock_wait(csd);
234 csd->flags |= CSD_FLAG_LOCK;234 csd->node.u_flags |= CSD_FLAG_LOCK;
235 235
236 /*236 /*
237 * prevent CPU from reordering the above assignment237 * prevent CPU from reordering the above assignment
@@ -243,12 +243,12 @@ static __always_inline void csd_lock(call_single_data_t *csd) · 5 unmodified lines
243 243
244static __always_inline void csd_unlock(call_single_data_t *csd)244static __always_inline void csd_unlock(call_single_data_t *csd)
245{245{
246 WARN_ON(!(csd->flags & CSD_FLAG_LOCK));246 WARN_ON(!(csd->node.u_flags & CSD_FLAG_LOCK));
247 247
248 /*248 /*
249 * ensure we're all done before releasing data:249 * ensure we're all done before releasing data:
250 */250 */
251 smp_store_release(&csd->flags, 0);251 smp_store_release(&csd->node.u_flags, 0);
252}252}
253 253
254static DEFINE_PER_CPU_SHARED_ALIGNED(call_single_data_t, csd_data);254static DEFINE_PER_CPU_SHARED_ALIGNED(call_single_data_t, csd_data);
@@ -300,7 +300,7 @@ static int generic_exec_single(int cpu, call_single_data_t *csd) · 45 unmodified lines
300 return -ENXIO;300 return -ENXIO;
301 }301 }
302 302
303 __smp_call_single_queue(cpu, &csd->llist);303 __smp_call_single_queue(cpu, &csd->node.llist);
304 304
305 return 0;305 return 0;
306}306}
@@ -353,7 +353,7 @@ static void flush_smp_call_function_queue(bool warn_cpu_offline) · 46 unmodified lines
353 * We don't have to use the _safe() variant here353 * We don't have to use the _safe() variant here
354 * because we are not invoking the IPI handlers yet.354 * because we are not invoking the IPI handlers yet.
355 */355 */
356 llist_for_each_entry(csd, entry, llist) {356 llist_for_each_entry(csd, entry, node.llist) {
357 switch (CSD_TYPE(csd)) {357 switch (CSD_TYPE(csd)) {
358 case CSD_TYPE_ASYNC:358 case CSD_TYPE_ASYNC:
359 case CSD_TYPE_SYNC:359 case CSD_TYPE_SYNC:
@@ -378,16 +378,16 @@ static void flush_smp_call_function_queue(bool warn_cpu_offline) · 18 unmodified lines
378 * First; run all SYNC callbacks, people are waiting for us.378 * First; run all SYNC callbacks, people are waiting for us.
379 */379 */
380 prev = NULL;380 prev = NULL;
381 llist_for_each_entry_safe(csd, csd_next, entry, llist) {381 llist_for_each_entry_safe(csd, csd_next, entry, node.llist) {
382 /* Do we wait until *after* callback? */382 /* Do we wait until *after* callback? */
383 if (CSD_TYPE(csd) == CSD_TYPE_SYNC) {383 if (CSD_TYPE(csd) == CSD_TYPE_SYNC) {
384 smp_call_func_t func = csd->func;384 smp_call_func_t func = csd->func;
385 void *info = csd->info;385 void *info = csd->info;
386 386
387 if (prev) {387 if (prev) {
388 prev->next = &csd_next->llist;388 prev->next = &csd_next->node.llist;
389 } else {389 } else {
390 entry = &csd_next->llist;390 entry = &csd_next->node.llist;
391 }391 }
392 392
393 csd_lock_record(csd);393 csd_lock_record(csd);
@@ -395,7 +395,7 @@ static void flush_smp_call_function_queue(bool warn_cpu_offline) · 1 unmodified line
395 csd_unlock(csd);395 csd_unlock(csd);
396 csd_lock_record(NULL);396 csd_lock_record(NULL);
397 } else {397 } else {
398 prev = &csd->llist;398 prev = &csd->node.llist;
399 }399 }
400 }400 }
401 401
@@ -406,14 +406,14 @@ static void flush_smp_call_function_queue(bool warn_cpu_offline) · 4 unmodified lines
406 * Second; run all !SYNC callbacks.406 * Second; run all !SYNC callbacks.
407 */407 */
408 prev = NULL;408 prev = NULL;
409 llist_for_each_entry_safe(csd, csd_next, entry, llist) {409 llist_for_each_entry_safe(csd, csd_next, entry, node.llist) {
410 int type = CSD_TYPE(csd);410 int type = CSD_TYPE(csd);
411 411
412 if (type != CSD_TYPE_TTWU) {412 if (type != CSD_TYPE_TTWU) {
413 if (prev) {413 if (prev) {
414 prev->next = &csd_next->llist;414 prev->next = &csd_next->node.llist;
415 } else {415 } else {
416 entry = &csd_next->llist;416 entry = &csd_next->node.llist;
417 }417 }
418 418
419 if (type == CSD_TYPE_ASYNC) {419 if (type == CSD_TYPE_ASYNC) {
@@ -429,7 +429,7 @@ static void flush_smp_call_function_queue(bool warn_cpu_offline) · 9 unmodified lines
429 }429 }
430 430
431 } else {431 } else {
432 prev = &csd->llist;432 prev = &csd->node.llist;
433 }433 }
434 }434 }
435 435
@@ -465,7 +465,7 @@ int smp_call_function_single(int cpu, smp_call_func_t func, void *info, · 29 unmodified lines
465{465{
466 call_single_data_t *csd;466 call_single_data_t *csd;
467 call_single_data_t csd_stack = {467 call_single_data_t csd_stack = {
468 .flags = CSD_FLAG_LOCK | CSD_TYPE_SYNC,468 .node = { .u_flags = CSD_FLAG_LOCK | CSD_TYPE_SYNC, },
469 };469 };
470 int this_cpu;470 int this_cpu;
471 int err;471 int err;
@@ -502,8 +502,8 @@ int smp_call_function_single(int cpu, smp_call_func_t func, void *info, · 30 unmodified lines
502 csd->func = func;502 csd->func = func;
503 csd->info = info;503 csd->info = info;
504#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG504#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG
505 csd->src = smp_processor_id();505 csd->node.src = smp_processor_id();
506 csd->dst = cpu;506 csd->node.dst = cpu;
507#endif507#endif
508 508
509 err = generic_exec_single(cpu, csd);509 err = generic_exec_single(cpu, csd);
@@ -544,12 +544,12 @@ int smp_call_function_single_async(int cpu, call_single_data_t *csd) · 34 unmodified lines
544 544
545 preempt_disable();545 preempt_disable();
546 546
547 if (csd->flags & CSD_FLAG_LOCK) {547 if (csd->node.u_flags & CSD_FLAG_LOCK) {
548 err = -EBUSY;548 err = -EBUSY;
549 goto out;549 goto out;
550 }550 }
551 551
552 csd->flags = CSD_FLAG_LOCK;552 csd->node.u_flags = CSD_FLAG_LOCK;
553 smp_wmb();553 smp_wmb();
554 554
555 err = generic_exec_single(cpu, csd);555 err = generic_exec_single(cpu, csd);
@@ -667,14 +667,14 @@ static void smp_call_function_many_cond(const struct cpumask *mask, · 111 unmodified lines
667 667
668 csd_lock(csd);668 csd_lock(csd);
669 if (wait)669 if (wait)
670 csd->flags |= CSD_TYPE_SYNC;670 csd->node.u_flags |= CSD_TYPE_SYNC;
671 csd->func = func;671 csd->func = func;
672 csd->info = info;672 csd->info = info;
673#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG673#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG
674 csd->src = smp_processor_id();674 csd->node.src = smp_processor_id();
675 csd->dst = cpu;675 csd->node.dst = cpu;
676#endif676#endif
677 if (llist_add(&csd->llist, &per_cpu(call_single_queue, cpu)))677 if (llist_add(&csd->node.llist, &per_cpu(call_single_queue, cpu)))
678 __cpumask_set_cpu(cpu, cfd->cpumask_ipi);678 __cpumask_set_cpu(cpu, cfd->cpumask_ipi);
679 }679 }
680 680
net/core/dev.c+1−2
@@ -11165,8 +11165,7 @@ static int __init net_dev_init(void) · 11164 unmodified lines
11165 INIT_LIST_HEAD(&sd->poll_list);11165 INIT_LIST_HEAD(&sd->poll_list);
11166 sd->output_queue_tailp = &sd->output_queue;11166 sd->output_queue_tailp = &sd->output_queue;
11167#ifdef CONFIG_RPS11167#ifdef CONFIG_RPS
11168 sd->csd.func = rps_trigger_softirq;11168 INIT_CSD(&sd->csd, rps_trigger_softirq, sd);
11169 sd->csd.info = sd;
11170 sd->cpu = i;11169 sd->cpu = i;
11171#endif11170#endif
11172 11171

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t