web-dev-qa-db-fra.com

les groupes de contrôle ne fonctionnent pas correctement avec l'application DPDK multicœur

Je souhaite restreindre l'utilisation du processeur d'une application DPDK pour les tests. Après quelques recherches rapides, j'ai trouvé que les groupes de contrôle (cgroups) pouvaient convenir à mes besoins. J'ai donc d'abord installé cgroup-bin.

Sudo apt-get install cgroup-bin

Et puis j'ai créé un sous-système en créant un répertoire sous /sys/fs/cgroup/cpu.

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

Et puis j'écris mes restrictions d'utilisation du CPU à cpu.cfs_period_us et cpu.cfs_quota_us. Par exemple, je souhaite limiter l'utilisation du processeur de mon application DPDK à 30%.

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

Cette approche fonctionne lors de l'exécution d'applications DPDK qui n'utilisent qu'un seul cœur. Par exemple, l'application exemple de transfert de base à 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

Je peux voir dans top que l'utilisation CPU de basicfwd est en fait à 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 

Cependant, lorsque j'exécute une application DPDK qui utilise plus d'un cœur. Le résultat est un peu bizarre. Par exemple, je souhaite exécuter l'exemple d'application 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

Lorsque j'ouvre top, je constate que l'utilisation du processeur de l3fwd est à 130%, au lieu de 30%, ce à quoi je m'attendais.

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  

Il semble que les restrictions ne s'appliquent qu'à un seul noyau. Cependant dans cette page il est dit que les paramètres de quota et de période fonctionnent sur une base CPU

cpu.cfs_quota_us

spécifie la durée totale en microsecondes (µs, représentée ici par "us") pendant laquelle toutes les tâches d'un groupe de contrôle peuvent s'exécuter pendant une période (définie par cpu.cfs_period_us). Dès que les tâches d'un groupe de contrôle utilisent tout le temps spécifié par le quota, elles sont limitées pour le reste du temps spécifié par la période et ne sont pas autorisées à s'exécuter jusqu'à la période suivante. Si les tâches d'un groupe de contrôle doivent pouvoir accéder à un seul processeur pendant 0,2 seconde toutes les 1 seconde, définissez cpu.cfs_quota_us sur 200000 et cpu.cfs_period_us sur 1000000. Notez que les paramètres de quota et de période fonctionnent sur la base du processeur. Pour permettre à un processus d'utiliser pleinement deux CPU, par exemple, définissez cpu.cfs_quota_us sur 200000 et cpu.cfs_period_us sur 100000.

Qu'est-ce que j'oublie ici? Que dois-je faire pour limiter l'utilisation du processeur d'une application DPDK multicœur à moins de 100%?

1
B. Wang

TL; DR:

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

Détails:

Je pense que dans votre cas, l'affectation de pgrep à la tâche doit être améliorée pour fonctionner avec plusieurs ID signalés.

S'il retourne un PID, les choses fonctionnent très bien, mais s'il renvoie plus, l'interface cgroup signale réellement

pgrep: write error: Invalid argument

Vous avez peut-être simplement simplifié votre rapport, mais veuillez vérifier que toutes les tâches se trouvent dans le fichier de tâches cgroups et utiliser une boucle (ou toute autre solution de contournement).

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

Maintenant pour votre cas en particulier, l3fwd a un processus mais trois threads. Ainsi, pgrep ne rapportera que le pid principal, les autres (boucles principales) sont sans restriction. Vous pouvez voir quand vous le générez et le testez via ps axlf contre ps -eLf et la sortie pgrep.

. /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

Vous devez donc prendre pgrep -w et combinez-le avec ce qui précède.

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

Et e voila, de:

  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 

Veuillez toujours voir mon commentaire initial, sauf pour les expériences, veuillez ne pas limiter la consommation du processeur DPDK - alors n'utilisez simplement pas DPDK.

1
Christian Ehrhardt