Skip to content

Commit

Permalink
smp: Cleanup smp_call_function*()
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Frederic Weisbecker <[email protected]>
  • Loading branch information
Peter Zijlstra committed Nov 24, 2020
1 parent 7a9f50a commit 545b8c8
Show file tree
Hide file tree
Showing 13 changed files with 60 additions and 94 deletions.
5 changes: 3 additions & 2 deletions arch/mips/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,6 @@ unsigned long arch_align_stack(unsigned long sp)
return sp & ALMASK;
}

static DEFINE_PER_CPU(call_single_data_t, backtrace_csd);
static struct cpumask backtrace_csd_busy;

static void handle_backtrace(void *info)
Expand All @@ -711,6 +710,9 @@ static void handle_backtrace(void *info)
cpumask_clear_cpu(smp_processor_id(), &backtrace_csd_busy);
}

static DEFINE_PER_CPU(call_single_data_t, backtrace_csd) =
CSD_INIT(handle_backtrace, NULL);

static void raise_backtrace(cpumask_t *mask)
{
call_single_data_t *csd;
Expand All @@ -730,7 +732,6 @@ static void raise_backtrace(cpumask_t *mask)
}

csd = &per_cpu(backtrace_csd, cpu);
csd->func = handle_backtrace;
smp_call_function_single_async(cpu, csd);
}
}
Expand Down
25 changes: 6 additions & 19 deletions arch/mips/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,36 +687,23 @@ EXPORT_SYMBOL(flush_tlb_one);

#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST

static DEFINE_PER_CPU(call_single_data_t, tick_broadcast_csd);

void tick_broadcast(const struct cpumask *mask)
{
call_single_data_t *csd;
int cpu;

for_each_cpu(cpu, mask) {
csd = &per_cpu(tick_broadcast_csd, cpu);
smp_call_function_single_async(cpu, csd);
}
}

static void tick_broadcast_callee(void *info)
{
tick_receive_broadcast();
}

static int __init tick_broadcast_init(void)
static DEFINE_PER_CPU(call_single_data_t, tick_broadcast_csd) =
CSD_INIT(tick_broadcast_callee, NULL);

