ãã®èšäºã¯ã NTT Communications Advent Calendar 2024 2 æ¥ç®ã®èšäºã§ãã perf ã® Python ã€ã³ã¿ããªã¿ã䜿ã£ãŠ KVM Exit/Entry ã®ã¬ã€ãã³ã·ãèšæž¬ããŠã¿ãŸãã ã¯ããã« KVM ã®ä»çµã¿ CPU ãã¬ãŒã¹ãååŸãã perf ããã«ããã Python ã³ãŒããæžã ç¬èªã¹ã¯ãªãããçšã㊠perf.data ãéèšãã ãŸãšã åèæç® ã¯ããã« ããã«ã¡ã¯ã SDPF ã¯ã©ãŠãã»ä»®æ³ãµãŒããŒããŒã ã®ææµŠ ( @Kumassy_ ) ã§ãã æ®æ®µã¯ OpenStack ã®éçºã»éçšãããŠãããæè¿ã¯ä»®æ³ãã·ã³ã®æ§èœè§£æããã©ãã«ã·ã¥ãŒãã£ã³ã°ãªã©ã«åãçµãã§ããŸãã perf 㯠Linux ã®ããã©ãŒãã³ã¹è§£æã«æçšãªããŒã«ã§ãã perf ã䜿ãããšã§ãããã©ãŒãã³ã¹ã«ãŠã³ã¿ã®å€ãèªãã ãããããã¡ã€ãªã³ã°ããã¬ãŒã·ã³ã°ãªã© æ§ã
ãªããŒã¿ãååŸããããšãã§ããŸã ã ååŸããããŒã¿ãåæããã«ã¯ perf report ã perf script ãå©çšã§ããŸããã蟌ã¿å
¥ã£ãããŒã¿ãè§£æããããšãã«ã¯ python ãŸã㯠perl ã§æžãããç¬èªã®ã¹ã¯ãªããã䜿ãããšãã§ããŸãã ä»å㯠perf ã® Python ã€ã³ã¿ããªã¿ã䜿ã£ãŠ KVM Exit/Entry ã®ã¬ã€ãã³ã·ãèšæž¬ããŠã¿ãŸãã KVM ã®ä»çµã¿ QEMU/KVM ãå©çšããä»®æ³ç°å¢ã§ã¯ããŠãŒã¶ãŒãäœæããä»®æ³ãã·ã³ã¯ QEMU ã®ãŠãŒã¶ãŒããã»ã¹ãšããŠå®è¡ãããŸãã ç®è¡æŒç®ãªã©ç°¡åãªåœä»€ã¯ãäžè¬çãªãŠãŒã¶ãŒããã»ã¹ãšåãããã«ãŠãŒã¶ãŒç©ºéã§åŠçãããŸããã I/O ãªã©ã®ã»ã³ã·ãã£ãåœä»€ã¯ãã€ããŒãã€ã¶åŽã§åŠçããå¿
èŠããããŸãã ä»®æ³ãã·ã³ãã»ã³ã·ãã£ãåœä»€ãå®è¡ããããšãããšãä»®æ³ãã·ã³ã®å®è¡ãäžæåæ¢ãã KVM Exit ãšããã€ãã³ããçºçããŸãã ãã€ããŒãã€ã¶ã¯ KVM Exit ãçºçããçç± (Exit Reason) ã調ã¹ãŠé©åã«åŠçããä»®æ³ãã·ã³ã®å®è¡ãåéããŸãããã®ãšã KVM Entry ã€ãã³ããçºçããŸãã ãã®ãµã€ã¯ã«ãå³ç€ºãããšæ¬¡ã®å³ã®ããã«ãªããŸãã KVM Exit ãçºçããŠãã KVM Entry ãå®äºãããŸã§ä»®æ³ãã·ã³ã¯äžæåæ¢ããŠããã®ã§ããã®ã¬ã€ãã³ã·ãé·ããšåé¡ã§ãã ãã®ãããªè§£æã«ã¯ perf kvm ãµãã³ãã³ããå©çšã§ããŸãããä»å㯠KVM Exit/Entry ã®ã¬ã€ãã³ã·ã顿ã«ã perf ã®ç¬èªã¹ã¯ãªãããæžããŠåæããŠã¿ãŸãã CPU ãã¬ãŒã¹ãååŸãã ãŸãã¯è§£æãã CPU ãã¬ãŒã¹ãååŸããŸãã ä»®æ³ãã·ã³ãå®è¡ããç©çãã·ã³ã«ã¯è€æ°ã® VM ãå容ãããŠããŸãã ããšã§è§£æããããããã«ã CPU affinity ã調æŽããããšã§ãè§£æå¯Ÿè±¡ VM ã® vCPU ãç¹å®ã®ç©ç CPU ã³ã¢ã« pinning ããŠãããŸãã $ sudo virsh vcpupin instance-0000xxxx 0 124 $ sudo virsh vcpupin instance-0000xxxx 1 125 $ sudo virsh vcpupin instance-0000xxxx 2 126 $ sudo virsh vcpupin instance-0000xxxx 3 127 以äžã®ãããªã³ãã³ãã§ kvm:kvm_exit ãš kvm:kvm_entry ã€ãã³ãã®ãã¬ãŒã¹ãååŸããŸãã $ sudo taskset -c 31 perf record -C 124-127 -e kvm:kvm_exit -e kvm:kvm_entry -- sleep 9000 perf script ã䜿ãã°ãã®ããã«è§£æã§ããŸãããå°ã
èŠã«ããã§ãã $ perf script -i /path/to/perf.data CPU 0/KVM 18292 [124] 151678.240967: kvm:kvm_exit: vcpu 0 reason MSR_WRITE rip 0xffffffff9ae6cf64 info1 0x0000000000000000 info2 0x0000000000000000 intr_info 0x00000000 error_code 0x00000000 CPU 0/KVM 18292 [124] 151678.240969: kvm:kvm_entry: vcpu 0, rip 0xffffffff9ae6cf66 CPU 0/KVM 18292 [124] 151678.240982: kvm:kvm_exit: vcpu 0 reason MSR_WRITE rip 0xffffffff9ae6cf64 info1 0x0000000000000000 info2 0x0000000000000000 intr_info 0x00000000 error_code 0x00000000 CPU 0/KVM 18292 [124] 151678.240983: kvm:kvm_entry: vcpu 0, rip 0xffffffff9ae6cf66 CPU 0/KVM 18292 [124] 151678.241044: kvm:kvm_exit: vcpu 0 reason EXTERNAL_INTERRUPT rip 0xffffffff9b0c99be info1 0x0000000000000000 info2 0x0000000000000000 intr_info 0x800000ec error_code 0x00000000 ããã§ãç¬èªã¹ã¯ãªããã§ã¯ä»¥äžã® 2 ã€ãç®æšãšããŸãã Exit Reason ããšã« KVM Exit/Entry ã®ã¬ã€ãã³ã·ããã¹ãã°ã©ã ãšããŠè¡šã äžèšãã¹ãã°ã©ã ãã³ã¢ããšã«åããŠè¡šç€ºãã perf ããã«ããã perf ã® Python ã€ã³ã¿ããªã¿ãå©çšããã«ã¯ã perf ã® libpython ãã«ããªãã·ã§ã³ãæå¹åãããŠããå¿
èŠããããŸãã ç§ã®ããŒã ã§å©çšã§ãã Ubuntu 22.04 ç°å¢ã§ã¯ã linux-tools-common ã«å«ãŸãã perf ã«ã¯ãã®ãªãã·ã§ã³ãæå¹åãããŠããŸããã§ããã $ sudo perf version --build-options perf version 5.15 dwarf: [ on ] # HAVE_DWARF_SUPPORT dwarf_getlocations: [ on ] # HAVE_DWARF_GETLOCATIONS_SUPPORT glibc: [ on ] # HAVE_GLIBC_SUPPORT syscall_table: [ on ] # HAVE_SYSCALL_TABLE_SUPPORT libbfd: [ OFF ] # HAVE_LIBBFD_SUPPORT libelf: [ on ] # HAVE_LIBELF_SUPPORT libnuma: [ on ] # HAVE_LIBNUMA_SUPPORT numa_num_possible_cpus: [ on ] # HAVE_LIBNUMA_SUPPORT libperl: [ OFF ] # HAVE_LIBPERL_SUPPORT libpython: [ OFF ] # HAVE_LIBPYTHON_SUPPORT libslang: [ on ] # HAVE_SLANG_SUPPORT libcrypto: [ on ] # HAVE_LIBCRYPTO_SUPPORT libunwind: [ on ] # HAVE_LIBUNWIND_SUPPORT libdw-dwarf-unwind: [ on ] # HAVE_DWARF_SUPPORT zlib: [ on ] # HAVE_ZLIB_SUPPORT lzma: [ on ] # HAVE_LZMA_SUPPORT get_cpuid: [ on ] # HAVE_AUXTRACE_SUPPORT bpf: [ on ] # HAVE_LIBBPF_SUPPORT aio: [ on ] # HAVE_AIO_SUPPORT zstd: [ OFF ] # HAVE_ZSTD_SUPPORT libpfm4: [ OFF ] # HAVE_LIBPFM ããã§ã以äžã®ããã« Linux ã«ãŒãã«ã®ãœãŒã¹ã³ãŒããããŠã³ããŒããã tools/perf ããã«ãããŸãã $ sudo apt install make gcc flex bison pkg-config $ sudo apt install libzstd1 libdwarf-dev libdw-dev binutils-dev libcap-dev libelf-dev libnuma-dev python3 python3-dev python-setuptools libssl-dev libunwind-dev libdwarf-dev zlib1g-dev liblzma-dev libaio-dev libtraceevent-dev debuginfod libpfm4-dev libslang2-dev systemtap-sdt-dev libperl-dev binutils-dev libbabeltrace-dev libiberty-dev libzstd-dev $ curl -O https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.15.tar.xz $ tar xvf linux-5.15.tar.xz $ cd linux-5.15/tools/perf # python3-config ããã±ãŒãžãå©çšããããã« `PYTHON=python3` ãå¿
èŠã§ãã $ make PYTHON=python3 libpython ãªãã·ã§ã³ãæå¹åã§ããŸããã $ ./perf version --build-options perf version 5.15.0 dwarf: [ on ] # HAVE_DWARF_SUPPORT dwarf_getlocations: [ on ] # HAVE_DWARF_GETLOCATIONS_SUPPORT glibc: [ on ] # HAVE_GLIBC_SUPPORT syscall_table: [ on ] # HAVE_SYSCALL_TABLE_SUPPORT libbfd: [ on ] # HAVE_LIBBFD_SUPPORT libelf: [ on ] # HAVE_LIBELF_SUPPORT libnuma: [ on ] # HAVE_LIBNUMA_SUPPORT numa_num_possible_cpus: [ on ] # HAVE_LIBNUMA_SUPPORT libperl: [ on ] # HAVE_LIBPERL_SUPPORT libpython: [ on ] # HAVE_LIBPYTHON_SUPPORT libslang: [ on ] # HAVE_SLANG_SUPPORT libcrypto: [ OFF ] # HAVE_LIBCRYPTO_SUPPORT libunwind: [ on ] # HAVE_LIBUNWIND_SUPPORT libdw-dwarf-unwind: [ on ] # HAVE_DWARF_SUPPORT zlib: [ on ] # HAVE_ZLIB_SUPPORT lzma: [ on ] # HAVE_LZMA_SUPPORT get_cpuid: [ on ] # HAVE_AUXTRACE_SUPPORT bpf: [ on ] # HAVE_LIBBPF_SUPPORT aio: [ on ] # HAVE_AIO_SUPPORT zstd: [ on ] # HAVE_ZSTD_SUPPORT libpfm4: [ OFF ] # HAVE_LIBPFM Python ã³ãŒããæžã æºåãæŽã£ãã®ã§ããããã CPU ãã¬ãŒã¹ãè§£æãã Python ã¹ã¯ãªãããèšè¿°ããŸãã 詳ãã解説ããµã³ãã«ã³ãŒãã perf-script-python(1) ã«ããã®ã§ã man ãåèã«äœæ¥ããŸãã ãŸãã¯ãã³ãã¬ãŒããçæããŸãã ãã³ãã¬ãŒã㯠perf script -g ã§çæã§ããŸããã perf record -e ã§æå®ããã€ãã³ãããšã«é¢æ°ãå®è£
ããã®ã§ã perf.data ãæž¡ãå¿
èŠããããŸãã $ ~/linux-5.15-build/tools/perf/perf script -i /path/to/perf.data -g python generated Python script: perf-script.py çæããããã¡ã€ã«ãã¿ããšã以äžã®ããã«ãªã£ãŠããŸãã # $ cat perf-script.py # (snip) def trace_begin (): print ( "in trace_begin" ) def trace_end (): print ( "in trace_end" ) def kvm__kvm_exit (event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, exit_reason, guest_rip, isa, info1, info2, intr_info, error_code, vcpu_id, perf_sample_dict): print_header(event_name, common_cpu, common_secs, common_nsecs, common_pid, common_comm) print ( "exit_reason=%s, guest_rip=%u, isa=%u, " \ "info1=%u, info2=%u, intr_info=%u, " \ "error_code=%u, vcpu_id=%u" % \ (flag_str( "kvm__kvm_exit" , "exit_reason" , exit_reason), guest_rip, isa, info1, info2, intr_info, error_code, vcpu_id)) print ( 'Sample: {' +get_dict_as_string(perf_sample_dict[ 'sample' ], ', ' )+ '}' ) for node in common_callchain: if 'sym' in node: print ( " \t [%x] %s" % (node[ 'ip' ], node[ 'sym' ][ 'name' ])) else : print ( " [%x]" % (node[ 'ip' ])) print () def kvm__kvm_entry (event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, vcpu_id, rip, perf_sample_dict): print_header(event_name, common_cpu, common_secs, common_nsecs, common_pid, common_comm) # (snip) print () def trace_unhandled (event_name, context, event_fields_dict, perf_sample_dict): print (get_dict_as_string(event_fields_dict)) print ( 'Sample: {' +get_dict_as_string(perf_sample_dict[ 'sample' ], ', ' )+ '}' ) # (snip) perf record -e ã§æå®ããã€ãã³ãåããšã«é¢æ°ãå®çŸ©ãããŠããããšãšãã€ãã³ãã®ä»å æ
å ±ãåŒæ°ãšããŠæž¡ãããããšãããããŸãã KVM Exit/Entry ã®ã¬ã€ãã³ã·ãèšæž¬ããã«ã¯ãã°ããŒãã«ãªããŒã¿æ§é ãçšæãã kvm__kvm_exit ã«æž¡ãããã€ãã³ãçºçæå»ãã kvm__kvm_entry ã«æž¡ãããã€ãã³ãçºçæå»ãåŒãã°ããããã§ãã ä»åã®äŸã§ã¯ã vCPU ããšã«å°çšã®ç©ç CPU ã³ã¢ãå²ãåœãŠãŠããã®ã§ã common_cpu ã䜿ãã° kvm__kvm_exit ã€ãã³ããš kvm__kvm_exit ã€ãã³ãã察å¿ã¥ããããšãã§ããŸãã æåŸã« kvm__kvm_exit ãçºçãããšãã®æå»ã last_kvm_exit_at ã«ããã®ãšãã® Reason ã last_kvm_exit_reason ãžä¿åããããã«ããŸãã ãããã®æ
å ±ãã³ã¢ããšã«ä¿åããããã defaultdict ã䜿ã£ãŠã³ã¢çªå·ãããŒãšããèŸæžã䜿ããŸãã kvm__entry ã€ãã³ãã®çºçæå»ãã last_kvm_exit_at ã«ä¿åãããæå»ãåŒããã¬ã€ãã³ã·ãšããŠéèšããŸãã ã€ãã³ãã®çºçæå»ã¯æŽæ°éšå common_secs ãšå°æ°éšå common_nsecs ã«åããŠæž¡ãããããšã«æ³šæããŸãã ããããçµåããŠã€ãã³ãã®çºçæå»ãèšç®ããã«ã¯ Util ããã±ãŒãžã® nsecs 颿°ã䜿ããæ¬¡ã®ããã«ããŸãã nsecs(common_secs, common_nsecs) exit_reason ã¯æŽæ°ã§æž¡ãããã®ã§ãæåå衚çŸã«å¯Ÿå¿ã¥ããã«ã¯ arch/x86/include/uapi/asm/vmx.h ãåèã«ãããšããã§ãã æçµçãªã³ãŒãã¯ä»¥äžã®ããã«ãªããŸããã # $ cat perf-script-kvm-exit-entry.py # perf script event handlers, generated by perf script -g python # Licensed under the terms of the GNU GPL License version 2 # The common_* event handler fields are the most useful fields common to # all events. They don't necessarily correspond to the 'common_*' fields # in the format files. Those fields not available as handler params can # be retrieved using Python functions of the form common_*(context). # See the perf-script-python Documentation for the list of available functions. from __future__ import print_function import os import sys sys.path.append(os.environ[ 'PERF_EXEC_PATH' ] + \ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace' ) sys.path.append( '/home/openstack/work_ksugiura/linux-5.15-build/tools/perf/scripts/python/Perf-Trace-Util/lib/Perf/Trace' ) from perf_trace_context import * from Core import * from Util import nsecs import numpy as np from collections import defaultdict ms = 1000 * 1000 exit_reason = ( "EXCEPTION_NMI" , "EXTERNAL_INTERRUPT" , "TRIPLE_FAULT" , "INIT_SIGNAL" , "N/A" , "N/A" , "N/A" , "INTERRUPT_WINDOW" , "NMI_WINDOW" , "TASK_SWITCH" , "CPUID" , "N/A" , "HLT" , "INVD" , "INVLPG" , "RDPMC" , "RDTSC" , "N/A" , "VMCALL" , "VMCLEAR" , "VMLAUNCH" , "VMPTRLD" , "VMPTRST" , "VMREAD" , "VMRESUME" , "VMWRITE" , "VMOFF" , "VMON" , "CR_ACCESS" , "DR_ACCESS" , "IO_INSTRUCTION" , "MSR_READ" , "MSR_WRITE" , "INVALID_STATE" , "MSR_LOAD_FAIL" , "N/A" , "MWAIT_INSTRUCTION" , "MONITOR_TRAP_FLAG" , "N/A" , "MONITOR_INSTRUCTION" , "PAUSE_INSTRUCTION" , "MCE_DURING_VMENTRY" , "N/A" , "TPR_BELOW_THRESHOLD" , "APIC_ACCESS" , "EOI_INDUCED" , "GDTR_IDTR" , "LDTR_TR" , "EPT_VIOLATION" , "EPT_MISCONFIG" , "INVEPT" , "RDTSCP" , "PREEMPTION_TIMER" , "INVVPID" , "WBINVD" , "XSETBV" , "APIC_WRITE" , "RDRAND" , "INVPCID" , "VMFUNC" , "ENCLS" , "RDSEED" , "PML_FULL" , "XSAVES" , "XRSTORS" , "N/A" , "N/A" , "UMWAIT" , "TPAUSE" "N/A" , "N/A" , "N/A" , "N/A" , "N/A" , "BUS_LOCK" , "NOTIFY" , ) def trace_begin (): global last_kvm_exit_at last_kvm_exit_at = defaultdict( lambda : 0 ) global last_kvm_exit_reason last_kvm_exit_reason = defaultdict( lambda : - 1 ) global kvm_entry_latencies kvm_entry_latencies = defaultdict( lambda : defaultdict( lambda : [])) print ( "in trace_begin" ) def trace_end (): global last_kvm_exit_at global kvm_entry_latencies print ( "in trace_end" ) print ( "kvm_entry_latencies" ) for core, reason_latencies in kvm_entry_latencies.items(): print ( "Core: " , core) for reason, latencies in reason_latencies.items(): print ( "Reason: [%d] %s" %(reason, exit_reason[reason])) max_latency = max (latencies) bins = [ 2 **i for i in range ( int (np.log2(max_latency)) + 2 )] hist, bins = np.histogram(latencies, bins=bins) for i in range ( len (hist)): print ( "[%16d, %16d) %d" % (bins[i], bins[i+ 1 ], hist[i])) def kvm__kvm_exit (event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, exit_reason, guest_rip, isa, info1, info2, intr_info, error_code, vcpu_id, perf_sample_dict): global last_kvm_exit_at global last_kvm_exit_reason global kvm_entry_latencies last_kvm_exit_at[common_cpu] = nsecs(common_secs, common_nsecs) last_kvm_exit_reason[common_cpu] = exit_reason def kvm__kvm_entry (event_name, context, common_cpu, common_secs, common_nsecs, common_pid, common_comm, common_callchain, vcpu_id, rip, perf_sample_dict): global last_kvm_exit_at global last_kvm_exit_reason global kvm_entry_latencies if last_kvm_exit_at[common_cpu] > 0 : latency = nsecs(common_secs, common_nsecs) - last_kvm_exit_at[common_cpu] reason = last_kvm_exit_reason[common_cpu] if latency > 1 * ms and reason != 12 : print ( "exit-entry: [%d]: [%d.%d]: reason: %s, %d" % (common_cpu, common_secs, common_nsecs, exit_reason[reason], latency)) kvm_entry_latencies[common_cpu][reason].append(latency) last_kvm_exit_at[common_cpu] = 0 def trace_unhandled (event_name, context, event_fields_dict, perf_sample_dict): print (get_dict_as_string(event_fields_dict)) print ( 'Sample: {' +get_dict_as_string(perf_sample_dict[ 'sample' ], ', ' )+ '}' ) def print_header (event_name, cpu, secs, nsecs, pid, comm): print ( "%-20s %5u %05u.%09u %8u %-20s " % \ (event_name, cpu, secs, nsecs, pid, comm), end= "" ) def get_dict_as_string (a_dict, delimiter= ' ' ): return delimiter.join([ '%s=%s' %(k, str (v)) for k,v in sorted (a_dict.items())]) ç¬èªã¹ã¯ãªãããçšã㊠perf.data ãéèšãã ã§ã¯ãäœæããã¹ã¯ãªãã perf-script-kvm-exit-entry.py ãçšã㊠KVM Exit/Entry ã®ã¬ã€ãã³ã·ãè§£æããŠã¿ãŸãã Exit Reason ããšãã³ã¢ããšã«ãã¹ãã°ã©ã ãäœæãããšä»¥äžã®ããã«ãªããŸããã åºåã¯éåžžã«é·ãã®ã§ãäžéšã ãæ²èŒããŸãã $ perf script -i /path/to/perf.data -s /path/to/perf-script-kvm-exit-entry.py exit-entry: [126]: [151856.170064250]: reason: EXTERNAL_INTERRUPT, 1522602 exit-entry: [125]: [151915.737653830]: reason: EXTERNAL_INTERRUPT, 1282485 exit-entry: [124]: [152201.81772565]: reason: EXTERNAL_INTERRUPT, 2198819 exit-entry: [127]: [152672.999539636]: reason: EXTERNAL_INTERRUPT, 1341486 exit-entry: [124]: [152812.995271815]: reason: EXTERNAL_INTERRUPT, 1475909 Core: 124 Reason: [32] MSR_WRITE [ 1, 2) 0 [ 2, 4) 0 [ 4, 8) 0 [ 8, 16) 0 [ 16, 32) 0 [ 32, 64) 0 [ 64, 128) 0 [ 128, 256) 17842 [ 256, 512) 1884223 [ 512, 1024) 2344850 [ 1024, 2048) 2567959 [ 2048, 4096) 653205 [ 4096, 8192) 81909 [ 8192, 16384) 1771 [ 16384, 32768) 620 [ 32768, 65536) 5 [ 65536, 131072) 0 [ 131072, 262144) 0 [ 262144, 524288) 1 [ 524288, 1048576) 0 [ 1048576, 2097152) 1 Reason: [1] EXTERNAL_INTERRUPT [ 1, 2) 0 [ 2, 4) 0 [ 4, 8) 0 [ 8, 16) 0 [ 16, 32) 0 [ 32, 64) 0 [ 64, 128) 0 [ 128, 256) 0 [ 256, 512) 0 [ 512, 1024) 112 [ 1024, 2048) 390 [ 2048, 4096) 7145 [ 4096, 8192) 13116 [ 8192, 16384) 69835 [ 16384, 32768) 23903 [ 32768, 65536) 44 [ 65536, 131072) 20 [ 131072, 262144) 1 [ 262144, 524288) 1 [ 524288, 1048576) 3 [ 1048576, 2097152) 11 [ 2097152, 4194304) 1 Reason: [48] EPT_VIOLATION [ 1, 2) 0 [ 2, 4) 0 [ 4, 8) 0 [ 8, 16) 0 [ 16, 32) 0 [ 32, 64) 0 [ 64, 128) 0 [ 128, 256) 0 [ 256, 512) 0 [ 512, 1024) 37 [ 1024, 2048) 286 [ 2048, 4096) 940 [ 4096, 8192) 848 [ 8192, 16384) 223 [ 16384, 32768) 785 [ 32768, 65536) 17 [ 65536, 131072) 1 [ 131072, 262144) 6 [ 262144, 524288) 11 [ 524288, 1048576) 4 å
šäœãçºããŠã¿ããšã EXTERNAL_INTERRUPT ã¯é »åºŠãé«ãã¬ã€ãã³ã·ã倧ããåŸåã«ããããšãããããŸããã EPT_VIOLATION ã®é »åºŠã¯äœããã®ã®ãçºçãããšãã®ããã«ãã£ã¯å€§ããããã§ãã ä»åã®å®éšã®ã¿ããäœããå°ãåºãã®ã¯é£ããã§ããããã¹ã OS ã®æ§æããã²ã¹ã OS ã®çš®é¡ãã²ã¹ã OS ã®ã¯ãŒã¯ããŒãã倿Žãããšãã®å·®åã«çç®ãããšãææçŸ©ãªçµæãåŸããããããããŸããã ãŸãšã perf ã«ã¯ç¬èªã® Python ã¹ã¯ãªãããçšã㊠CPU ãã¬ãŒã¹ãéèšã§ããæ©èœããããŸããããã©ã«ãã®è¡šç€ºãå€ããããšãããç¬èªã®éèšåŠçãæžããããšãã«æçšã§ãã kvm:kvm_exit ãš kvm:kvm_entry ãšãããã¬ãŒã¹ãã€ã³ãã䜿ãããšã§ã KVM Exit / Entry ã®ã¬ã€ãã³ã·ãéèšãããã¹ãã°ã©ã ãšããŠè¡šç€ºããŸããã åèæç® 第5åãx86ããã»ããµã®ä»®æ³åæ¯æŽæ©èœIntel VT ïŒ AMD-V | gihyo.jp Linux perf Examples perf-script-python(1)