Skip to contentSkip to conversation

perf tool: Improve bash command line auto-complete for multiple events with comma

PATCH In review Jin Yao 3 participants 4 messages Dec 21, 2017 – Dec 28, 2017 perf events

lore
Share & tools
lore

Jin Yao

author
#0 lore raw

PATCH 1/1 perf tool: Improve bash command line auto-complete for multiple events with comma

perf has perf-completion.sh to define command line auto-completion in bash/zsh.

For record/stat -e it works for single events, but not working when specifying multiple events with comma.

This would be very useful if it could be fixed to make it easier by supporting of multiple events with comma.

With this patch, the result could be:

1. Support the events returned from 'perf list --raw-dump'

root@skl:/tmp# perf stat -e cpu/cache <TAB>
cpu/cache-misses/      cpu/cache-references/
root@skl:/tmp# perf stat -e cpu/cache-misses/,cpu/branch- <TAB>
cpu/branch-instructions/  cpu/branch-misses/
root@skl:/tmp# perf stat -e cpu/cache-misses/,cpu/branch-i <TAB>
root@skl:/tmp# perf stat -e cpu/cache-misses/,cpu/branch-instructions/

2. Support the events listed in /sys/bus/event_source/devices/cpu/events

root@skl:/tmp# perf stat -e cycle <TAB>
cycle_activity.cycles_l1d_miss  cycle_activity.stalls_l3_miss
cycle_activity.cycles_l2_miss   cycle_activity.stalls_mem_any
cycle_activity.cycles_l3_miss   cycle_activity.stalls_total
cycle_activity.cycles_mem_any   cycles-ct
cycle_activity.stalls_l1d_miss  cycles-t
cycle_activity.stalls_l2_miss
root@skl:/tmp# perf stat -e cycles- <TAB>
cycles-ct  cycles-t
root@skl:/tmp# perf stat -e cycles-t,cpu/c <TAB>
cpu/cache-misses/      cpu/cpu-cycles/        cpu/cycles-t/
cpu/cache-references/  cpu/cycles-ct/
root@skl:/tmp# perf stat -e cycles-t,cpu/cache- <TAB>
cpu/cache-misses/      cpu/cache-references/
root@skl:/tmp# perf stat -e cycles-t,cpu/cache-misses/

3. Support the uppercase event which is with prefix "cpu/"

root@skl:/tmp# perf stat -e cpu/c <TAB>
cpu/cache-misses/      cpu/cpu-cycles/        cpu/cycles-t/
cpu/cache-references/  cpu/cycles-ct/
root@skl:/tmp# perf stat -e cpu/cache-misses/,cpu/C <TAB>
cpu/CACHE-MISSES/      cpu/CPU-CYCLES/        cpu/CYCLES-T/
cpu/CACHE-REFERENCES/  cpu/CYCLES-CT/
root@skl:/tmp# perf stat -e cpu/cache-misses/,cpu/CACHE-REFERENCES/

Note that:

a) This patch only supports bash.

b) It doesn't support the cases like {},{} or {...,...}.

---
 tools/perf/perf-completion.sh | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)
tools/perf/perf-completion.sh +34 -4
index 345f5d6..d831083 100644
@@ -162,8 +162,33 @@ __perf_main ()
 	# List possible events for -e option
 	elif [[ $prev == @("-e"|"--event") &&
 		$prev_skip_opts == @(record|stat|top) ]]; then
