-
perf_event_open
은 성능 모니터링을 설정하기 위한 시스템 콜이다. -
perf_event_open()
는 성능 정보를 측정할 수 있는 파일 디스크립터(FD)를 반환한다. 각 FD는 측정되는 하나의 이벤트를 의미한다. -
각 이벤트는
ioctl(2)
와prctl(2)
를 통해 활성화, 비활성화될 수 있다. 이벤트가 비활성화되면 측정을 멈추지만 카운트 값은 그대로 유지한다. -
이벤트는 카운팅(counting) 타입과 샘플링(sampled) 타입 두 형태로 제공된다.
- 카운팅 이벤트는 발생하는 이벤트의 총 수를 세기 위해 사용된다. 카운팅 이벤트 결과는 일반적으로
read(2)
호출로 수집된다. - 샘플링 이벤트는 측정값을 주기적으로 버퍼에 기록하고,
mmap(2)
를 통해 버퍼에 액세스할 수 있다.
- 카운팅 이벤트는 발생하는 이벤트의 총 수를 세기 위해 사용된다. 카운팅 이벤트 결과는 일반적으로
Arguments
pid와 cpu
- pid 인자로 측정할 프로세스를 지정할 수 있다.
pid == 0
: 현재 프로세스를 측정pid > 0
: 해당 pid의 프로세스를 측정pid == -1
: 모든 프로세스 측정
CAP_PERFMON
,CAP_SYS_ADMIN
권한을 가지고 있거나/proc/sys/kernel/perf_event_paranoid
값이 1 이하인 경우에만 실행할 수 있다.
- cpu 인자로 측정할 CPU를 지정할 수 있다.
cpu >= 0
: 지정된 CPU를 측정cpu == -1
: 모든 CPU에서 이벤트 측정
- pid와 cpu 인자 두 개가 모두 -1인 경우 에러가 발생한다.
group_fd
- 이벤트 그룹을 생성할 수 있도록 하는 인자이다.
- 이벤트 그룹에서는 하나의 이벤트가 그룹의 리더가 된다. roup_fd를 -1로 지정해서 리더를 먼저 생성할 수 있고, 나머지 그룹 구성원을 생성할 때는 그룹 리더의 fd를
group_fd
로 지정한다. (단일 이벤트는 멤버가 1명뿐인 그룹으로 간주된다.) - 이벤트 그룹은 CPU에 하나의 단위로 스케줄링된다. 멤버 이벤트의 값이 동일한 명령어에 대한 이벤트를 계산했기 때문에 서로 의미 있게 비교, 추가, 계산할 수 있다는 것을 의미한다.
flags
-
flag 인자는 다음 중 하나의 값을 가진다.
-
PERF_FLAG_FD_CLOEXEC
이 flag는 생성된 이벤트 FD가 execve(2)를 통해 닫히도록 한다. (이걸 close-on-exec라고 부른다.) fcntl(2)로도 설정할 수 있지만, 다른 스레드가fork(2)
와execve(2)
를 호출해서 생길 수 있는 경합 가능성을 피하기 위해 유용하다. -
PERF_FLAG_FD_NO_GROUP
이 flag는group_fd
인자를 무시하도록 한다. -
PERF_FLAG_FD_OUTPUT
(Linux 2.6.35부터 에러 발생)
이벤트 수집 결과가group_fd
에 지정된 이벤트의 mmap 버퍼에 같이 저장되도록 한다. -
PERF_FLAG_PID_CGROUP
(Linux 2.6.39부터 사용 가능)
컨테이너별 시스템 전역 모니터링을 활성화한다. 이 모드에서 이벤트는 스레드가 지정된 컨테이너(cgroup)에 속할 경우에만 측정된다.
cgroup은 cgroupfs 파일 시스템의 디렉터리에서 열린 FD를 통해 식별된다. 예를 들어 모니터링할 컨트롤 그룹이 test이고, cgroupfs가/dev/cgroup
에 마운트되어 있다면/dev/cgroup/test
에서 열린 FD를 pid 매개변수로 전달해야 한다.
cgroup 모니터링은 시스템 전체 이벤트에만 사용할 수 있으며 추가 권한이 필요할 수 있다.
perf_event_attr
perf_event_attr
구조체로 되어있는 인자는 생성될 이벤트에 대한 구체적인 정보를 전달하기 위해 사용한다.
각 필드에 대한 자세한 설명은 다음과 같다.
-
type
: 추적할 이벤트의 타입을 나타낸다. 상세한 이벤트는config
인자의 값으로 결정된다. 타입은 아래 값 중 하나이다.PERF_TYPE_HARDWARE
: 커널에서 제공하는 제네럴한 하드웨어 이벤트 중 하나를 나타낸다.PERF_TYPE_SOFTWARE
: kernel의 software로 정의된 이벤트를 나타낸다.PERF_TYPE_TRACEPOINT
: kernel의 tracepoint 인프라에서 제공되는 tracepoint를 나타낸다.PERF_TYPE_HW_CACHE
: 하드웨어 캐시 이벤트를 나타낸다. config 필드 정의에서 설명되는 특수 인코딩을 가지고 있다.PERF_TYPE_RAW
: config 필드에서 명시되는 raw 구현을 나타낸다.PERF_TYPE_BREAKPOINT
: CPU로부터 제공되는 hardware breakpoint를 나타낸다. breakpoint의 주소로부터 읽기/쓰기 뿐만 아니라 명령어 주소 실행 또한 가능하다.kprobe
과uprobe
: 이 두가지의 동적 PMU는perf_event_open
로 생성된 FD에 대해서 kprobe/uprobe를 생성하고 등록한다.
-
size
: perf_event_attr 구조체의 크기 값을 넣어주면 된다.sizeof(struct perf_event_attr)
를 사용하여 구할 수 있다. -
config
: 타입 필드와 함께 원하는 이벤트를 지정한다. config1, config2 필드는 이벤트를 지정하기 위해 64비트만으로는 충분하지 않은 경우 사용된다. 이 필드들의 인코딩은 이벤트에 따라 다르다. -
kprobe_func
,uprobe_path
,kprobe_addr
,probe_offset
: kprobe/uprobe 타입을 쓰는 경우 그에 대한 -
sample_period
,sample_freq
: 샘플링 주기를 지정하기 위해 사용한다. 샘플링 기간 또는 주기를 지정할 수 있다. -
sample_type
: 샘플링 할 데이터의 타입을 지정한다.
PERF_SAMPLE_IP, PERF_SAMPLE_TID, PERF_SAMPLE_TIME, PERF_SAMPLE_ADDR, PERF_SAMPLE_READ, PERF_SAMPLE_CALLCHAIN, PERF_SAMPLE_ID, PERF_SAMPLE_CPU, PERF_SAMPLE_STACK_USER, PERF_SAMPLE_PHYS_ADDR 등이 있다. -
inherit
: 해당 작업의 하위 작업의 이벤트도 함께 카운트할지 여부를 지정한다. 기존 하위 작업에는 적용되지 않고 새로운 하위 작업에만 적용된다. -
pinned
: 카운터를 한 CPU에서 실행되도록 할지 여부를 지정한다. 하드웨어 카운터, 그룹 리더에만 적용된다. 카운터가 고정된 CPU에 놓일 수 없는 경우(예: 하드웨어 카운터가 충분하지 않거나 다른 이벤트와의 충돌이 있는 경우), 카운터는 ‘에러’ 상태가 되어 파일의 끝(즉, read(2)가 0을 반환)을 반환하며, 나중에 카운터가 활성화되거나 비활성화될 때까지 이 상태가 유지된다. -
exclusive
: 이 카운터 그룹이 CPU에 있을 때 CPU의 카운터를 사용하는 유일한 그룹이도록 강제할지 여부를 지정한다. 이 기능을 사용하면 다른 하드웨어 카운터를 방해하지 않도록 도와주는 PMU 기능을 사용하도록 할 수 있다.
참고