void tick_broadcast(const struct cpumask *mask)
{
call_single_data_t *csd;
int cpu;

for (cpu = 0; cpu < NR_CPUS; cpu++) {
for_each_cpu(cpu, mask) {
csd = &per_cpu(tick_broadcast_csd, cpu);
csd->func = tick_broadcast_callee;
smp_call_function_single_async(cpu, csd);
}

return 0;
}
early_initcall(tick_broadcast_init);

#endif /* CONFIG_GENERIC_CLOCKEVENTS_BROADCAST */
4 changes: 1 addition & 3 deletions arch/s390/pci/pci_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,7 @@ static void zpci_handle_fallback_irq(void)
if (atomic_inc_return(&cpu_data->scheduled) > 1)
continue;

cpu_data->csd.func = zpci_handle_remote_irq;
cpu_data->csd.info = &cpu_data->scheduled;
cpu_data->csd.flags = 0;
INIT_CSD(&cpu_data->csd, zpci_handle_remote_irq, &cpu_data->scheduled);
smp_call_function_single_async(cpu, &cpu_data->csd);
}
}
Expand Down
7 changes: 3 additions & 4 deletions arch/x86/kernel/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,9 @@ static ssize_t cpuid_read(struct file *file, char __user *buf,

init_completion(&cmd.done);
for (; count; count -= 16) {
call_single_data_t csd = {
.func = cpuid_smp_cpuid,
.info = &cmd,
};
call_single_data_t csd;

INIT_CSD(&csd, cpuid_smp_cpuid, &cmd);

cmd.regs.eax = pos;
cmd.regs.ecx = pos >> 32;
Expand Down
7 changes: 3 additions & 4 deletions arch/x86/lib/msr-smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,11 @@ static void __wrmsr_safe_on_cpu(void *info)
int rdmsr_safe_on_cpu(unsigned int cpu, u32 msr_no, u32 *l, u32 *h)
{
struct msr_info_completion rv;
call_single_data_t csd = {
.func = __rdmsr_safe_on_cpu,
.info = &rv,
};
call_single_data_t csd;
int err;

INIT_CSD(&csd, __rdmsr_safe_on_cpu, &rv);

memset(&rv, 0, sizeof(rv));
init_completion(&rv.done);
rv.msr.msr_no = msr_no;
Expand Down
4 changes: 1 addition & 3 deletions block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,9 +671,7 @@ bool blk_mq_complete_request_remote(struct request *rq)
return false;

if (blk_mq_complete_need_ipi(rq)) {
rq->csd.func = __blk_mq_complete_request_remote;
rq->csd.info = rq;
rq->csd.flags = 0;
INIT_CSD(&rq->csd, __blk_mq_complete_request_remote, rq);
smp_call_function_single_async(rq->mq_ctx->cpu, &rq->csd);
} else {
if (rq->q->nr_hw_queues > 1)
Expand Down
3 changes: 1 addition & 2 deletions drivers/cpuidle/coupled.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,8 +674,7 @@ int cpuidle_coupled_register_device(struct cpuidle_device *dev)
coupled->refcnt++;

csd = &per_cpu(cpuidle_coupled_poke_cb, dev->cpu);
csd->func = cpuidle_coupled_handle_poke;
csd->info = (void *)(unsigned long)dev->cpu;
INIT_CSD(csd, cpuidle_coupled_handle_poke, (void *)(unsigned long)dev->cpu);

return 0;
}
Expand Down
9 changes: 2 additions & 7 deletions drivers/net/ethernet/cavium/liquidio/lio_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,13 +729,8 @@ static void liquidio_napi_drv_callback(void *arg)
droq->cpu_id == this_cpu) {
napi_schedule_irqoff(&droq->napi);
} else {
call_single_data_t *csd = &droq->csd;

csd->func = napi_schedule_wrapper;
csd->info = &droq->napi;
csd->flags = 0;

smp_call_function_single_async(droq->cpu_id, csd);
INIT_CSD(&droq->csd, napi_schedule_wrapper, &droq->napi);
smp_call_function_single_async(droq->cpu_id, &droq->csd);
}
}

Expand Down
19 changes: 9 additions & 10 deletions include/linux/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,23 @@ typedef bool (*smp_cond_func_t)(int cpu, void *info);
* structure shares (partial) layout with struct irq_work
*/
struct __call_single_data {
union {
struct __call_single_node node;
struct {
struct llist_node llist;
unsigned int flags;
#ifdef CONFIG_64BIT
u16 src, dst;
#endif
};
};
struct __call_single_node node;
smp_call_func_t func;
void *info;
};

#define CSD_INIT(_func, _info) \
(struct __call_single_data){ .func = (_func), .info = (_info), }

/* Use __aligned() to avoid to use 2 cache lines for 1 csd */
typedef struct __call_single_data call_single_data_t
__aligned(sizeof(struct __call_single_data));

#define INIT_CSD(_csd, _func, _info) \
do { \
*(_csd) = CSD_INIT((_func), (_info)); \
} while (0)

/*
* Enqueue a llist_node on the call_single_queue; be very careful, read
* flush_smp_call_function_queue() in detail.
Expand Down
6 changes: 3 additions & 3 deletions kernel/debug/debug_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,6 @@ NOKPROBE_SYMBOL(kgdb_skipexception);
* Default (weak) implementation for kgdb_roundup_cpus
*/

static DEFINE_PER_CPU(call_single_data_t, kgdb_roundup_csd);

void __weak kgdb_call_nmi_hook(void *ignored)
{
/*
Expand All @@ -241,6 +239,9 @@ void __weak kgdb_call_nmi_hook(void *ignored)
}
NOKPROBE_SYMBOL(kgdb_call_nmi_hook);

static DEFINE_PER_CPU(call_single_data_t, kgdb_roundup_csd) =
CSD_INIT(kgdb_call_nmi_hook, NULL);

void __weak kgdb_roundup_cpus(void)
{
call_single_data_t *csd;
Expand All @@ -267,7 +268,6 @@ void __weak kgdb_roundup_cpus(void)
continue;
kgdb_info[cpu].rounding_up = true;

csd->func = kgdb_call_nmi_hook;
ret = smp_call_function_single_async(cpu, csd);
if (ret)
kgdb_info[cpu].rounding_up = false;
Expand Down
12 changes: 2 additions & 10 deletions kernel/sched/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,14 +320,6 @@ void update_rq_clock(struct rq *rq)
update_rq_clock_task(rq, delta);
}

static inline void
rq_csd_init(struct rq *rq, call_single_data_t *csd, smp_call_func_t func)
{
csd->flags = 0;
csd->func = func;
csd->info = rq;
}

#ifdef CONFIG_SCHED_HRTICK
/*
* Use HR-timers to deliver accurate preemption points.
Expand Down Expand Up @@ -428,7 +420,7 @@ void hrtick_start(struct rq *rq, u64 delay)
static void hrtick_rq_init(struct rq *rq)
{
#ifdef CONFIG_SMP
rq_csd_init(rq, &rq->hrtick_csd, __hrtick_start);
INIT_CSD(&rq->hrtick_csd, __hrtick_start, rq);
#endif
hrtimer_init(&rq->hrtick_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD);
rq->hrtick_timer.function = hrtick;
Expand Down Expand Up @@ -7774,7 +7766,7 @@ void __init sched_init(void)
rq->last_blocked_load_update_tick = jiffies;
atomic_set(&rq->nohz_flags, 0);

rq_csd_init(rq, &rq->nohz_csd, nohz_csd_func);
INIT_CSD(&rq->nohz_csd, nohz_csd_func, rq);
#endif
#ifdef CONFIG_HOTPLUG_CPU
rcuwait_init(&rq->hotplug_wait);
Expand Down
Loading

0 comments on commit 545b8c8

Please sign in to comment.