1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/anolis-plugsched

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README_zh.md 27 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 30.11.2024 08:08 1dcfc5a

Плагскхед: горячее обновление подсистемы планировщика ядра Linux

Плагскхед — это набор средств разработки (SDK), который позволяет динамически заменять подсистему планировщика без перезагрузки системы или приложений. Это позволяет сократить время простоя до миллисекунд. Плагскхед позволяет динамически изменять, добавлять и удалять функции планировщика в производственной среде, чтобы удовлетворить потребности различных сценариев использования и поддерживает откат изменений.

Мотивация

  • Различные сценарии использования требуют разных стратегий планирования: оптимизация стратегии планирования в облачных сценариях является сложной задачей, и не существует универсальной стратегии. Поэтому важно предоставить пользователям возможность настраивать планировщик для конкретных сценариев.
  • Итерации планировщика происходят медленно: ядро Linux прошло долгий путь обновлений, его код стал сложным и взаимосвязанным, особенно в области планировщика, который является одной из самых важных подсистем ядра. Разработка и отладка становятся всё более сложными. В ядре редко добавляются новые типы планировщиков, особенно те, которые предназначены для специфических сценариев. Плагскхед может отделить планировщик от ядра, позволяя разработчикам сосредоточиться на итеративной разработке планировщика.
  • Обновление ядра затруднено: планировщик встроен в ядро, поэтому любые изменения в планировщике требуют обновления ядра. Цикл выпуска ядра обычно составляет несколько месяцев, что приводит к задержкам в применении новых планировщиков в системе. Кроме того, обновление нового ядра в кластере требует миграции сервисов и перезагрузки, что является дорогостоящим процессом для бизнеса.
  • Невозможность обновить подсистемы: kpatch и livepatch представляют собой решения для горячего обновления на уровне функций, но их возможности ограничены, и они не могут реализовать сложные изменения кода. Для eBPF текущий планировщик также не поддерживает ebpf hook, и даже если поддержка будет добавлена в будущем, она будет ограничена изменениями локальной стратегии.

Как это работает Планировщик не является отдельным модулем в ядре, а интегрирован в него. Плагскхед использует концепцию модульности: он предоставляет инструмент для определения границ планировщика и извлекает планировщик из исходного кода ядра в отдельный каталог. Разработчики могут вносить изменения в извлечённый код планировщика, компилировать его в новый модуль ядра планировщика и динамически заменять старый планировщик в ядре.

Для функций плагскхед предоставляет внешние интерфейсы. Заменяя эти функции в ядре, ядро может обойти существующую логику выполнения и выполнить новый модуль планировщика, тем самым обновляя функцию. Функции в модуле либо являются интерфейсными функциями, либо внутренними функциями; все остальные функции считаются внешними функциями.

Что касается данных, плагскхед разделяет данные на частные и общие. Частные данные распределяются по модулю независимо, в то время как общие данные совместно используются модулем и ядром. Глобальные переменные можно преобразовать в частные данные путём переопределения или в общие данные путём объявления. По умолчанию статические глобальные переменные помечаются как частные данные, а нестатические глобальные переменные — как общие данные. Однако для улучшения работы системы некоторые глобальные переменные настраиваются вручную в файле конфигурации границ.

В процессе горячего обновления синхронизация состояния данных является ключевой проблемой. Данные делятся на основные и неосновные в зависимости от необходимости восстановления состояния. Основные данные включают rq, cfs_rq, rt_rq, dl_rq, cfs_bandwidth, sched_class, sysfs, debugfs, sched_features и timer. Остальные данные считаются неосновными данными, включая sched_domain_topology, task_group_cache и связанные с планировщиком sysctls, tracepoint и cpumask. Плагскхед восстанавливает состояние основных данных планировщика с помощью технологии sched rebuild. Для неосновных данных частные данные не требуют синхронизации состояния, а общие данные автоматически наследуют состояние без дополнительной обработки. Этот универсальный подход к восстановлению состояния эффективно решает проблему синхронизации состояния.

