Skip to content

Commit 1139aeb

Browse files
arndbPeter Zijlstra
authored andcommitted
smp: Fix smp_call_function_single_async prototype
As of commit 966a967 ("smp: Avoid using two cache lines for struct call_single_data"), the smp code prefers 32-byte aligned call_single_data objects for performance reasons, but the block layer includes an instance of this structure in the main 'struct request' that is more senstive to size than to performance here, see 4ccafe0 ("block: unalign call_single_data in struct request"). The result is a violation of the calling conventions that clang correctly points out: block/blk-mq.c:630:39: warning: passing 8-byte aligned argument to 32-byte aligned parameter 2 of 'smp_call_function_single_async' may result in an unaligned pointer access [-Walign-mismatch] smp_call_function_single_async(cpu, &rq->csd); It does seem that the usage of the call_single_data without cache line alignment should still be allowed by the smp code, so just change the function prototype so it accepts both, but leave the default alignment unchanged for the other users. This seems better to me than adding a local hack to shut up an otherwise correct warning in the caller. Signed-off-by: Arnd Bergmann <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Acked-by: Jens Axboe <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 635de95 commit 1139aeb

File tree

3 files changed

+15
-15
lines changed

3 files changed

+15
-15
lines changed

include/linux/smp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ int smp_call_function_single(int cpuid, smp_call_func_t func, void *info,
5353
void on_each_cpu_cond_mask(smp_cond_func_t cond_func, smp_call_func_t func,
5454
void *info, bool wait, const struct cpumask *mask);
5555

56-
int smp_call_function_single_async(int cpu, call_single_data_t *csd);
56+
int smp_call_function_single_async(int cpu, struct __call_single_data *csd);
5757

5858
/*
5959
* Call a function on all processors

kernel/smp.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ static u64 cfd_seq_inc(unsigned int src, unsigned int dst, unsigned int type)
211211
} while (0)
212212

213213
/* Record current CSD work for current CPU, NULL to erase. */
214-
static void __csd_lock_record(call_single_data_t *csd)
214+
static void __csd_lock_record(struct __call_single_data *csd)
215215
{
216216
if (!csd) {
217217
smp_mb(); /* NULL cur_csd after unlock. */
@@ -226,13 +226,13 @@ static void __csd_lock_record(call_single_data_t *csd)
226226
/* Or before unlock, as the case may be. */
227227
}
228228

229-
static __always_inline void csd_lock_record(call_single_data_t *csd)
229+
static __always_inline void csd_lock_record(struct __call_single_data *csd)
230230
{
231231
if (static_branch_unlikely(&csdlock_debug_enabled))
232232
__csd_lock_record(csd);
233233
}
234234

235-
static int csd_lock_wait_getcpu(call_single_data_t *csd)
235+
static int csd_lock_wait_getcpu(struct __call_single_data *csd)
236236
{
237237
unsigned int csd_type;
238238

@@ -282,7 +282,7 @@ static const char *csd_lock_get_type(unsigned int type)
282282
return (type >= ARRAY_SIZE(seq_type)) ? "?" : seq_type[type];
283283
}
284284

285-
static void csd_lock_print_extended(call_single_data_t *csd, int cpu)
285+
static void csd_lock_print_extended(struct __call_single_data *csd, int cpu)
286286
{
287287
struct cfd_seq_local *seq = &per_cpu(cfd_seq_local, cpu);
288288
unsigned int srccpu = csd->node.src;
@@ -321,7 +321,7 @@ static void csd_lock_print_extended(call_single_data_t *csd, int cpu)
321321
* the CSD_TYPE_SYNC/ASYNC types provide the destination CPU,
322322
* so waiting on other types gets much less information.
323323
*/
324-
static bool csd_lock_wait_toolong(call_single_data_t *csd, u64 ts0, u64 *ts1, int *bug_id)
324+
static bool csd_lock_wait_toolong(struct __call_single_data *csd, u64 ts0, u64 *ts1, int *bug_id)
325325
{
326326
int cpu = -1;
327327
int cpux;
@@ -387,7 +387,7 @@ static bool csd_lock_wait_toolong(call_single_data_t *csd, u64 ts0, u64 *ts1, in
387387
* previous function call. For multi-cpu calls its even more interesting
388388
* as we'll have to ensure no other cpu is observing our csd.
389389
*/
390-
static void __csd_lock_wait(call_single_data_t *csd)
390+
static void __csd_lock_wait(struct __call_single_data *csd)
391391
{
392392
int bug_id = 0;
393393
u64 ts0, ts1;
@@ -401,7 +401,7 @@ static void __csd_lock_wait(call_single_data_t *csd)
401401
smp_acquire__after_ctrl_dep();
402402
}
403403

404-
static __always_inline void csd_lock_wait(call_single_data_t *csd)
404+
static __always_inline void csd_lock_wait(struct __call_single_data *csd)
405405
{
406406
if (static_branch_unlikely(&csdlock_debug_enabled)) {
407407
__csd_lock_wait(csd);
@@ -431,17 +431,17 @@ static void __smp_call_single_queue_debug(int cpu, struct llist_node *node)
431431
#else
432432
#define cfd_seq_store(var, src, dst, type)
433433

434-
static void csd_lock_record(call_single_data_t *csd)
434+
static void csd_lock_record(struct __call_single_data *csd)
435435
{
436436
}
437437

438-
static __always_inline void csd_lock_wait(call_single_data_t *csd)
438+
static __always_inline void csd_lock_wait(struct __call_single_data *csd)
439439
{
440440
smp_cond_load_acquire(&csd->node.u_flags, !(VAL & CSD_FLAG_LOCK));
441441
}
442442
#endif
443443

444-
static __always_inline void csd_lock(call_single_data_t *csd)
444+
static __always_inline void csd_lock(struct __call_single_data *csd)
445445
{
446446
csd_lock_wait(csd);
447447
csd->node.u_flags |= CSD_FLAG_LOCK;
@@ -454,7 +454,7 @@ static __always_inline void csd_lock(call_single_data_t *csd)
454454
smp_wmb();
455455
}
456456

457-
static __always_inline void csd_unlock(call_single_data_t *csd)
457+
static __always_inline void csd_unlock(struct __call_single_data *csd)
458458
{
459459
WARN_ON(!(csd->node.u_flags & CSD_FLAG_LOCK));
460460

@@ -501,7 +501,7 @@ void __smp_call_single_queue(int cpu, struct llist_node *node)
501501
* for execution on the given CPU. data must already have
502502
* ->func, ->info, and ->flags set.
503503
*/
504-
static int generic_exec_single(int cpu, call_single_data_t *csd)
504+
static int generic_exec_single(int cpu, struct __call_single_data *csd)
505505
{
506506
if (cpu == smp_processor_id()) {
507507
smp_call_func_t func = csd->func;
@@ -784,7 +784,7 @@ EXPORT_SYMBOL(smp_call_function_single);
784784
* NOTE: Be careful, there is unfortunately no current debugging facility to
785785
* validate the correctness of this serialization.
786786
*/
787-
int smp_call_function_single_async(int cpu, call_single_data_t *csd)
787+
int smp_call_function_single_async(int cpu, struct __call_single_data *csd)
788788
{
789789
int err = 0;
790790

kernel/up.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
2525
}
2626
EXPORT_SYMBOL(smp_call_function_single);
2727

28-
int smp_call_function_single_async(int cpu, call_single_data_t *csd)
28+
int smp_call_function_single_async(int cpu, struct __call_single_data *csd)
2929
{
3030
unsigned long flags;
3131

0 commit comments

Comments
 (0)