"perf_event_paranoid == 1" 实际上对 x86 perf 有什么限制?

33
新版本的Linux内核有一个sysfs可调参数/proc/sys/kernel/perf_event_paranoid,允许用户为非root用户调整perf_events的可用功能,更高的数字表示更安全(相应地提供更少的功能):
kernel documenation中我们可以看到各个值的行为:

perf_event_paranoid:

控制非特权用户(没有CAP_SYS_ADMIN权限)使用性能事件系统的使用。默认值为2。

-1:允许所有用户(几乎)使用所有事件,在没有CAP_IPC_LOCK的情况下忽略perf_event_mlock_kb的mlock限制

>=0:禁止没有CAP_SYS_ADMIN权限的用户使用ftrace函数跟踪点;禁止没有CAP_SYS_ADMIN权限的用户访问原始跟踪点

>=1:禁止没有CAP_SYS_ADMIN权限的用户访问CPU事件

>=2:禁止没有CAP_SYS_ADMIN权限的用户对内核进行分析

我在我的perf_event_paranoid文件中设置了1,这应该是“禁止CPU事件访问”——但这究竟意味着什么?
简单的阅读会暗示无法访问CPU性能计数器事件(如Intel PMU事件),但似乎我可以正常访问这些事件。例如:
$ perf stat sleep 1

 Performance counter stats for 'sleep 1':

          0.408734      task-clock (msec)         #    0.000 CPUs utilized          
                 1      context-switches          #    0.002 M/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
                57      page-faults               #    0.139 M/sec                  
         1,050,362      cycles                    #    2.570 GHz                    
           769,135      instructions              #    0.73  insn per cycle         
           152,661      branches                  #  373.497 M/sec                  
             6,942      branch-misses             #    4.55% of all branches        

       1.000830821 seconds time elapsed

在这里,许多事件都是CPU PMU事件(cyclesinstructionsbranchesbranch-missescache-misses)。

如果这些不是指的CPU事件,那么它们是什么?


随机猜测:限制非通用uarch特定事件,如uops_issued.any - Peter Cordes
@PeterCordes - 不对,ocperf stat -e uops_issued.any sleep 1 也可以。 - BeeOnRope
1
另一个表明这不是普通PMU事件的迹象是,值为2会阻止内核分析,实际上任何内核CPU事件(使用:k后缀)在使用2时都返回零。由于2应该比1更安全,这意味着用户模式事件在1和2中都被允许,并且内核模式事件在1中被允许(确实,在使用1时,:k有效),因此“CPU事件”必须意味着比普通PMU事件更狭窄或不同的东西... - BeeOnRope
2
新的猜测:它是用于系统范围的分析,或者是整个CPU而不是我的进程。您可以使用“1”对由自己的进程调用的内核代码进行分析,但可能会尝试防御直接计时其他用户的进程,仅留下超线程计时侧信道。 - Peter Cordes
4
价值为“3”的选项在2013年被提出:https://lkml.org/lkml/2016/1/11/587 “security,perf: Allow further restriction of perf_event_open”。此选项已于2009年添加,具体详见https://github.com/torvalds/linux/commit/0764771dab80d7b84b9a271bee7f1b21a04a3f0c和https://github.com/torvalds/linux/commit/0fbdea19e9394a5cb5f2f5081b028c50b558910a。我们应该查看LKML上的补丁以获取更多评论。 - osgx
1个回答

13
在这种情况下,CPU 事件 指的是监视每个 CPU 的事件,而不是每个任务。对于 perf 工具,这限制了使用。
-C, --cpu=
    Count only on the list of CPUs provided. Multiple CPUs can be provided as a comma-separated list with no space: 0,1.
    Ranges of CPUs are specified with -: 0-2. In per-thread mode, this option is ignored. The -a option is still necessary
    to activate system-wide monitoring. Default is to count on all CPUs.

-a, --all-cpus
    system-wide collection from all CPUs (default if no target is specified)

对于perf_event_open,考虑以下情况:

pid == -1 and cpu >= 0
       This measures all processes/threads on the specified CPU.  This requires CAP_SYS_ADMIN capability or a /proc/sys/ker‐
       nel/perf_event_paranoid value of less than 1.

这可能是版本特定的,引用的文档来自于4.17。这是另一个相关的问题


3
就目前而言,那个关于paranoid == 2被接受的回答似乎是错误的。当paranoid == 2时,我肯定仍然可以使用perf stat来获取事件,但我无法看到内核PMU计数(仅限用户)。 - BeeOnRope
2
我可以通过查看代码确认此答案是正确的。此外,进行检查sysctl_perf_event_paranoid> 0以确定在P4处理器上是否允许使用线程共享(在逻辑处理器之间共享)事件(正式称为TI事件)。 - Hadi Brais
1
本地测试已确认。 - BeeOnRope

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接