Основные данные Неосновные данные
Частное Восстановление Переинициализация
Общее Восстановление Наследование

Важно отметить, что структура и семантика членов структуры не должны изменяться произвольно. Если необходимо добавить новых членов, рекомендуется использовать зарезервированные поля, предварительно определённые в структуре.

Извлечение границ Поскольку планировщик сам по себе не является модулем, необходимо чётко определить его границы, чтобы сделать его модульным. Инструмент определения границ использует информацию, собранную во время компиляции ядра, такую как имена символов, местоположения, атрибуты символов и отношения вызовов функций, для извлечения кода планировщика из исходного кода ядра. Процесс извлечения включает сбор информации, анализ границ на основе файла конфигурации границ и извлечение кода внутри границ в отдельный каталог kernel/sched/mod.

Разработка планировщика После извлечения код модуля планировщика помещается в отдельный каталог, где разработчики могут модифицировать код для настройки планировщика под конкретные сценарии. Важно учитывать ограничения, описанные в разделе «Ограничения».

Компиляция и установка планировщика По завершении разработки код модуля планировщика вместе с программами для загрузки/выгрузки и другими связанными функциями компилируется в модуль ядра и создаётся пакет RPM для планировщика. После установки новый планировщик заменяет старый в ядре. Процесс установки включает в себя:

  • Переопределение символов: неопределённые символы в модуле переназначаются.
  • Проверка безопасности стека: перед заменой функций необходимо провести проверку безопасности стека, иначе может произойти сбой. Плагскхед оптимизирует параллельную проверку безопасности стека для повышения эффективности и снижения времени простоя.
  • Замена интерфейсных функций: интерфейсные функции модуля динамически заменяют функции ядра.
  • Восстановление состояния планировщика: используется общий метод для автоматической синхронизации состояний старого и нового планировщиков, значительно упрощая работу по поддержанию согласованности данных.

Сценарии использования

  1. Быстрая разработка, тестирование и внедрение новых функций с последующим включением в основную линию ядра.
  2. Настройка планировщика для различных бизнес-сценариев с выпуском и поддержкой специализированных характеристик планировщика через пакеты RPM.
  3. Централизованное управление обновлениями планировщика для предотвращения конфликтов между несколькими горячими исправлениями и возникновения проблем.

Быстрый старт На данный момент плагскхед поддерживает систему Anolis OS 8.6 ANCK. Для других систем требуется настройка файла конфигурации границ. Чтобы упростить настройку среды разработки, предоставляются образы контейнеров и Dockerfile, избавляя разработчиков от необходимости самостоятельно создавать среду разработки. Для демонстрации процесса обновления используется экземпляр ECS (64CPU + 128GB) с установленной системой Anolis OS 8.6 ANCK, на котором будет выполнено горячее обновление планировщика ядра.

Процесс быстрого старта включает следующие шаги:

  1. Войдите в облачный сервер после установки необходимых базовых пакетов программного обеспечения:
# yum install anolis-repos -y
# yum install yum-utils podman kernel-debuginfo-$(uname -r) kernel-devel-$(uname -r) --enablerepo=Plus-debuginfo --enablerepo=Plus -y
  1. Создайте временную рабочую директорию и загрузите исходный код ядра:
# mkdir /tmp/work && cd /tmp/work
# yumdownloader --source kernel-$(uname -r) --enablerepo=Plus
  1. Запустите и войдите в контейнер:
# podman run -itd --name=plugsched -v /tmp/work:/tmp/work -v /usr/src/kernels:/usr/src/kernels -v /usr/lib/debug/lib/modules:/usr/lib/debug/lib/modules plugsched-registry.cn-hangzhou.cr.aliyuncs.com/plugsched/plugsched-sdk
# podman exec -it plugsched bash
# cd /tmp/work
  1. Извлеките исходный код ядра:
