я использовал cpuset
для защиты некоторых процессоров для исключительного использования некоторыми потоками реального времени.
Отображение конфигурации процессора с помощью тестового приложения RealtimeTest1
running и его задачи переместились в cpusets:
$ cset set --list -r
cset:
Name CPUs-X MEMs-X Tasks Subs Path
------------ ---------- - ------- - ----- ---- ----------
root 0-23 y 0-1 y 279 2 /
system 0,2,4,6,8,10 n 0 n 202 0 /system
shield 1,3,5,7,9,11 n 1 n 0 2 /shield
RealtimeTest1 1,3,5,7 n 1 n 0 4 /shield/RealtimeTest1
thread1 3 n 1 n 1 0 /shield/RealtimeTest1/thread1
thread2 5 n 1 n 1 0 /shield/RealtimeTest1/thread2
main 1 n 1 n 1 0 /shield/RealtimeTest1/main
Я могу допросить cpuset
файловая система, чтобы показать, что мои задачи якобы закреплен на запрашиваемом мной процессоре:
/cpusets/shield/RealtimeTest1 $ for i in `find -name tasks`; do echo $i; cat $i; echo "------------"; done
./thread1/tasks
17651
------------
./main/tasks
17649
------------
./thread2/tasks
17654
------------
Далее, если я использую sched_getaffinity
, он сообщает, что cpuset
делает - этот поток1 находится на процессоре 3, а поток2 - на процессоре 5.
Однако, если я убегу top -p 17649 -H
с участием f,j
поднять last used cpu
, это показывает, что поток 1 работает на процессоре потока 2, а основной поток работает на процессоре в system
процессор
(Обратите внимание, что поток 17654 работает с FIFO, поэтому поток 17651 заблокирован)
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ P COMMAND
17654 root -2 0 54080 35m 7064 R 100 0.4 5:00.77 3 RealtimeTest
17649 root 20 0 54080 35m 7064 S 0 0.4 0:00.05 2 RealtimeTest
17651 root 20 0 54080 35m 7064 R 0 0.4 0:00.00 3 RealtimeTest
Кроме того, глядя на /proc/17649/task
найти last_cpu
каждая из его задач выполнялась:
/proc/17649/task $ for i in `ls -1`; do cat $i/stat | awk '{print $1 " is on " $(NF - 5)}'; done
17649 is on 2
17651 is on 3
17654 is on 3
Так cpuset
и sched_getaffinity
сообщает одно, а реальность - другое
Я бы сказал, что cpuset
не работает?
Конфигурация моей машины:
$ cat /etc/SuSE-release
SUSE Linux Enterprise Server 11 (x86_64)
VERSION = 11
PATCHLEVEL = 1
$ uname -a
Linux foobar 2.6.32.12-0.7-default #1 SMP 2010-05-20 11:14:20 +0200 x86_64 x86_64 x86_64 GNU/Linux
Обновить:
Дополнительно разбираю /proc/pid/task/tid/stat
и звонит sched_getcpu()
до и после cset --move
звоните, и я также делаю sched_yield()
после закрепления, чтобы попытаться переместить нить ...
Это пример вывода:
13:12:56 INFO before pinning thread 17508 reports lastCpu=0, currCpu=1
13:12:56 INFO pinning thread 17508 to cpu 3 (/shield/RealtimeTest1/thread1)
13:12:56 INFO SetAffinity cset response:
cset: moving following pidspec: 17508
cset: moving 1 userspace tasks to /shield/RealtimeTest1/thread1
cset: done
13:12:56 INFO after pinning thread 17508 reports lastCpu=0, currCpu=1
13:12:56 INFO after sch_yld thread 17508 reports lastCpu=0, currCpu=1
Таким образом, поток не переходит к своему новому процессору сразу или даже после sched_yield
Может быть, это проблема SLES 11 / SP 1?
Я повторил тесты на SLES 11 / SP 2 коробка, и крепление работает.
Поэтому я отмечу это как ответ, а именно: Это проблема, связанная с SP 1