LINUX.ORG.RU

cgroups, systemd и распределение процессора.

 , ,


2

4

Есть 4 меделеных ядра, systemd, 2 пользователя и желание нагрузить комп многопотоком так, чтобы мне это не мешало. nice прекрасно работал давно, когда ядро было единственное и процессы однопоточные. Почитал про cgroups и сделал вывод, что с помошью этой штуки можно рулить приоритетами для многопоточной нагрузки на многоядерных системах, т.е. теоретически это то что надо.

Далее, раз уж системд всё равно есть, раз уж cgroups в него зашит, то и пользоваться нужно им. Вроде как каждой отдельной сессии пользователя выдаётся отдельный slice с собственной долей cpu и в соответствии с этой долей выделяются проценты cpu. Стандартно доли равные, но можно указать в /etc/systemd/system/user-1000.slice.d/50-CPUShares.conf

[Slice]
CPUShares=2048
и в /etc/systemd/system/user-1001.slice.d/50-CPUShares.conf
[Slice]
CPUShares=100
и вторичный пользователь должен получить малую долю cpu если у первичного появится достаточно потоков. Т.е. в теории то что нужно.

Ребут, логин первичного и вторичного пользователей, запуск условного майнера под вторичным, и что то идёт не так: условный майнер отказывается отдавать первичному пользователю более 50% свободного cpu, даже если первичный создаёт 8-10-12 потоков нагрузки.

Почему настройка CPUShares не применяется (механизм работает! но явно с равными шарами!) и предусмотрен ли способ применять изменения без перезагрузки системы? А без перезапуска сессии?

Решал подобную же проблему: огородить ключевой юзерспейс в отдельный cgroup, с гарантированно высокими шарами, а всё остальное по остаточному принципу.

Работать то это работает, но с отзывчивостью не очень помогает.
Есть особо чувствительное ПО вроде chromium, которое как лагало, когда ядра заняты процессом с nice 19, так и продолжает лагать с cgroups.

Кванты шедулера крутил, с 1000HZ пересобирал.

С задачей распределения ресурсов cgroups справляется на отлично, но практически бесполезен для десктопных юзкейсов (кроме крайних случаев предотвращения дедлоков).
Если всё поделить на группу desktop с 90 cpu shares и idle, с 10 shares, то хромой находясь в группе desktop всё равно будет дёргаться в микрофризах, пока в idle работает ffmpeg.


запуск условного майнера под вторичным, и что то идёт не так: условный майнер отказывается отдавать первичному пользователю более 50% свободного cpu, даже если первичный создаёт 8-10-12 потоков нагрузки.

Cgroups начнёт душить майнер в ситуации нехватки ресурсов. Пока на cpu никто не претендует, даже процесс в группе с одной шарой может использовать весь доступный ресурс.
Возможно те 10 потоков по каким-то причинам не могут быть распланированы (I/O?), а чтобы циклы не пропадали, их отдают майнеру.

Чтобы проверить, действительно ли всё делится по братски, нужно первому юзеру тот же майнер запустить.

P.S. Не знаю как там через мастодонта systemd, но вообще менять настройки cgroups можно в рантайме, ничего не перезапуская.

aidaho ★★★★★ ()
Ответ на: комментарий от aidaho

Cgroups начнёт душить майнер в ситуации нехватки ресурсов. Пока на cpu никто не претендует, даже процесс в группе с одной шарой может использовать весь доступный ресурс. Возможно те 10 потоков по каким-то причинам не могут быть распланированы (I/O?), а чтобы циклы не пропадали, их отдают майнеру.

Нет, там чувствуется точно отмеренная справедливая балансировка 47% майнеру, 47% всему остальному зоопарку и 6% ядру. Зоопарк варировался от 4-х вкладок хромиума и openxcom до тестового набора из ffmpeg+pbzip2, и всегда он отрабатывал чётко пополам.

всё равно будет дёргаться в микрофризах

Мои 4-е медленых ядра это RPi3. Хромой что так, что так лагает, мне паралельно. Т.е. вообще то последовательно, на 2-х ядрах из 4, а я хочу чтобы он лагал быстрее, 4-я вкладками в паралель.

