Как заставить ядро ​​Linux «замерзнуть» (или почти замереть) на несколько сотен миллисекунд

Как заставить ядро ​​Linux «замерзнуть» (или почти замереть) на несколько сотен миллисекунд

Мы запускаем процесс реального времени на ядре, не поддерживающем режим реального времени (CentOS 6), и это, вероятно, не изменится.

У нас есть приложение потокового видео, которому требуется около 500 МБ/с трафика PCIe от пользовательской FPGA непрерывно в течение 1,5 часов. Приложение работает довольно хорошо — большую часть времени. Однако у нас были ситуации, когда ядро ​​просто переставало отвечать на обслуживание запросов PCIe или памяти на время до 500 миллисекунд за раз. Похоже, это происходит во время пакетного ввода-вывода файла из другого потока. Я обнаружил, что невозможно попытаться воспроизвести эту проблему, просто выполняя множество фиктивных операций ввода-вывода файла из пользовательского пространства во время работы основного приложения.

Есть ли способ принудительно (симулировать) глобальную «заморозку» ядра Linux (в частности, остановить доступ к PCIe или всем модулям памяти DDR3 или что-то в этом роде), чтобы мы могли воспроизвести эту проблему?

У нас есть буферизация до 10 миллисекунд, реализованная прямо сейчас во внутренней памяти FPGA, но этого недостаточно. Мы можем буферизировать в FPGA DDR3, а затем сбрасывать на хост, но нам нужен метод для тестирования этой новой функции под давлением.

Мы не хотим, чтобы ядро ​​зависло или заблокировалось навсегда. Мы хотели бы иметь возможность устанавливать временной интервал.

Я ищу что-то вроде /proc/sys/vmвременной записи магических значений, которые заставят систему работать практически медленно, а затем вернутся к норме через несколько сотен миллисекунд, но рассмотрение возможных способов сломать это — не для новичка вроде меня (https://www.kernel.org/doc/Documentation/sysctl/vm.txt) . Может быть немного numactlмагии?

решение1

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

С другой стороны, вот что я помню и что могло вызвать у вас паузу:

  • cpufreq cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latency, значение в нс (4000 в моем восьмиядерном процессоре AMD FX(tm)-8120) не должно быть проблемой, но проверьте
  • Тепловое регулирование либо самого процессора, либо модуля регулятора напряжения.
  • NAPI и/или большой сетевой трафик
  • PCIe ASPM ( cat /sys/module/pcie_aspm/parameters/policy)
  • Конфликт в буферах вашего целевого устройства (жесткий диск, сетевая карта...)
  • Ошибка в прошивке какого-либо устройства на шине PCIe (даже если вы его не используете), вы можете попробовать отключить его с помощью/sys/bus/pci/devices/$DEVICE/power/control

решение2

Можно ли получить более подробную информацию о том, как ваше приложение взаимодействует с FPGA? Это приложение считывает буфер из FPGA или FPGA отправляет прерывание ядру (как сетевые карты)?

Я ожидаю, что он откроет блок/символ в /dev и затем свяжется с ним. Это означает, что он использует драйвер для связи между приложением и файлом /dev/XXX.

Я хотел бы получить вывод: cat /proc/interrupts; lsmod;ls -al /dev/yourmod

Вот идеи:

  • Если это прерывание, вы можете настроить PIC ЦП на отключение соответствующего IRQ, а затем снова включить его. Это приведет к игнорированию всех запросов карты (без того, чтобы карта знала об этом).
  • если это похоже на чтение буфера, вы можете:
    • Переведите приложение в спящий режим, чтобы данные из ПЛИС не считывались, а буфер заполнялся, затем разбудите приложение и продолжите чтение.
    • Используйте «crash» или «kgdb», чтобы изменить значение «read» на «noop» на несколько секунд, а затем верните его к функции по умолчанию.

Пожалуйста, предоставьте всю информацию, которая может оказаться полезной.

решение3

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

Каждое устройство PCI может быть приостановлено в соответствии с заголовочным файлом.http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/pci.h#L479

Например, вот функция приостановки сетевого адаптера Intel e1000.http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/drivers/net/e1000e/netdev.c#L4643

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

решение4

Я думаю, вы мыслите в неправильном направлении. Ваша цель ясна.

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

Более сложная проблема — обработка прерываний PCIe, которая находится в пространстве ядра.

Поскольку здесь задействовано аппаратное обеспечение, вам следует более внимательно изучить задействованную линию PCIe на вашей материнской плате и то, как она может быть подключена к определенному разъему ЦП.

irqbalanceобычно хорошо справляется с этой задачей, но вы можете настроить его поведение в соответствии со своими потребностями.

Связанный контент