# uname_r=$(uname -r)
# plugsched-cli extract_src kernel-${uname_r%.*}.src.rpm ./kernel
  1. Проведите определение границ и извлечение:
# plugsched-cli init $(uname -r) ./kernel ./scheduler
  1. Код модуля планировщика после извлечения находится в каталоге ./scheduler/kernel/sched/mod. Добавьте новую функцию sched_feature и создайте пакет RPM:
diff --git a/scheduler/kernel/sched/mod/core.c b/scheduler/kernel/sched/mod/core.c
index 9f16b72..21262fd 100644
--- a/scheduler/kernel/sched/mod/core.c
+++ **b/scheduler/kernel/sched/mod/core.c**

static void __sched notrace __schedule(bool preempt) { struct rq *rq; int cpu;

if (sched_feat(PLUGSCHED_TEST)) {
    printk_once("I am the new scheduler: __schedule\n");
}

cpu = smp_processor_id();
rq = cpu_rq(cpu);
prev = rq->curr;

}


**diff --git a/scheduler/kernel/sched/mod/features.h b/scheduler/kernel/sched/mod/features.h**

SCHED_FEAT(PLUGSCHED_TEST, false)


7. Чтобы собрать сгенерированный пакет RPM, скопируйте его на хост и выйдите из контейнера. Затем проверьте текущие параметры sched_features:

```shell
# uname_r=$(uname -r)
# cp /tmp/work/scheduler/working/rpmbuild/RPMS/x86_64/scheduler-xxx-${uname_r%.*}.yyy.x86_64.rpm /tmp/work/scheduler-xxx.rpm
# exit
exit
# cat /sys/kernel/debug/sched_features
GENTLE_FAIR_SLEEPERS START_DEBIT NO_NEXT_BUDDY LAST_BUDDY CACHE_HOT_BUDDY WAKEUP_PREEMPTION NO_HRTICK NO_DOUBLE_TICK NONTASK_CAPACITY TTWU_QUEUE NO_SIS_AVG_CPU SIS_PROP NO_WARN_DOUBLE_CLOCK RT_PUSH_IPI RT_RUNTIME_SHARE NO_LB_MIN ATTACH_AGE_LOAD WA_IDLE WA_WEIGHT WA_BIAS NO_WA_STATIC_WEIGHT UTIL_EST ID_IDLE_AVG ID_RESCUE_EXPELLEE NO_ID_EXPELLEE_NEVER_HOT NO_ID_LOOSE_EXPEL ID_LAST_HIGHCLASS_STAY
  1. Установите пакет планировщика, добавив новый параметр sched_feature PLUGSCHED_TEST (отключённое состояние):
# rpm -ivh /tmp/work/scheduler-xxx.rpm
# lsmod | grep scheduler
scheduler             503808  1
# dmesg | tail -n 10
[ 2186.213916] cni-podman0: port 1(vethfe1a04fa) entered forwarding state
[ 6092.916180] Hi, scheduler mod is installing!
[ 6092.923037] scheduler: total initialization time is        6855921 ns
[ 6092.923038] scheduler module is loading
[ 6092.924136] scheduler load: current cpu number is               64
[ 6092.924137] scheduler load: current thread number is           667
[ 6092.924138] scheduler load: stop machine time is            249471 ns
[ 6092.924138] scheduler load: stop handler time is            160616 ns
[ 6092.924138] scheduler load: stack check time is              85916 ns
[ 6092.924139] scheduler load: all the time is                1097321 ns
# cat /sys/kernel/debug/sched_features
NO_PLUGSCHED_TEST GENTLE_FAIR_SLEEPERS START_DEBIT NO_NEXT_BUDDY LAST_BUDDY CACHE_HOT_BUDDY WAKEUP_PREEMPTION NO_HRTICK NO_DOUBLE_TICK NONTASK_CAPACITY TTWU_QUEUE NO_SIS_AVG_CPU SIS_PROP NO_WARN_DOUBLE_CLOCK RT_PUSH_IPI RT_RUNTIME_SHARE NO_LB_MIN ATTACH_AGE_LOAD WA_IDLE WA_WEIGHT WA_BIAS NO_WA_STATIC_WEIGHT UTIL_EST ID_IDLE_AVG ID_RESCUE_EXPELLEE NO_ID_EXPELLEE_NEVER_HOT NO_ID_LOOSE_EXPEL ID_LAST_HIGHCLASS_STAY
  1. Включите новый параметр sched_feature, чтобы информация «I am the new scheduler: __schedule» появилась в журнале dmesg:
# echo PLUGSCHED_TEST > /sys/kernel/debug/sched_features
# dmesg | tail -n 5
[ 6092.924138] scheduler load: stop machine time is            249471 ns
[ 6092.924138] scheduler load: stop handler time is            160616 ns
[ 6092.924138] scheduler load: stack check time is              85916 ns
[ 6092.924139] scheduler load: all the time is                1097321 ns
[ 6512.539300] I am the new scheduler: __schedule
  1. После удаления пакета планировщика новый параметр sched_feature будет удалён:
# rpm -e scheduler-xxx
# dmesg | tail -n 8
[ 6717.794923] scheduler module is unloading
[ 6717.809110] scheduler unload: current cpu number is               64
[ 6717.809111] scheduler unload: current thread number is           670
[ 6717.809112] scheduler unload: stop machine time is            321757 ns
[ 6717.809112] scheduler unload: stop handler time is            142844 ns
[ 6717.809113] scheduler unload: stack check time is              74938 ns
[ 6717.809113] scheduler unload: all the time is               14185493 ns
[ 6717.810189] Bye, scheduler mod has be removed!
#
# cat /sys/kernel/debug/sched_features
GENTLE_FAIR_SLEEPERS START_DEBIT NO_NEXT_BUDDY LAST_BUDDY CACHE_HOT_BUDDY WAKEUP_PREEMPTION NO_HRTICK NO_DOUBLE_TICK NONTASK_CAPACITY TTWU_QUEUE
``` **НОТ_СИС_СРУ CPU СИС_ПРОП НОТ_ВАРН_ДАБЛ_КЛОК РТ_ПУШ_ИПИ РТ_РУНТЙМ_ШАРЕ НОТ_ЛБ_МИН АТТАЧ_ЭЙДЖ_ЛОАД ВА_АЙДЛЕ ВА_ВЕЙТ ВА_БИАС НОТ_ВА_СТАТИК_ВЕЙТ УТЙЛ_ЕСТ ИД_АЙДЛЕ_СРУ ИД_РЕСКЮ_ЭКСПЛЕ НОТ_ИД_ЭКСПЛЕ_НЕВЕР_ХОТ НОТ_ИД_ЛУЗ_ЭКСПЛЕ ИД_ЛАСТ_ХАЙКЛАСС_СТЕЙ**

Внимание: нельзя использовать команду «rmmod» для непосредственного удаления модуля планировщика, следует использовать стандартные команды «rpm или yum» для удаления пакета планировщика.

FAQ

Q: Что содержится в модуле планировщика после разделения границ по умолчанию?

Содержит следующее:

  • autogroup
  • cpuacct
  • cputime
  • sched debug
  • sched stats
  • cfs rt deadline idle stop sched class
  • sched domain topology
  • sched tick
  • scheduler core

Q: Какие функции можно изменить при горячей замене планировщика?

После завершения извлечения границ в каталоге kernel/sched/mod файлы определяют функции, которые можно изменять. Например, в примере быстрого запуска диапазон функций, которые могут быть изменены в модуле планировщика, включает более 1 тыс. функций. Однако есть некоторые моменты, на которые следует обратить внимание, см. раздел «Ограничения».**

В: Можно ли изменить границы модуля планировщика?