огородить ключевой юзерспейс в отдельный cgroup, с гарантированно высокими шарами

А есть более-менее простой способ, или инструкция на русском? Мне бы идеально подошло огородить небольшой список процессов в отдельный слайс idle с самой маленькой шарой.

kirill_rrr ★★★★★ ()
Последнее исправление: kirill_rrr (всего исправлений: 3)
Ответ на: комментарий от kirill_rrr

Не знаю на счёт инструкций на русском.
Почитал маны, наваял своё.
(Ре)Стартую свой конфиг таким скриптом

#!/usr/bin/env bash
##########################
# Sets up cgroups daemon #
##########################

# Unmount existing cgroups
umount /sys/fs/cgroup/*
# Stop daemon
pkill cgrulesengd

# Load cgroups configuration
cgconfigparser -l /etc/cgconfig.conf
# Track and assign processes
cgrulesengd -s

exit 0


Пример cgconfig.conf

mount {
      cpu = /sys/fs/cgroup/cpu;
      memory = /sys/fs/cgroup/memory;
      blkio = /sys/fs/cgroup/blkio;
}

group anyprocess {
  cpu {
      cpu.shares="290";
  }
  blkio {
      blkio.weight="290";
  }
}


group system {
  cpu {
      cpu.shares="200";
  }
  blkio {
      blkio.weight="200";
  }
}


group desktop {
  cpu {
      cpu.shares="500";
  }
  blkio {
      blkio.weight="500";
  }
}


group idle {
  perm {
      admin {
          uid = root;
          gid = root;
      }
      task {
          uid = aidaho;
          gid = users;
      }
  }
  cpu {
      cpu.shares="1";
  }
  memory {
      # RAM max
      memory.limit_in_bytes="4G";
      # RAM + SWAP
      # memory.memsw.limit_in_bytes="8G";
  }
  blkio {
      blkio.weight="10";
  }
}

Секция perm в idle даёт пользователю право забросить процесс в группу, скажем, посредством cgexec.


Дальше cgrulesengd читает на старте /etc/cgrules.conf
Он с правами рута будет распихивать процессы по группам.

Вольная выдержка из моего:
*:dpkg                     cpu,memory,blkio          idle
*:dpkg-deb                 cpu,memory,blkio          idle
*:dpkg-buildpackage        cpu,memory,blkio          idle
*:hugin_hdrmerge           cpu,blkio                 idle
*:enblend                  cpu,blkio                 idle
*:enfuse                   cpu,blkio                 idle
*:sshd          cpu,blkio                 system
*:mosh-server   cpu,blkio                 system
*:tincd         cpu,blkio                 system
*:tmux          cpu,blkio                 system
*:Xorg          cpu,blkio                 desktop
*:compton-tde   cpu,blkio                 desktop
*:compton       cpu,blkio                 desktop
*:pulseaudio    cpu,blkio                 desktop
*               cpu,blkio                 anyprocess


Меня интересовало распихивание в группы не по пользователям, а по имени процессов, поэтому вместо юзера везде звёздочка.
Указанные группы должны быть определены в cgconfig.conf

Как уже рассказывал выше, хоть desktop имеет более половины всех шар, а idle - 1 (одну), числодробилка, находясь в последнем, влияет на отзывчивость.

aidaho ★★★★★ ()

Почему настройка CPUShares не применяется

Сначала проверь, записывается ли это значение в соответствующий файл в cgroupfs (/sys/fs/cgroup/cpu/user.slice/user-1000.slice/cpu.shares) и находится ли искомый процесс в той цгруппе, которую ты настраивал (systemctl status PID).

Если на оба вопроса ответ «да», значит, ты как-то не так понимаешь семантику cpu.shares и/или что-то сломано со стороны ядра (я здесь ничего не подскажу, т. к. не пользовался).

и предусмотрен ли способ применять изменения без перезагрузки системы? А без перезапуска сессии?

По systemctl daemon-reload всё должно применяться.

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от anonymous

А там не важно. Нагрузка есть, ядро ставит процесс на паузу и отдаёт cpu другому. Сам факт обработки прерываний уже съедает проценты времени и рвёт цепочку кадров. На софтовом рендере с отключеными анимациями оно даже шустрее смотрится.

kirill_rrr ★★★★★ ()
Ответ на: комментарий от anonymous

А какая разница, какой он там?
Суть проблемы не в скорости отрисовки, а в неоднородных задержках в ответ на ввод.

Подозреваю, что мультипроцесс архитектура хрома тут ему подкладывает большую свинью, так как, например, огнелис теряет в отзывчивости гораздо меньше.

Хрому нужно проксировать события и реакцию в/через отдельные процессы, которые в условиях высокой загруженности не будут распланированы так, как хотелось бы пользователю (с упором на уменьшение latency).

К сожалению cgroups тут не особо в помощь.
Единственный условно рабочий вариант, который я видел, это ограничить количество квантов для idle так, чтобы процесс в принципе не мог взять больше половины процессорного времени.
Так остаётся куча свободного времени для более быстрого прохождения очереди приоритетными процессами.

Но половина вычислительной мощности стоит.

aidaho ★★★★★ ()
Ответ на: комментарий от intelfx
root@raspberrypi:/sys/fs/cgroup/systemd# find
.....
./user.slice
./user.slice/user-1000.slice
./user.slice/user-1000.slice/tasks
./user.slice/user-1000.slice/user@1000.service
./user.slice/user-1000.slice/user@1000.service/tasks
./user.slice/user-1000.slice/user@1000.service/cgroup.procs
./user.slice/user-1000.slice/user@1000.service/cgroup.clone_children
./user.slice/user-1000.slice/user@1000.service/notify_on_release
./user.slice/user-1000.slice/cgroup.procs
./user.slice/user-1000.slice/session-c1.scope
./user.slice/user-1000.slice/session-c1.scope/tasks
./user.slice/user-1000.slice/session-c1.scope/cgroup.procs
./user.slice/user-1000.slice/session-c1.scope/cgroup.clone_children
./user.slice/user-1000.slice/session-c1.scope/notify_on_release
./user.slice/user-1000.slice/cgroup.clone_children
./user.slice/user-1000.slice/notify_on_release
./user.slice/tasks
./user.slice/user-1001.slice
./user.slice/user-1001.slice/tasks
./user.slice/user-1001.slice/cgroup.procs
./user.slice/user-1001.slice/cgroup.clone_children
./user.slice/user-1001.slice/user@1001.service
./user.slice/user-1001.slice/user@1001.service/tasks
./user.slice/user-1001.slice/user@1001.service/cgroup.procs
./user.slice/user-1001.slice/user@1001.service/cgroup.clone_children
./user.slice/user-1001.slice/user@1001.service/notify_on_release
./user.slice/user-1001.slice/notify_on_release
./user.slice/user-1001.slice/session-c2.scope
./user.slice/user-1001.slice/session-c2.scope/tasks
./user.slice/user-1001.slice/session-c2.scope/cgroup.procs
./user.slice/user-1001.slice/session-c2.scope/cgroup.clone_children
./user.slice/user-1001.slice/session-c2.scope/notify_on_release
./user.slice/cgroup.procs
./user.slice/cgroup.clone_children
./user.slice/notify_on_release

Просмотрел файлики, но не нашёл никаких явных упоминаний CPUSares

root@raspberrypi:/sys/fs/cgroup/systemd# systemctl status user-1001.slice
● user-1001.slice
   Loaded: loaded
  Drop-In: /etc/systemd/system/user-1001.slice.d
           └─50-CPUShares.conf
   Active: active since Чт 2018-10-04 17:39:01 +05; 2 days ago
   CGroup: /user.slice/user-1001.slice
           ├─user@1001.service
           │ ├─1007 /lib/systemd/systemd --user
           │ └─1010 (sd-pam)
           └─session-c2.scope
             ├─ 976 /bin/login --
             ├─1015 -bash
             └─1020 ./xmrig

Насколько я понял, правило было загружено. Но само значение CPUShares не упоминается.

У меня кастомное ядро. Что надо проверять?

kirill_rrr ★★★★★ ()
Последнее исправление: kirill_rrr (всего исправлений: 2)
Ответ на: комментарий от kirill_rrr

/sys/fs/cgroup/systemd

Не там смотришь.

$ mount | grep 'type cgroup' | grep -w cpu
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)

systemctl status user-1001.slice

Не user-1001.slice, а PID процесса. Я предложил проверить, что процесс действительно попал в ту cgroup, которую ты настраиваешь.

intelfx ★★★★★ ()
Последнее исправление: intelfx (всего исправлений: 3)
Ответ на: комментарий от intelfx

Не там смотришь.

А /sys/fs/cgroup/cpu вообще отсутствует.

root@raspberrypi:/sys/fs/cgroup# ls 
net_cls  systemd

И:

root@raspberrypi:/sys/fs/cgroup# systemctl status 1020
● session-c2.scope - Session c2 of user n
   Loaded: loaded (/run/systemd/system/session-c2.scope; static)
  Drop-In: /run/systemd/system/session-c2.scope.d
           └─50-After-systemd-logind\x2eservice.conf, 50-After-systemd-user-sessions\x2eservice.conf, 50-Description.conf, 50-SendSIGHUP.conf, 50-Slice.conf
   Active: active (running) since Чт 2018-10-04 17:39:02 +05; 3 days ago
   CGroup: /user.slice/user-1001.slice/session-c2.scope
           ├─ 976 /bin/login --
           ├─1015 -bash
           └─1020 ./xmrig

kirill_rrr ★★★★★ ()
Ответ на: комментарий от intelfx
root@raspberrypi:/sys/fs/cgroup# cat /media/mnt/boot/config-4.4.50-gen5 | grep CGROUP
CONFIG_CGROUPS=y
# CONFIG_CGROUP_DEBUG is not set
# CONFIG_CGROUP_FREEZER is not set
# CONFIG_CGROUP_PIDS is not set
# CONFIG_CGROUP_DEVICE is not set
# CONFIG_CGROUP_CPUACCT is not set
# CONFIG_CGROUP_PERF is not set
CONFIG_CGROUP_SCHED=y
# CONFIG_BLK_CGROUP is not set
# CONFIG_NETFILTER_XT_MATCH_CGROUP is not set
CONFIG_NET_CLS_CGROUP=m
# CONFIG_CGROUP_NET_PRIO is not set
CONFIG_CGROUP_NET_CLASSID=y
root@raspberrypi:/sys/fs/cgroup#

Их все стоит задать?

kirill_rrr ★★★★★ ()
Ответ на: комментарий от kirill_rrr

А /sys/fs/cgroup/cpu вообще отсутствует.

Раз контроллер не смонтирован, то и ограничения не задать.
Вообще, монтировать можно куда угодно.

В моём примере выше сначала cgconfigparser монтирует cpu, memory и blkio, в те места, где их ожидает найти cgrulesengd.

Чтобы убедиться, что процесс действительно был классифицирован, надо почитать вывод cat /proc/`pidof processname`/cgroup

aidaho ★★★★★ ()
Ответ на: комментарий от kirill_rrr

Вообще, за контроллер cpu отвечает CONFIG_CGROUP_SCHED. Но попробуй включить ещё и CONFIG_CGROUP_CPUACCT: systemd монтирует их в одну иерархию, и вполне возможно, что если один из них недоступен — оно забивает на оба.

intelfx ★★★★★ ()
Ответ на: комментарий от intelfx

Собственно всем спасибо, включил примерно половину всего и оно заработало как по мануалу. Какие это даст недостатки пока не знаю, первый час полёта. Потом можно будет на досуге всё лишнее из ядра выкинуть.

kirill_rrr ★★★★★ ()
Ответ на: комментарий от kirill_rrr

Какие это даст недостатки пока не знаю

Memory controller жрёт память. Больше недостатков не знаю. Были ещё проблемы с realtime scheduling (когда включаешь CPU controller, по дефолту без ручной конфигурации все процессы получают нулевую квоту реалтаймового процессорного времени), но их вроде бы как-то порешали.

intelfx ★★★★★ ()
Ответ на: комментарий от intelfx

Собственно появился один непонятный косяк. Что то подвисает и блокирует звук для остальных. Лечится перезапуском сессии с убиванием процессов пльзователя. Проявлялось 3 раза, в первый раз виноваты были зомбо-копии флешплеера в хромиуме.

kirill_rrr ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.