perf/core: expose thread context switch out event type to user space
v5 cover perf/core: expose thread context switch out event type to user space
Implement preempting context switch out event as a part of PERF_RECORD_SWITCH[_CPU_WIDE] record. The event is treated as preemption one when task->state value of the thread being switched out is TASK_RUNNING;
Percentage of preempting and non-preempting context switches help understanding the nature of workloads (CPU or IO bound) that are running on the machine;
Event type encoding is implemented using a new PERF_RECORD_MISC_SWITCH_OUT_PREEMPT bit in misc field of event record header;
Perf tool report and script commands have been extended to decode new PREEMPT bit and the updated output looks like this:
tools/perf/perf report -D -i perf.data | grep _SWITCH
0 768361415226 0x27f076 [0x28]: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 8/8 4 768362216813 0x28f45e [0x28]: PERF_RECORD_SWITCH_CPU_WIDE OUT next pid/tid: 0/0 4 768362217824 0x28f486 [0x28]: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 4073/4073 0 768362414027 0x27f0ce [0x28]: PERF_RECORD_SWITCH_CPU_WIDE OUT preempt next pid/tid: 8/8 0 768362414367 0x27f0f6 [0x28]: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 0/0
perf script --show-switch-events -F +misc -I -i perf.data:
hdparm 4073 [004] U 762.198265: 380194 cycles:ppp: 7faf727f5a23 strchr (/usr/lib64/ld-2.26.so)
hdparm 4073 [004] K 762.198366: 441572 cycles:ppp: ffffffffb9218435 alloc_set_pte (/lib/modules/4.16.0-rc6+/build/vmlinux)
hdparm 4073 [004] S 762.198391: PERF_RECORD_SWITCH_CPU_WIDE OUT next pid/tid: 0/0
swapper 0 [004] 762.198392: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 4073/4073
swapper 0 [004] Sp 762.198477: PERF_RECORD_SWITCH_CPU_WIDE OUT preempt next pid/tid: 4073/4073
hdparm 4073 [004] 762.198478: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 0/0
swapper 0 [007] K 762.198514: 2303073 cycles:ppp: ffffffffb98b0c66 intel_idle (/lib/modules/4.16.0-rc6+/build/vmlinux)
swapper 0 [007] Sp 762.198561: PERF_RECORD_SWITCH_CPU_WIDE OUT preempt next pid/tid: 1134/1134
kworker/u16:18 1134 [007] 762.198562: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 0/0
kworker/u16:18 1134 [007] S 762.198567: PERF_RECORD_SWITCH_CPU_WIDE OUT next pid/tid: 0/0 The documentation has been updated to mention PREEMPT switch out events and its decoding symbols in perf script output.
The changes have been manually tested on Fedora 27 with the patched kernel:git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
---
Alexey Budankov (3):
perf/core: store context switch out type into Perf trace perf report: extend raw dump (-D) out with switch out event type perf script: extend misc field decoding with switch out event type
include/uapi/linux/perf_event.h | 18 +++++++++++++++--- kernel/events/core.c | 4 ++++ tools/include/uapi/linux/perf_event.h | 18 +++++++++++++++--- tools/perf/Documentation/perf-script.txt | 17 +++++++++-------- tools/perf/builtin-script.c | 5 ++++- tools/perf/util/event.c | 4 +++- 6 files changed, 50 insertions(+), 16 deletions(-)
PATCH v5 1/3 perf/core: store context switch out type into Perf trace
Store preempting context switch out event into Perf trace as a part of PERF_RECORD_SWITCH[_CPU_WIDE] record.
Percentage of preempting and non-preempting context switches help understanding the nature of workloads (CPU or IO bound) that are running on a machine;
The event is treated as preemption one when task->state value of the thread being switched out is TASK_RUNNING. Event type encoding is implemented using PERF_RECORD_MISC_SWITCH_OUT_PREEMPT bit;
--- include/uapi/linux/perf_event.h | 18 +++++++++++++++--- kernel/events/core.c | 4 ++++ tools/include/uapi/linux/perf_event.h | 18 +++++++++++++++--- 3 files changed, 34 insertions(+), 6 deletions(-)
include/uapi/linux/perf_event.h +15 -3
@@ -650,11 +650,23 @@ struct perf_event_mmap_page {#define PERF_RECORD_MISC_COMM_EXEC (1 << 13)#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13)/* -* Indicates that the content of PERF_SAMPLE_IP points to -* the actual instruction that triggered the event. See also -* perf_event_attr::precise_ip. +* These PERF_RECORD_MISC_* flags below are safely reused +* for the following events: +* +* PERF_RECORD_MISC_EXACT_IP - PERF_RECORD_SAMPLE of precise events +* PERF_RECORD_MISC_SWITCH_OUT_PREEMPT - PERF_RECORD_SWITCH* events +* +* +* PERF_RECORD_MISC_EXACT_IP: +* Indicates that the content of PERF_SAMPLE_IP points to +* the actual instruction that triggered the event. See also +* perf_event_attr::precise_ip. +* +* PERF_RECORD_MISC_SWITCH_OUT_PREEMPT: +* Indicates that thread was preempted in TASK_RUNNING state. */ #define PERF_RECORD_MISC_EXACT_IP (1 << 14) +#define PERF_RECORD_MISC_SWITCH_OUT_PREEMPT (1 << 14)/* * Reserve the last bit to indicate some extended misc field */
kernel/events/core.c +4 -0
@@ -7584,6 +7584,10 @@ static void perf_event_switch(struct task_struct *task, }, }; +if (!sched_in && task->state ==TASK_RUNNING ) + switch_event.event_id.header.misc |= +PERF_RECORD_MISC_SWITCH_OUT_PREEMPT ; +perf_iterate_sb (perf_event_switch_output, &switch_event,NULL );
tools/include/uapi/linux/perf_event.h +15 -3
@@ -650,11 +650,23 @@ struct perf_event_mmap_page {#define PERF_RECORD_MISC_COMM_EXEC (1 << 13)#define PERF_RECORD_MISC_SWITCH_OUT (1 << 13)/* -* Indicates that the content of PERF_SAMPLE_IP points to -* the actual instruction that triggered the event. See also -* perf_event_attr::precise_ip. +* These PERF_RECORD_MISC_* flags below are safely reused +* for the following events: +* +* PERF_RECORD_MISC_EXACT_IP - PERF_RECORD_SAMPLE of precise events +* PERF_RECORD_MISC_SWITCH_OUT_PREEMPT - PERF_RECORD_SWITCH* events +* +* +* PERF_RECORD_MISC_EXACT_IP: +* Indicates that the content of PERF_SAMPLE_IP points to +* the actual instruction that triggered the event. See also +* perf_event_attr::precise_ip. +* +* PERF_RECORD_MISC_SWITCH_OUT_PREEMPT: +* Indicates that thread was preempted in TASK_RUNNING state. */ #define PERF_RECORD_MISC_EXACT_IP (1 << 14) +#define PERF_RECORD_MISC_SWITCH_OUT_PREEMPT (1 << 14)/* * Reserve the last bit to indicate some extended misc field */
PATCH v5 2/3 perf report: extend raw dump (-D) out with switch out event type
In reply to Alexey BudankovPrint additional 'preempt' tag for PERF_RECORD_SWITCH[_CPU_WIDE] OUT records when event header misc field contains PERF_RECORD_MISC_SWITCH_OUT_PREEMPT bit set designating preemption context switch out event:
tools/perf/perf report -D -i perf.data | grep _SWITCH
0 768361415226 0x27f076 [0x28]: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 8/8 4 768362216813 0x28f45e [0x28]: PERF_RECORD_SWITCH_CPU_WIDE OUT next pid/tid: 0/0 4 768362217824 0x28f486 [0x28]: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 4073/4073 0 768362414027 0x27f0ce [0x28]: PERF_RECORD_SWITCH_CPU_WIDE OUT preempt next pid/tid: 8/8 0 768362414367 0x27f0f6 [0x28]: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 0/0
--- tools/perf/util/event.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/perf/util/event.c +3 -1
@@ -1421,7 +1421,9 @@ size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp)size_t perf_event__fprintf_switch (union perf_event *event,FILE *fp) {bool out = event->header.misc &PERF_RECORD_MISC_SWITCH_OUT ; -const char *in_out = out ?"OUT" :"IN " ; +const char *in_out = !out ?"IN " : + !(event->header.misc &PERF_RECORD_MISC_SWITCH_OUT_PREEMPT ) ? +"OUT " :"OUT preempt" ;if (event->header.type ==PERF_RECORD_SWITCH )return fprintf (fp," %s\n" , in_out);
PATCH v5 3/3 perf script: extend misc field decoding with switch out event type
In reply to Alexey BudankovAppend 'p' sign to 'S' tag designating the type of context switch out event so 'Sp' means preemption context switch. Documentation is extended to cover new presentation changes.
perf script --show-switch-events -F +misc -I -i perf.data:
hdparm 4073 [004] U 762.198265: 380194 cycles:ppp: 7faf727f5a23 strchr (/usr/lib64/ld-2.26.so)
hdparm 4073 [004] K 762.198366: 441572 cycles:ppp: ffffffffb9218435 alloc_set_pte (/lib/modules/4.16.0-rc6+/build/vmlinux)
hdparm 4073 [004] S 762.198391: PERF_RECORD_SWITCH_CPU_WIDE OUT next pid/tid: 0/0
swapper 0 [004] 762.198392: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 4073/4073
swapper 0 [004] Sp 762.198477: PERF_RECORD_SWITCH_CPU_WIDE OUT preempt next pid/tid: 4073/4073
hdparm 4073 [004] 762.198478: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 0/0
swapper 0 [007] K 762.198514: 2303073 cycles:ppp: ffffffffb98b0c66 intel_idle (/lib/modules/4.16.0-rc6+/build/vmlinux)
swapper 0 [007] Sp 762.198561: PERF_RECORD_SWITCH_CPU_WIDE OUT preempt next pid/tid: 1134/1134
kworker/u16:18 1134 [007] 762.198562: PERF_RECORD_SWITCH_CPU_WIDE IN prev pid/tid: 0/0
kworker/u16:18 1134 [007] S 762.198567: PERF_RECORD_SWITCH_CPU_WIDE OUT next pid/tid: 0/0 --- tools/perf/Documentation/perf-script.txt | 17 +++++++++-------- tools/perf/builtin-script.c | 5 ++++- 2 files changed, 13 insertions(+), 9 deletions(-)
tools/perf/Documentation/perf-script.txt +9 -8
@@ -228,14 +228,15 @@ OPTIONS For sample events it's possible to display misc field with -F +misc option, following letters are displayed for each bit: - PERF_RECORD_MISC_KERNEL K - PERF_RECORD_MISC_USER U - PERF_RECORD_MISC_HYPERVISOR H - PERF_RECORD_MISC_GUEST_KERNEL G - PERF_RECORD_MISC_GUEST_USER g - PERF_RECORD_MISC_MMAP_DATA* M - PERF_RECORD_MISC_COMM_EXEC E - PERF_RECORD_MISC_SWITCH_OUT S + PERF_RECORD_MISC_KERNEL K + PERF_RECORD_MISC_USER U + PERF_RECORD_MISC_HYPERVISOR H + PERF_RECORD_MISC_GUEST_KERNEL G + PERF_RECORD_MISC_GUEST_USER g + PERF_RECORD_MISC_MMAP_DATA* M + PERF_RECORD_MISC_COMM_EXEC E + PERF_RECORD_MISC_SWITCH_OUT S + PERF_RECORD_MISC_SWITCH_OUT_PREEMPT Sp $ perf script -F +misc ... sched-messaging 1414 K 28690.636582: 4590 cycles ...
tools/perf/builtin-script.c +4 -1
@@ -657,8 +657,11 @@ static int perf_sample__fprintf_start(struct perf_sample *sample,break ;case PERF_RECORD_SWITCH :case PERF_RECORD_SWITCH_CPU_WIDE : -if (has (SWITCH_OUT )) +if (has (SWITCH_OUT )) { ret +=fprintf (fp,"S" ); +if (sample->misc &PERF_RECORD_MISC_SWITCH_OUT_PREEMPT ) + ret +=fprintf (fp,"p" ); + }default :break ; }