Skip to content

Commit 949fa3f

Browse files
Leonardo BrasPeter Zijlstra
authored andcommitted
trace,smp: Add tracepoints around remotelly called functions
The recently added ipi_send_{cpu,cpumask} tracepoints allow finding sources of IPIs targeting CPUs running latency-sensitive applications. For NOHZ_FULL CPUs, all IPIs are interference, and those tracepoints are sufficient to find them and work on getting rid of them. In some setups however, not *all* IPIs are to be suppressed, but long-running IPI callbacks can still be problematic. Add a pair of tracepoints to mark the start and end of processing a CSD IPI callback, similar to what exists for softirq, workqueue or timer callbacks. Signed-off-by: Leonardo Bras <leobras@redhat.com> Tested-and-reviewed-by: Valentin Schneider <vschneid@redhat.com> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/r/20230615065944.188876-5-leobras@redhat.com
1 parent 60be49b commit 949fa3f

2 files changed

Lines changed: 64 additions & 6 deletions

File tree

include/trace/events/csd.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#undef TRACE_SYSTEM
3+
#define TRACE_SYSTEM csd
4+
5+
#if !defined(_TRACE_CSD_H) || defined(TRACE_HEADER_MULTI_READ)
6+
#define _TRACE_CSD_H
7+
8+
#include <linux/tracepoint.h>
9+
10+
/*
11+
* Tracepoints for a function which is called as an effect of smp_call_function.*
12+
*/
13+
DECLARE_EVENT_CLASS(csd_function,
14+
15+
TP_PROTO(smp_call_func_t func, struct __call_single_data *csd),
16+
17+
TP_ARGS(func, csd),
18+
19+
TP_STRUCT__entry(
20+
__field(void *, func)
21+
__field(void *, csd)
22+
),
23+
24+
TP_fast_assign(
25+
__entry->func = func;
26+
__entry->csd = csd;
27+
),
28+
29+
TP_printk("func=%ps, csd=%p", __entry->func, __entry->csd)
30+
);
31+
32+
DEFINE_EVENT(csd_function, csd_function_entry,
33+
TP_PROTO(smp_call_func_t func, struct __call_single_data *csd),
34+
TP_ARGS(func, csd)
35+
);
36+
37+
DEFINE_EVENT(csd_function, csd_function_exit,
38+
TP_PROTO(smp_call_func_t func, struct __call_single_data *csd),
39+
TP_ARGS(func, csd)
40+
);
41+
42+
#endif /* _TRACE_CSD_H */
43+
44+
/* This part must be outside protection */
45+
#include <trace/define_trace.h>

kernel/smp.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#include <linux/jump_label.h>
2828

2929
#include <trace/events/ipi.h>
30+
#define CREATE_TRACE_POINTS
31+
#include <trace/events/csd.h>
32+
#undef CREATE_TRACE_POINTS
3033

3134
#include "smpboot.h"
3235
#include "sched/smp.h"
@@ -121,6 +124,14 @@ send_call_function_ipi_mask(struct cpumask *mask)
121124
arch_send_call_function_ipi_mask(mask);
122125
}
123126

127+
static __always_inline void
128+
csd_do_func(smp_call_func_t func, void *info, struct __call_single_data *csd)
129+
{
130+
trace_csd_function_entry(func, csd);
131+
func(info);
132+
trace_csd_function_exit(func, csd);
133+
}
134+
124135
#ifdef CONFIG_CSD_LOCK_WAIT_DEBUG
125136

126137
static DEFINE_STATIC_KEY_MAYBE(CONFIG_CSD_LOCK_WAIT_DEBUG_DEFAULT, csdlock_debug_enabled);
@@ -375,7 +386,7 @@ static int generic_exec_single(int cpu, struct __call_single_data *csd)
375386
csd_lock_record(csd);
376387
csd_unlock(csd);
377388
local_irq_save(flags);
378-
func(info);
389+
csd_do_func(func, info, NULL);
379390
csd_lock_record(NULL);
380391
local_irq_restore(flags);
381392
return 0;
@@ -477,7 +488,7 @@ static void __flush_smp_call_function_queue(bool warn_cpu_offline)
477488
}
478489

479490
csd_lock_record(csd);
480-
func(info);
491+
csd_do_func(func, info, csd);
481492
csd_unlock(csd);
482493
csd_lock_record(NULL);
483494
} else {
@@ -508,7 +519,7 @@ static void __flush_smp_call_function_queue(bool warn_cpu_offline)
508519

509520
csd_lock_record(csd);
510521
csd_unlock(csd);
511-
func(info);
522+
csd_do_func(func, info, csd);
512523
csd_lock_record(NULL);
513524
} else if (type == CSD_TYPE_IRQ_WORK) {
514525
irq_work_single(csd);
@@ -522,8 +533,10 @@ static void __flush_smp_call_function_queue(bool warn_cpu_offline)
522533
/*
523534
* Third; only CSD_TYPE_TTWU is left, issue those.
524535
*/
525-
if (entry)
526-
sched_ttwu_pending(entry);
536+
if (entry) {
537+
csd = llist_entry(entry, typeof(*csd), node.llist);
538+
csd_do_func(sched_ttwu_pending, entry, csd);
539+
}
527540
}
528541

529542

@@ -816,7 +829,7 @@ static void smp_call_function_many_cond(const struct cpumask *mask,
816829
unsigned long flags;
817830

818831
local_irq_save(flags);
819-
func(info);
832+
csd_do_func(func, info, NULL);
820833
local_irq_restore(flags);
821834
}
822835

0 commit comments

Comments
 (0)