cgroups 无法与多核 DPDK 应用程序正常工作

cgroups 无法与多核 DPDK 应用程序正常工作

我想限制 DPDK 应用程序的 CPU 使用率以进行测试。经过一番快速搜索,我发现控制组 (cgroups) 可能适合我的需求。所以我首先安装了cgroup-bin

sudo apt-get install cgroup-bin

然后我通过在 下创建一个目录来创建子系统/sys/fs/cgroup/cpu

mkdir -v /sys/fs/cgroup/cpu/dpdk

然后我将对 CPU 使用率的限制写入cpu.cfs_period_uscpu.cfs_quota_us。例如,我想将我的 DPDK 应用程序的 CPU 使用率限制为 30%。

cd /sys/fs/cgroup/cpu/dpdk
echo 1000000 > cpu.cfs_period_us
echo 300000 > cpu.cfs_quota_us

此方法在运行仅使用一个核心的 DPDK 应用程序时有效。例如,examples/skeleton

cd /home/wang/dpdk-17.02/examples/skeleton
make
./build/basicfwd -c 1 -n 2
pgrep basicfwd > /sys/fs/cgroup/cpu/dpdk/tasks

我可以看到topbasicfwd 的 CPU 使用率实际上为 30%。

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                  
3346 root      20   0 4222472   3100   2780 R  30.0  0.0   0:56.35 basicfwd 

但是当我运行使用多个核心的 DPDK 应用程序时,结果有点奇怪。例如,我想在 运行 L3 forward 示例应用程序examples/l3fwd

cd /home/wang/dpdk-17.02/examples/l3fwd
make
./build/l3fwd -l 1,2 -n 2 -- -p 0x3 -P --config="(0,0,1),(1,0,2)" --parse-ptype
pgrep l3fwd > /sys/fs/cgroup/cpu/dpdk/tasks

当我打开时top,我看到的 CPU 使用率l3fwd是 130%,而不是我预期的 30%。

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                  
3404 root      20   0 4305752   5092   2728 R 130.3  0.0   0:25.98 l3fwd  

看起来限制只适用于一个核心。然而这一页它表示配额和期限参数以 CPU 为基础运行

cpu.cfs_quota_us

指定 cgroup 中所有任务在一个周期(由 cpu.cfs_period_us 定义)内可以运行的总时间(以微秒 (µs,此处表示为“us”))。一旦 cgroup 中的任务用完了配额指定的所有时间,它们就会在周期指定的剩余时间内受到限制,并且不允许运行,直到下一个周期。如果 cgroup 中的任务应该能够每 1 秒访问单个 CPU 0.2 秒,请将 cpu.cfs_quota_us 设置为 200000,将 cpu.cfs_period_us 设置为 1000000。请注意,配额和周期参数以 ​​CPU 为基础运行。例如,要允许进程充分利用两个 CPU,请将 cpu.cfs_quota_us 设置为 200000,将 cpu.cfs_period_us 设置为 100000。

我这里遗漏了什么?我应该怎么做才能将多核 DPDK 应用程序的 CPU 使用率限制在 100% 以下?

答案1

总结:

  • 使用for i in $(pgrep -w l3fwd); do echo $i > tasks; done

细节:

我认为在您的情况下,pgrep 的任务分配需要一些改进才能处理报告的多个 ID。

如果它返回一个 PID,那么一切正常,但如果返回更多 PID,cgroup 接口实际上会报告

pgrep: write error: Invalid argument

也许您只是简化了您的报告,但请仔细检查所有任务是否都在 cgroups 任务文件中并使用循环(或任何其他解决方法)。

$ stress-ng -c 4
$ for i in $(pgrep stress); do echo $i > /sys/fs/cgroup/cpu/dpdk/tasks; done
$ cat tasks 
28543
28544
[...]

现在,对于您的具体情况,l3fwd 有一个进程但有三个线程。因此,pgrep只会报告主 pid,其他(主循环)不受限制。您可以在构建和测试它时通过ps axlfvsps -eLfpgrep输出看到。

. /usr/share/dpdk/dpdk-sdk-env.sh
mkdir -p l3fwd
make -C /usr/share/dpdk/examples/l3fwd "O=$(pwd)/l3fwd/"
#  config /etc/dpdk/dpdk.conf and /etc/dpdk/interfaces
service dpdk restart
$(pwd)/l3fwd/l3fwd -l 1,2 --socket-mem 512 -- -p 0x3 -P --config="(0,0,1),(1,0,2)" --parse-ptype

因此,您必须将pgrep -w其与上述内容结合起来。

for i in $(pgrep -w l3fwd); do echo $i > tasks; done

瞧,来自:

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                   
29849 root      20   0  703052   4184   3336 R 200,7  0,0   0:17.36 l3fwd

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                   
29849 root      20   0  703052   4184   3336 R  29,8  0,0   0:34.11 l3fwd 

仍然请参阅我最初的评论,除了实验之外,请不要限制 DPDK CPU 消耗 - 然后不要使用 DPDK。

相关内容