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

17

Мы запускаем процесс в реальном времени на ядре не в реальном времени (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магии?

Марк Лаката
источник
Я догадываюсь, что это требует написания модуля ядра. Вам нужно как-то заморозить все потоки на всех процессорах и организовать перезапуск по прерыванию по таймеру.
Жиль "ТАК - перестань быть злым"
Я не хочу заморозить темы, я хочу заморозить ядро! Я имею в виду, я хочу на короткое время запретить доступ к оборудованию (памяти и / или PCIe и / или диску). Если это не сработает, я не возражаю против того, чтобы сделать вещи неоптимизированными, отключить кэш L1 и т. Д. Я просто не знаю, как это сделать.
Марк Лаката
1
Ах, вы не хотите заморозить ядро, вы хотите заморозить только часть ядра, которая реагирует на какое-то оборудование? Это также потребовало бы погружения довольно глубоко в ядро.
Жиль "ТАК - перестань быть злым"
Я не возражаю против полного замораживания ядра до тех пор, пока аппаратное обеспечение как часть его заморожено.
Марк Лаката
1
Оказывается, проблема связана с перезаписью TLB, поскольку центральный процессор сбрасывает некоторые буферы ввода-вывода (мы используем HDF5 для записи файлов), и это перезапись TLB вызывает сбой сопроцессора, так как это система NUMA. Полагаю, все, что нам сейчас нужно, - это надежный способ программно вызывать перегрузку TLB в течение контролируемого периода времени.
Марк Лаката

Ответы:

9

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

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

  • cpufreq, cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latencyзначение в нс (4000 в моем 8-ядерном процессоре AMD FX (tm) -8120) не должно быть проблемой, но проверьте
  • Термическое дросселирование либо самого процессора, либо модуля регулятора напряжения.
  • NAPI и / или интенсивный сетевой трафик
  • PCIe ASPM ( cat /sys/module/pcie_aspm/parameters/policy)
  • Конфликт в буферах целевого устройства (жесткий диск, ник ...)
  • Ошибка в прошивке какого-либо устройства в шине PCIe (даже если вы не используете его), вы можете попробовать отключить их с помощью /sys/bus/pci/devices/$DEVICE/power/control
Хорхе Нерин
источник
Могу ли я использовать kdbвместо того, kgdbчтобы сделать то же самое? Я никогда не использовал ни того, ни другого. Это похоже на последовательность команд «Стоп-А» на рабочих станциях Sun прошлого года? Если я просто сделаю быстрый SysRq-g, а затем наберу "go", у меня будет высокая вероятность того, что система не сломается? (ссылка: kernel.org/pub/linux/kernel/people/jwessel/kdb/… )
Марк Лаката,
1
Возможно, вы сможете использовать KDB. Помните, что он должен работать с клавиатурами, подключенными через USB, но на всякий случай постарайтесь иметь PS / 2. И это отладчик очень низкого уровня (земля ядра), так что, как всегда, сохраняйте резервные копии, и если он сломается, вы сохраняете обе части :).
Хорхе Нерин
Прежде чем прибегнуть к настройке ядра, я сначала попытался бы выгрузить неиспользуемые модули ядра для устройств PCIe, которые могли бы использовать шину (особенно графические драйверы), и либо физически удалить устройства из системы, либо отключить их питание. PCIe 1.0 x1 имеет пропускную способность 250 МБ / с, а PCIe 2.0 x1 - до 500 МБ / с. Являются ли устройства отправления и назначения свободными для принятия такой устойчивой скорости без перерывов, или у них больше полос для увеличения запаса?
Хорхе Нерин
Другим возможным источником задержки может быть некоторый обработчик управления питанием ACPI какого-либо устройства или даже некоторый обработчик ЦП SMM, ожидающий внешнего события.
Франки
2

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

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

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

Вот идеи:

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

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

Адриен М.
источник
FPGA выполняет запись DMA в память хоста, и во время этих периодов простоя FPGA не может выполнять запись в память хоста, поэтому ее внутреннее резервное копирование FIFO. Существует интерфейс на основе сообщений с процессом хоста (происходит через PCIe), но я уверен, что это не связано. В целях проверки мне в основном нужен способ запрета аппаратным средствам ПЛИС производить запись в память хоста в течение нескольких сотен миллисекунд. Я не хочу решать проблему с памятью, но хочу убедиться, что наша реализация на ПЛИС способна справиться с нехваткой памяти (до 1000 мс).
Марк Лаката
Хорошо, если он использует DMA, вы можете взглянуть на: kernel.org/doc/Documentation/DMA-ISA-LPC.txt, в частности на request_dma_lock () и dma_disable (). Однако вам необходимо знать адреса, используемые вашей FPGA.
Адриен М.
1

Не уверен, что это поможет. Но если вы можете написать модуль ядра, который вызывает 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

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

yegle
источник
спасибо, но я не думаю, что это сработает. Я действительно не хочу приостанавливать устройство, которое является ядром, которое говорит устройству подготовиться к гибернации; Я хочу, чтобы ядро ​​игнорировало конкретное устройство (в данном случае дочернюю плату FPGA) без его ведома (кроме длинных задержек или тайм-аутов) - или я хочу остановить все передачи памяти SDRAM.
Марк Лаката
0

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

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

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

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

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

Nils
источник