Длинные IRQ ОТКЛЮЧЕНЫ для _raw_spin_lock_irqsave

#linux #real-time #scheduler #trace

#linux #в режиме реального времени #планировщик #трассировка

Вопрос:

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

У меня есть ядро 4.9.68 с PREEMPT_RT, работающее на микроконтроллере iMX7. У меня установлен PROVE_LOCKING, который обнаружил некоторую несогласованность gpio_lock в драйвере, которую я собираюсь исправить — это не проблема.

Проблема в том, что когда я запускаю cyclictest, я получаю огромное дрожание максимум в несколько миллисекунд. Но странно то, что системы начинают вести себя правильно, как только я вызываю предупреждение о несоответствии gpio_lock, вызывая IRQ неисправного драйвера или отключая функцию PROVE_LOCKING.

Трассировщик preemptirqsoff сообщает, что в разделах отключены длинные IRQ, вызванные _raw_spin_lock_irqsave. В комментарии в исходном коде говорится, что функция не может быть вытеснена при использовании lockdep. Поэтому я подозреваю, что опция PROVE_LOCKING не подходит для системы RT и должна быть отключена.

Но я не удовлетворен таким решением, потому что я не понимаю двух вещей:

  1. Почему проблема исчезает после того, как gpio_lock (dis) доказан?
  2. Почему он сохраняется, даже если неисправный драйвер отключен?

Или какая деталь отсутствует в моем понимании системы?

Я не видел никакого шаблона в трассировке function_graph, который дал бы мне какую-либо подсказку.

Я был бы очень признателен за любое направление, подсказку или вину за мое непонимание 🙂

Комментарии:

1. "this is not an issue" Я думаю, что я слышал это раньше. В любом случае, хорошее резюме. Если у вас когда-нибудь возникнет проблема, пожалуйста, опубликуйте свой код, и тогда мы сможем предложить некоторую помощь. Возможно, существует более длинный путь с отключенными целыми числами, чем вы думаете. Попытки рассуждать об ошибке с неизвестной причиной могут быть бесполезными.

2. Проблема заключается в драйвере ads7846, который несовместим с PREEMPT_RT, поскольку он использует устаревший целочисленный интерфейс gpio. Его обработчик IRQ через get_pendown , через gpio_get_value в конечном итоге вызовет gpio_to_desc, который пытается заблокировать gpio_lock в контексте IRQ-> что является проблемой с PREEMPT_RT.

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

Ответ №1:

В итоге я просто отключил опцию PROVE_LOCKING . До сих пор не знаю, почему это происходит, но оно просто исчезает, как только эта функция отключена. Так что либо где-то в модуле есть ошибка, либо это желаемое, но недокументированное поведение…

Тем не менее, мониторинг задержки на ферме контроля качества OSADL (например, этой) также отключен, поэтому я думаю, что они знают, что делают, и я в порядке с этим.

Спасибо всем, кто потратил время на чтение и обдумывание моей проблемы.