Можно изменить, изменив файл конфигурации границ, чтобы изменить границы планировщика. Например, путём изменения файлов кода, интерфейсов и т. д., см. здесь. Обратите внимание, что если границы планировщика были изменены, перед выпуском необходимо провести тщательное тестирование.

Q: Поддерживает ли plugsched какие-либо версии ядра Linux?

Теоретически plugsched не зависит от версии ядра, мы протестировали версии 3.10 и 4.19, другие версии требуют самостоятельной адаптации и тестирования разработчиками.

Q: Можно ли изменять функции в заголовочных файлах?

Можно. Мы провели разделение границ для функций в заголовочном файле, и функции, помеченные как «DON'T MODIFY INLINE EXTERNAL FUNCTION», в заголовочном файле каталога kernel/sced/mod не могут быть изменены, а остальные функции могут быть изменены.

Q: Можно ли модифицировать структуры данных?

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

Q: Будет ли снижение производительности после замены внутреннего планировщика?

Накладные расходы самого планировщика невелики и ими можно пренебречь. Кроме того, это также зависит от модификации планировщика разработчиком. После теста производительности, если нет никаких изменений, то влияния на производительность нет.

Q: Сколько времени занимает загрузка модуля? Насколько долго?

Это зависит от текущей нагрузки системы и количества процессов, чем больше процессов и чем выше нагрузка, тем дольше время простоя. В нашем тесте на 104-ядерном процессоре с более чем 10 тыс. процессов время простоя не превышает 10 мс.

Q: В чём разница между этим и kpatch? Является ли это оптимизацией kpatch?

kpatch — это оптимизация с уровнем детализации функций, plugsched — это оптимизация на уровне подсистемы, некоторые функции и реализации невозможно оптимизировать с помощью kpatch, например, kpatch не может изменить функцию __schedule и не может одновременно изменить более тысячи функций.

Q: Есть ли конфликт с kpatch? Это оптимизация kpatch?

Есть конфликт, если области модификации kpatch и plugsched пересекаются, перекрывающаяся часть будет покрыта plugsched. Тем не менее, мы разработали механизм обнаружения конфликтов, который можно использовать в производственной среде.

Q: Можно ли изменять функции вне границ планировщика?

Можно, мы предоставляем механизм sidecar, который позволяет одновременно изменять функции за пределами границ планировщика. Например, некоторые исправления исправляют планировщик и содержимое cpuacct, и вы можете использовать механизм sidecar для обновления содержимого cpuacct.

Поддерживаемые архитектуры

  • x86-64
  • aarch64

Ограничения

  • Нельзя изменять функцию init, поскольку функция init освобождается после перезагрузки системы, процесс инициализации должен выполняться во время загрузки модуля;
  • Нельзя изменять сигнатуру интерфейсной функции или удалять интерфейсную функцию, если её нужно удалить, можно преобразовать функцию в пустую функцию;
  • Нельзя изменять любую функцию с комментарием «DON'T MODIFY INLINE EXTERNAL FUNCTION»;
  • Нельзя произвольно изменять семантику структур данных, необходимо обратиться к документу working/boundary_doc.yaml для внесения изменений;
  • После загрузки модуля планировщика нельзя напрямую подключить функции внутри ядра, принадлежащие диапазону модуля планировщика, такие как инструменты perf или ftrace, при необходимости укажите модуль scheduler.ko;

Лицензия

plugsched — это SDK для горячего подключения планировщика ядра Linux, разработанный Alibaba и лицензированный по лицензии GPLv2+ или лицензии BSD-3-Clause. Этот продукт содержит различные сторонние компоненты под другими лицензиями с открытым исходным кодом. Дополнительную информацию см. в файле NOTICE.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/anolis-plugsched.git
git@api.gitlife.ru:oschina-mirror/anolis-plugsched.git
oschina-mirror
anolis-plugsched
anolis-plugsched
master