“perf_event_open”系统调用通过选项“PERF_RECORD_SAMPLE”返回的结构中的“id”和“stream_id”有啥区别?
Posted
技术标签:
【中文标题】“perf_event_open”系统调用通过选项“PERF_RECORD_SAMPLE”返回的结构中的“id”和“stream_id”有啥区别?【英文标题】:Whats the difference between "id" and "stream_id" in the structure returned with the option "PERF_RECORD_SAMPLE" by the "perf_event_open" syscall?“perf_event_open”系统调用通过选项“PERF_RECORD_SAMPLE”返回的结构中的“id”和“stream_id”有什么区别? 【发布时间】:2020-02-20 09:39:15 【问题描述】:我正在尝试使用perf_event_open
系统调用编写一段代码。但我不明白我的内存映射中返回的结构中id
和stream_id
字段之间的真正区别。
这个结构是这样的(来自perf_event_open
的手册页):
struct
struct perf_event_header header;
u64 sample_id; /* if PERF_SAMPLE_IDENTIFIER */
u64 ip; /* if PERF_SAMPLE_IP */
u32 pid, tid; /* if PERF_SAMPLE_TID */
u64 time; /* if PERF_SAMPLE_TIME */
u64 addr; /* if PERF_SAMPLE_ADDR */
u64 id; /* if PERF_SAMPLE_ID */
u64 stream_id; /* if PERF_SAMPLE_STREAM_ID */
u32 cpu, res; /* if PERF_SAMPLE_CPU */
u64 period; /* if PERF_SAMPLE_PERIOD */
struct read_format v;
/* if PERF_SAMPLE_READ */
u64 nr; /* if PERF_SAMPLE_CALLCHAIN */
u64 ips[nr]; /* if PERF_SAMPLE_CALLCHAIN */
u32 size; /* if PERF_SAMPLE_RAW */
char data[size]; /* if PERF_SAMPLE_RAW */
u64 bnr; /* if PERF_SAMPLE_BRANCH_STACK */
struct perf_branch_entry lbr[bnr];
/* if PERF_SAMPLE_BRANCH_STACK */
u64 abi; /* if PERF_SAMPLE_REGS_USER */
u64 regs[weight(mask)];
/* if PERF_SAMPLE_REGS_USER */
u64 size; /* if PERF_SAMPLE_STACK_USER */
char data[size]; /* if PERF_SAMPLE_STACK_USER */
u64 dyn_size; /* if PERF_SAMPLE_STACK_USER &&
size != 0 */
u64 weight; /* if PERF_SAMPLE_WEIGHT */
u64 data_src; /* if PERF_SAMPLE_DATA_SRC */
u64 transaction; /* if PERF_SAMPLE_TRANSACTION */
u64 abi; /* if PERF_SAMPLE_REGS_INTR */
u64 regs[weight(mask)];
/* if PERF_SAMPLE_REGS_INTR */
;
手册页给了我这个解释:
id If PERF_SAMPLE_ID is enabled, a 64-bit unique ID is included. If the event is a member of an event group, the group leader ID is returned. This ID is the same as the one returned by PERF_FORMAT_ID.
stream_id If PERF_SAMPLE_STREAM_ID is enabled, a 64-bit unique ID is included. Unlike PERF_SAMPLE_ID the actual ID is returned, not the group leader. This ID is the same as the one returned by PERF_FORMAT_ID.
但问题就在这里:文档似乎不连贯。
我错过了什么吗?
感谢您的关注。
【问题讨论】:
The man7.org has a different description 不,看这个位置的描述是一样的:MMAP Layout -> PERF_RECORD_SAMPLE -> id 我想你没看对地方。 看来,上面似乎提供了不同的文字来描述PERF_SAMPLE_ID
和PERF_SAMPLE_STREAM_ID
的含义
嗯.. 如果我理解,你告诉我一个给我一个任意唯一的 ID,这对于发泄组是相同的,另一个只给我事件负责人的 ID?我说的对吗?
【参考方案1】:
PERF_SAMPLE_STREAM_ID
存在的主要原因是为了维护继承计数器的事件 ID。而PERF_SAMPLE_ID
将包含父计数器的事件 ID。 (如果有任何父子关系)。
继承的计数器是分配给子任务的计数器,它们源自正在分析的父任务(除非标志 --no-inherit
被传递给 perf
命令)。
这个细节在这个旧的commit中有描述。
看最新源码here,
if (sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER))
data->id = primary_event_id(event);
if (sample_type & PERF_SAMPLE_STREAM_ID)
data->stream_id = event->id;
....
/*
* If we inherit events we want to return the parent event id
* to userspace.
*/
static u64 primary_event_id(struct perf_event *event)
u64 id = event->id;
if (event->parent)
id = event->parent->id;
return id;
上面的sn-p代码清楚地区分了结构的两个成员。这与事件是否为组长无关。
另外,需要注意的是,组中的所有事件也将计算/使用这个primary_event_id
函数。这可以看到here。因此,组中的所有事件都将包含组长的 id。
【讨论】:
很抱歉,我不懂sn-p。什么是“perf_event”结构?它的“父”成员是什么? 我也不明白你对PERF_SAMPLE_STREAM_ID
和PERF_SAMPLE_ID
的解释。如果你有时间,我想一个例子会更清楚。以上是关于“perf_event_open”系统调用通过选项“PERF_RECORD_SAMPLE”返回的结构中的“id”和“stream_id”有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
Linux内核 eBPF基础:perf基础perf_event_open系统调用内核源码分析
如何从 perf_event_open 中的环形缓冲区中检索调用链以获取 PERF_RECORD_SWITCH?