-		evts=$($cmd list --raw-dump)
-		__perfcomp_colon "$evts" "$cur"
+
+		local cur1=${COMP_WORDS[COMP_CWORD]}
+		local raw_evts=$($cmd list --raw-dump)
+		local arr s tmp result
+
+		if [[ "$cur1" == */* && ${cur1#*/} =~ ^[A-Z] ]]; then
+			OLD_IFS="$IFS"
+			IFS=" "
+			arr=($raw_evts)
+			IFS="$OLD_IFS"
+
+			for s in ${arr[@]}
+			do
+				if [[ "$s" == *cpu/* ]]; then
+					tmp=${s#*cpu/}
+					result=$result" ""cpu/"${tmp^^}
+				else
+					result=$result" "$s
+				fi
+			done
+
+			evts=${result}+$(ls /sys/bus/event_source/devices/cpu/events)
+		else
+			evts=${raw_evts}+$(ls /sys/bus/event_source/devices/cpu/events)
+		fi
+
+		__perfcomp_colon "$evts" "$cur1"
 	else
 		# List subcommands for perf commands
 		if [[ $prev_skip_opts == @(kvm|kmem|mem|lock|sched|
@@ -246,11 +271,16 @@ fi
 type perf &>/dev/null &&
 _perf()
 {
+	if [[ "$COMP_WORDBREAKS" != *,* ]]; then
+		COMP_WORDBREAKS="${COMP_WORDBREAKS},"
+		export COMP_WORDBREAKS
+	fi
+
 	local cur words cword prev
 	if [ $preload_get_comp_words_by_ref = "true" ]; then
-		_get_comp_words_by_ref -n =: cur words cword prev
+		_get_comp_words_by_ref -n =:, cur words cword prev
 	else
-		__perf_get_comp_words_by_ref -n =: cur words cword prev
+		__perf_get_comp_words_by_ref -n =:, cur words cword prev
 	fi
 	__perf_main
 } &&
Signature · 1 line
2.7.4
#1 lore raw

Em Thu, Dec 21, 2017 at 05:26:10PM +0800, Jin Yao escreveu:

Quoted 5 lines

perf has perf-completion.sh to define command line auto-completion in bash/zsh.

For record/stat -e it works for single events, but not working when specifying multiple events with comma.

I'm testing this, and found one issue, that can be fixed in a followup patch, I think:

If I do:

perf stat -e <TAB>

Then it will get all events and offer them as completions:

[acme@jouet perf]$ perf stat -e
Display all 1523 possibilities? (y or n)

Which is around what:

[acme@jouet perf]$ perf list --raw-dump | wc -w
1509
[acme@jouet perf]$

gives.

Ok, so if I say yes all will be presented, and the pager will be used, etc. then I can press 'q' as soon as I find the one I want and continue from there (the pager doesn't allow searching with '/', would be nice).

then, the behaviour changes after I add a comma:

[acme@jouet perf]$ perf stat -e cycles,<TAB>
0000-cover-letter.patch Kbuild
0001-perf-tools-Use-shell-function-for-perl-cflags-retrie.patch Kconfig <SNIP>
[acme@jouet perf]$ perf stat -e cycles

I.e. after the comma it tries autocompletion with files in the local directory, not with the list of all events.

Only if I have some character right after the comma is that it will look for events and not files in the local directory:

ipc/
[acme@jouet perf]$ perf stat -e cycles,i<TAB>

icache.hit                                         idq_uops_not_delivered.cycles_le_3_uop_deliv.core
icache.ifdata_stall                                ild_stall.lcp
icache.misses                                      inst_retired.any
idq.all_dsb_cycles_4_uops                          inst_retired.any_p
idq.all_dsb_cycles_any_uops                        inst_retired.prec_dist
idq.all_mite_cycles_4_uops                         inst_retired.x87
idq.all_mite_cycles_any_uops                       instructions
idq.dsb_cycles                                     intel_bts//
idq.dsb_uops                                       intel_pt//

<SNIP>
[acme@jouet perf]$ perf stat -e cycles,i

Would be nice to have the same behaviour right after the comma as when right after -e.

I'm doing a few more tests but I think this can be merged as-is and the above be just a suggestion for improvement.

Thanks,

- Arnaldo

author
#2 lore raw
Quoted 62 lines · Arnaldo Carvalho de Melo

Em Thu, Dec 21, 2017 at 05:26:10PM +0800, Jin Yao escreveu:

Quoted 5 lines

perf has perf-completion.sh to define command line auto-completion in bash/zsh.

For record/stat -e it works for single events, but not working when specifying multiple events with comma.

I'm testing this, and found one issue, that can be fixed in a followup patch, I think:

If I do:

perf stat -e <TAB>

Then it will get all events and offer them as completions:

[acme@jouet perf]$ perf stat -e
Display all 1523 possibilities? (y or n)

Which is around what:

[acme@jouet perf]$ perf list --raw-dump | wc -w
1509
[acme@jouet perf]$

gives.

Ok, so if I say yes all will be presented, and the pager will be used, etc. then I can press 'q' as soon as I find the one I want and continue from there (the pager doesn't allow searching with '/', would be nice).

then, the behaviour changes after I add a comma:

[acme@jouet perf]$ perf stat -e cycles,<TAB>
0000-cover-letter.patch Kbuild
0001-perf-tools-Use-shell-function-for-perl-cflags-retrie.patch Kconfig <SNIP>
[acme@jouet perf]$ perf stat -e cycles

I.e. after the comma it tries autocompletion with files in the local directory, not with the list of all events.

Only if I have some character right after the comma is that it will look for events and not files in the local directory:

ipc/
[acme@jouet perf]$ perf stat -e cycles,i<TAB>

icache.hit                                         idq_uops_not_delivered.cycles_le_3_uop_deliv.core
icache.ifdata_stall                                ild_stall.lcp
icache.misses                                      inst_retired.any
idq.all_dsb_cycles_4_uops                          inst_retired.any_p
idq.all_dsb_cycles_any_uops                        inst_retired.prec_dist
idq.all_mite_cycles_4_uops                         inst_retired.x87
idq.all_mite_cycles_any_uops                       instructions
idq.dsb_cycles                                     intel_bts//
idq.dsb_uops                                       intel_pt//

<SNIP>
[acme@jouet perf]$ perf stat -e cycles,i

Would be nice to have the same behaviour right after the comma as when right after -e.

Quoted 7 lines

I'm doing a few more tests but I think this can be merged as-is and the above be just a suggestion for improvement.

Thanks,

- Arnaldo

Hi Arnaldo,

Thanks so much for testing and merging this patch.

Yes, it could have a further improvement. I will post a follow-up patch to fix this issue.

Thanks
Jin Yao

#3 lore raw
In reply to Jin Yao
perf tool: Improve bash command line auto-complete for multiple events with comma
Commit-ID:  74cd5815d9af6e6c4f3bcecfbc8e439f2fd7e6b1
Gitweb:     https://git.kernel.org/tip/74cd5815d9af6e6c4f3bcecfbc8e439f2fd7e6b1
Author:     Jin Yao <[email protected]>
AuthorDate: Thu, 21 Dec 2017 17:26:10 +0800
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Wed, 27 Dec 2017 12:15:59 -0300

perf tool: Improve bash command line auto-complete for multiple events with comma

perf has perf-completion.sh to define command line auto-completion in bash/zsh.

For record/stat -e it works for single events, but isn't working when specifying multiple events with comma.

It would be very useful if it could be fixed to make it easier by supporting multiple events, comma separated.

With this patch, the result can be like this:

1. Support the events returned from 'perf list --raw-dump'

root@skl:/tmp# perf stat -e cpu/cache<TAB>
cpu/cache-misses/      cpu/cache-references/
root@skl:/tmp# perf stat -e cpu/cache-misses/,cpu/branch-<TAB>
cpu/branch-instructions/  cpu/branch-misses/
root@skl:/tmp# perf stat -e cpu/cache-misses/,cpu/branch-i<TAB>
root@skl:/tmp# perf stat -e cpu/cache-misses/,cpu/branch-instructions/

2. Support the events listed in /sys/bus/event_source/devices/cpu/events

root@skl:/tmp# perf stat -e cycle<TAB>
cycle_activity.cycles_l1d_miss  cycle_activity.stalls_l3_miss
cycle_activity.cycles_l2_miss   cycle_activity.stalls_mem_any
cycle_activity.cycles_l3_miss   cycle_activity.stalls_total
cycle_activity.cycles_mem_any   cycles-ct
cycle_activity.stalls_l1d_miss  cycles-t
cycle_activity.stalls_l2_miss
root@skl:/tmp# perf stat -e cycles-<TAB>
cycles-ct  cycles-t
root@skl:/tmp# perf stat -e cycles-t,cpu/c<TAB>
cpu/cache-misses/      cpu/cpu-cycles/        cpu/cycles-t/
cpu/cache-references/  cpu/cycles-ct/
root@skl:/tmp# perf stat -e cycles-t,cpu/cache-<TAB>
cpu/cache-misses/      cpu/cache-references/
root@skl:/tmp# perf stat -e cycles-t,cpu/cache-misses/

3. Support the uppercase event which is with prefix "cpu/"

root@skl:/tmp# perf stat -e cpu/c<TAB>
cpu/cache-misses/      cpu/cpu-cycles/        cpu/cycles-t/
cpu/cache-references/  cpu/cycles-ct/
root@skl:/tmp# perf stat -e cpu/cache-misses/,cpu/C<TAB>
cpu/CACHE-MISSES/      cpu/CPU-CYCLES/        cpu/CYCLES-T/
cpu/CACHE-REFERENCES/  cpu/CYCLES-CT/
root@skl:/tmp# perf stat -e cpu/cache-misses/,cpu/CACHE-REFERENCES/

Note that:

a) This patch only supports bash.

b) It doesn't support the cases like {},{} or {...,...}.

---
 tools/perf/perf-completion.sh | 38 ++++++++++++++++++++++++++++++++++----
 1 file changed, 34 insertions(+), 4 deletions(-)
tools/perf/perf-completion.sh +34 -4
index 345f5d6..d831083 100644
@@ -162,8 +162,33 @@ __perf_main ()
 	# List possible events for -e option
 	elif [[ $prev == @("-e"|"--event") &&
 		$prev_skip_opts == @(record|stat|top) ]]; then
-		evts=$($cmd list --raw-dump)
-		__perfcomp_colon "$evts" "$cur"
+
+		local cur1=${COMP_WORDS[COMP_CWORD]}
+		local raw_evts=$($cmd list --raw-dump)
+		local arr s tmp result
+
+		if [[ "$cur1" == */* && ${cur1#*/} =~ ^[A-Z] ]]; then
+			OLD_IFS="$IFS"
+			IFS=" "
+			arr=($raw_evts)
+			IFS="$OLD_IFS"
+
+			for s in ${arr[@]}
+			do
+				if [[ "$s" == *cpu/* ]]; then
+					tmp=${s#*cpu/}
+					result=$result" ""cpu/"${tmp^^}
+				else
+					result=$result" "$s
+				fi
+			done
+
+			evts=${result}+$(ls /sys/bus/event_source/devices/cpu/events)
+		else
+			evts=${raw_evts}+$(ls /sys/bus/event_source/devices/cpu/events)
+		fi
+
+		__perfcomp_colon "$evts" "$cur1"
 	else
 		# List subcommands for perf commands
 		if [[ $prev_skip_opts == @(kvm|kmem|mem|lock|sched|
@@ -246,11 +271,16 @@ fi
 type perf &>/dev/null &&
 _perf()
 {
+	if [[ "$COMP_WORDBREAKS" != *,* ]]; then
+		COMP_WORDBREAKS="${COMP_WORDBREAKS},"
+		export COMP_WORDBREAKS
+	fi
+
 	local cur words cword prev
 	if [ $preload_get_comp_words_by_ref = "true" ]; then
-		_get_comp_words_by_ref -n =: cur words cword prev
+		_get_comp_words_by_ref -n =:, cur words cword prev
 	else
-		__perf_get_comp_words_by_ref -n =: cur words cword prev
+		__perf_get_comp_words_by_ref -n =:, cur words cword prev
 	fi
 	__perf_main
 } &&