Проблемка с драйвером на двуядерном проце
От: V-ctor  
Дата: 18.09.07 15:38
Оценка:
собственно проблемка у меня стара, стала всплывать еше на проциках с HT,
http://www.rsdn.ru/Forum/?mid=1901516
Автор: Евгений Музыченко
Дата: 17.05.06

http://www.rsdn.ru/forum/message/1900042.1.aspx
Автор: V-ctor
Дата: 16.05.06

но тогда пришлось позабросить, щас вернулся

В общем в кратце суть такая самописный WDM драйвер исправно обслуживает мою самодельную PCI-плату на одноядерных, однопроцессорных машинах. Но если помимо ядра есть что-то еще (еще ядра или HT) , то драйвер глючит. Выглядит это так прорабоатет себе драйвер некторое время (когда пару секунд не продержицо,а когд и несколько минут), а потом вижу картину: было прерывание сработал ISR (в плате гашу прерывание), запланировал DPC, последнее начало выполняцо и тут как будто снова посреди DPC срабатывает ISR со всеми признаками того что это отклик на прежнее прерывание.
Долго ниче не мог понять, как бы это развести грамотно.
Сделал тупо
завел переменную-флаг в ISR проверяю установлен? тогда выход с возвратом false иначе выставляем флаг и отрабаываем по полной "программе", а потом в конце DPC перед самым выходом сбрасываю, вроде стоит, вроде работает. Но что-то уж через чур по бубуински, наверно это не правильно, как грамотно тут разрулить?
Логике не протеворечит ибо очередь DPC не расчитана более чем на одного человека, т.е. если у меня и сгенерятся в плате несколько разных, но близких по времени прерывания, все кроме первого будут потеряны, но для этого в плате приняты меры что бы такого не происходило, что бы ОС успевала выгребать.

И вообще может быть такое что оба ядра берутся за обслуживания прерывания одновременно в силу стечения каких-то обстоятельств (ну например планировщик не имел более приоритетных прерываний)? не хватает понимания принципа работы ядра ОС на многоядерных системах
Re: Проблемка с драйвером на двуядерном проце
От: Геннадий Майко США  
Дата: 18.09.07 18:39
Оценка:
Здравствуйте, V-ctor,

VC>В общем в кратце суть такая самописный WDM драйвер исправно обслуживает мою самодельную PCI-плату на одноядерных, однопроцессорных машинах. Но если помимо ядра есть что-то еще (еще ядра или HT) , то драйвер глючит. Выглядит это так прорабоатет себе драйвер некторое время (когда пару секунд не продержицо,а когд и несколько минут), а потом вижу картину: было прерывание сработал ISR (в плате гашу прерывание), запланировал DPC, последнее начало выполняцо и тут как будто снова посреди DPC срабатывает ISR со всеми признаками того что это отклик на прежнее прерывание.

--
Ваша процедура обработки прерывания ISR вполне может быть вызвана второй раз до того, как начнет выполняться DPC, поставленное в очеред вызванной ранее первой ISR (если при выходе из ISR она сбросила признак прерывания в плате). К этому надо быть готовым.

VC>Долго ниче не мог понять, как бы это развести грамотно.

VC>Сделал тупо
VC>завел переменную-флаг в ISR проверяю установлен? тогда выход с возвратом false иначе выставляем флаг и отрабаываем по полной "программе", а потом в конце DPC перед самым выходом сбрасываю, вроде стоит, вроде работает. Но что-то уж через чур по бубуински, наверно это не правильно, как грамотно тут разрулить?
VC>Логике не протеворечит ибо очередь DPC не расчитана более чем на одного человека, т.е. если у меня и сгенерятся в плате несколько разных, но близких по времени прерывания, все кроме первого будут потеряны, но для этого в плате приняты меры что бы такого не происходило, что бы ОС успевала выгребать.
--
Как раз наоборот — в один и тот же момент процедура ISR может работать только одна (из-за спинлока прерывания), а вот DPC, поставленных в очередь этой ISR и даже одновременно выполняющихся на разных процессорах, может быть в принципе сколько угодно много.


VC>И вообще может быть такое что оба ядра берутся за обслуживания прерывания одновременно в силу стечения каких-то обстоятельств (ну например планировщик не имел более приоритетных прерываний)?

--
Нет, такого быть не может (см. выше о спинлоках).

Могу предложить несколько подходов:
1. Всю обработку прерывания выполнять только в ISR, в DPC выносить только то, что нельзя делать на "высоких" IRQL (например, установку event и т.п.).
2. Иметь гарантированно одну DPC на каждую ISR — этого можно достичь маскированием прерывания в ISR (но не его сбросом!), запуском DPC на выполнение (понятно, что раз линия прерывания замаскирована и сброшена, то новые возможные прерывания не вызовут новую ISR), в DPC уже обрабатывать прерывания, вычитывая признаки прерывания и сбрасывая их, в конце DPC отменить маскирование, разрешив, таким образом новые прерывания.
3. Защищать DPC от повторного входа с помощью InterlockXXX функций — одна DPC захватывает глобальную переменную и, успешно захватив ее, начинает работу с платой, обрабатывая признаки прерываний и сбрасывая их, а все остальные, которым посчастливилось работать паралельно, просто выходят из DPC (они попытались захватить переменную и не смогли и, понимая, что в это время кто-то другой уже работает, просто заканчивают свою работу).

В принципе, возможно и другие варианты работы, в зависимости от реализации контроллера прерываний на плате.

С уважением,
Геннадий Майко.
Re[2]: Проблемка с драйвером на двуядерном проце
От: V-ctor  
Дата: 19.09.07 11:52
Оценка:
VC>>В общем в кратце суть такая самописный WDM драйвер исправно обслуживает мою самодельную PCI-плату на одноядерных, однопроцессорных машинах. Но если помимо ядра есть что-то еще (еще ядра или HT) , то драйвер глючит. Выглядит это так прорабоатет себе драйвер некторое время (когда пару секунд не продержицо,а когд и несколько минут), а потом вижу картину: было прерывание сработал ISR (в плате гашу прерывание), запланировал DPC, последнее начало выполняцо и тут как будто снова посреди DPC срабатывает ISR со всеми признаками того что это отклик на прежнее прерывание.
ГМ>--
ГМ>Ваша процедура обработки прерывания ISR вполне может быть вызвана второй раз до того, как начнет выполняться DPC, поставленное в очеред вызванной ранее первой ISR (если при выходе из ISR она сбросила признак прерывания в плате). К этому надо быть готовым.
че-т я тут недопонимаю, почему она будет повторно вызвана если я сбросил первый раз прерывание?

VC>>Долго ниче не мог понять, как бы это развести грамотно.

VC>>Сделал тупо
VC>>завел переменную-флаг в ISR проверяю установлен? тогда выход с возвратом false иначе выставляем флаг и отрабаываем по полной "программе", а потом в конце DPC перед самым выходом сбрасываю, вроде стоит, вроде работает. Но что-то уж через чур по бубуински, наверно это не правильно, как грамотно тут разрулить?
VC>>Логике не протеворечит ибо очередь DPC не расчитана более чем на одного человека, т.е. если у меня и сгенерятся в плате несколько разных, но близких по времени прерывания, все кроме первого будут потеряны, но для этого в плате приняты меры что бы такого не происходило, что бы ОС успевала выгребать.
ГМ>--
ГМ>Как раз наоборот — в один и тот же момент процедура ISR может работать только одна (из-за спинлока прерывания), а вот DPC, поставленных в очередь этой ISR и даже одновременно выполняющихся на разных процессорах, может быть в принципе сколько угодно много.
Это верно, я о другом. У меня в ISR проверка если есть уже в очереди DPC, то этот вызов ISR пройдет впустую.


VC>>И вообще может быть такое что оба ядра берутся за обслуживания прерывания одновременно в силу стечения каких-то обстоятельств (ну например планировщик не имел более приоритетных прерываний)?

ГМ>--
ГМ>Нет, такого быть не может (см. выше о спинлоках).
имелось ввиду тож немного иное что скажем сначала одно ядро реагирует на прерывание, а потом вскоре и второе

ГМ>Могу предложить несколько подходов:

ГМ>1. Всю обработку прерывания выполнять только в ISR, в DPC выносить только то, что нельзя делать на "высоких" IRQL (например, установку event и т.п.).
да там так почти и есть, если дальше выносить в ISR, то система начнет тормозить
ГМ>2. Иметь гарантированно одну DPC на каждую ISR — этого можно достичь маскированием прерывания в ISR (но не его сбросом!), запуском DPC на выполнение (понятно, что раз линия прерывания замаскирована и сброшена, то новые возможные прерывания не вызовут новую ISR), в DPC уже обрабатывать прерывания, вычитывая признаки прерывания и сбрасывая их, в конце DPC отменить маскирование, разрешив, таким образом новые прерывания.
примерно понял, надо подумать
ГМ>3. Защищать DPC от повторного входа с помощью InterlockXXX функций — одна DPC захватывает глобальную переменную и, успешно захватив ее, начинает работу с платой, обрабатывая признаки прерываний и сбрасывая их, а все остальные, которым посчастливилось работать паралельно, просто выходят из DPC (они попытались захватить переменную и не смогли и, понимая, что в это время кто-то другой уже работает, просто заканчивают свою работу).
надо попробовать , просто похоже что все вклинивает как раз на этапе повтороного вызова ISR во время работы DPC, до повтороного вызова DPC кажись не доходит дело

ГМ>В принципе, возможно и другие варианты работы, в зависимости от реализации контроллера прерываний на плате.
Re[3]: Проблемка с драйвером на двуядерном проце
От: Геннадий Майко США  
Дата: 19.09.07 12:24
Оценка:
Здравствуйте, V-ctor,

ГМ>>Ваша процедура обработки прерывания ISR вполне может быть вызвана второй раз до того, как начнет выполняться DPC, поставленное в очеред вызванной ранее первой ISR (если при выходе из ISR она сбросила признак прерывания в плате). К этому надо быть готовым.

VC>че-т я тут недопонимаю, почему она будет повторно вызвана если я сбросил первый раз прерывание?
--
Представьте себе, что после сброса прерывания и выхода из ISR, но до входа в DPC, Ваша плата еще раз сгенерировала прерывание. Другими словами, время между окончанием ISR и началом DPC не определено и, в принципе, может быть достаточно большим.



VC>>>завел переменную-флаг в ISR проверяю установлен? тогда выход с возвратом false иначе выставляем флаг и отрабаываем по полной "программе", а потом в конце DPC перед самым выходом сбрасываю, вроде стоит, вроде работает. Но что-то уж через чур по бубуински, наверно это не правильно, как грамотно тут разрулить?

VC>>>Логике не протеворечит ибо очередь DPC не расчитана более чем на одного человека, т.е. если у меня и сгенерятся в плате несколько разных, но близких по времени прерывания, все кроме первого будут потеряны, но для этого в плате приняты меры что бы такого не происходило, что бы ОС успевала выгребать.
ГМ>>--
ГМ>>Как раз наоборот — в один и тот же момент процедура ISR может работать только одна (из-за спинлока прерывания), а вот DPC, поставленных в очередь этой ISR и даже одновременно выполняющихся на разных процессорах, может быть в принципе сколько угодно много.
VC>Это верно, я о другом. У меня в ISR проверка если есть уже в очереди DPC, то этот вызов ISR пройдет впустую.
--
Что значит "впустую"?

Если Вы не сбрасываете каким-то образом запрос прерывания (PCI INTA), то сразу же после выхода из ISR (с любым возвращаемым значением), она будет сразу-же вызвана еще раз.

Или "впустую" означает, что DPC не будет в этом случае вызванна?

Кроме того, меня немного смущает возвращение "false" из ISR в том случае, если Вы определили, что это прерывание от Вашей платы.



VC>имелось ввиду тож немного иное что скажем сначала одно ядро реагирует на прерывание, а потом вскоре и второе

--
Да, такое вполне возможно, если Вы, при "подключении" процедуры прерывания, задаете Afinity с несколькими установленными битами.

С уважением,
Геннадий Майко.
Re[4]: Проблемка с драйвером на двуядерном проце
От: V-ctor  
Дата: 19.09.07 12:47
Оценка:
Здравствуйте, Геннадий Майко, Вы писали:

ГМ>Здравствуйте, V-ctor,


ГМ>>>Ваша процедура обработки прерывания ISR вполне может быть вызвана второй раз до того, как начнет выполняться DPC, поставленное в очеред вызванной ранее первой ISR (если при выходе из ISR она сбросила признак прерывания в плате). К этому надо быть готовым.

VC>>че-т я тут недопонимаю, почему она будет повторно вызвана если я сбросил первый раз прерывание?
ГМ>--
ГМ>Представьте себе, что после сброса прерывания и выхода из ISR, но до входа в DPC, Ваша плата еще раз сгенерировала прерывание. Другими словами, время между окончанием ISR и началом DPC не определено и, в принципе, может быть достаточно большим.
Эт я себе ясно представляю, я не представляю другое: если такое явление имело бы место быть, то почему на одноядерном камне не давало бы о себе знать?



VC>>>>завел переменную-флаг в ISR проверяю установлен? тогда выход с возвратом false иначе выставляем флаг и отрабаываем по полной "программе", а потом в конце DPC перед самым выходом сбрасываю, вроде стоит, вроде работает. Но что-то уж через чур по бубуински, наверно это не правильно, как грамотно тут разрулить?

VC>>>>Логике не протеворечит ибо очередь DPC не расчитана более чем на одного человека, т.е. если у меня и сгенерятся в плате несколько разных, но близких по времени прерывания, все кроме первого будут потеряны, но для этого в плате приняты меры что бы такого не происходило, что бы ОС успевала выгребать.
ГМ>>>--
ГМ>>>Как раз наоборот — в один и тот же момент процедура ISR может работать только одна (из-за спинлока прерывания), а вот DPC, поставленных в очередь этой ISR и даже одновременно выполняющихся на разных процессорах, может быть в принципе сколько угодно много.
VC>>Это верно, я о другом. У меня в ISR проверка если есть уже в очереди DPC, то этот вызов ISR пройдет впустую.
ГМ>--
ГМ>Что значит "впустую"?

ГМ>Если Вы не сбрасываете каким-то образом запрос прерывания (PCI INTA), то сразу же после выхода из ISR (с любым возвращаемым значением), она будет сразу-же вызвана еще раз.

нет нет, все сбрасывается

ГМ>Или "впустую" означает, что DPC не будет в этом случае вызванна?

именно это

ГМ>Кроме того, меня немного смущает возвращение "false" из ISR в том случае, если Вы определили, что это прерывание от Вашей платы.

ну да, тут я что-то сглупил



VC>>имелось ввиду тож немного иное что скажем сначала одно ядро реагирует на прерывание, а потом вскоре и второе

ГМ>--
ГМ>Да, такое вполне возможно, если Вы, при "подключении" процедуры прерывания, задаете Afinity с несколькими установленными битами.
нет Afinity я не трогаю
Re[5]: Проблемка с драйвером на двуядерном проце
От: Геннадий Майко США  
Дата: 19.09.07 13:06
Оценка:
Здравствуйте, V-ctor,

ГМ>>>>Ваша процедура обработки прерывания ISR вполне может быть вызвана второй раз до того, как начнет выполняться DPC, поставленное в очеред вызванной ранее первой ISR (если при выходе из ISR она сбросила признак прерывания в плате). К этому надо быть готовым.

VC>>>че-т я тут недопонимаю, почему она будет повторно вызвана если я сбросил первый раз прерывание?
ГМ>>--
ГМ>>Представьте себе, что после сброса прерывания и выхода из ISR, но до входа в DPC, Ваша плата еще раз сгенерировала прерывание. Другими словами, время между окончанием ISR и началом DPC не определено и, в принципе, может быть достаточно большим.
VC>Эт я себе ясно представляю, я не представляю другое: если такое явление имело бы место быть, то почему на одноядерном камне не давало бы о себе знать?
--
Вы, случайно, в DPC Вы поднимаете IRQL до уровня device IRQL (например, чтобы таким образом "защитить" доступ к регистрам платы от ISR)?

С уважением,
Геннадий Майко.
Re[6]: Проблемка с драйвером на двуядерном проце
От: V-ctor  
Дата: 19.09.07 13:43
Оценка:
ГМ>>>>>Ваша процедура обработки прерывания ISR вполне может быть вызвана второй раз до того, как начнет выполняться DPC, поставленное в очеред вызванной ранее первой ISR (если при выходе из ISR она сбросила признак прерывания в плате). К этому надо быть готовым.
VC>>>>че-т я тут недопонимаю, почему она будет повторно вызвана если я сбросил первый раз прерывание?
ГМ>>>--
ГМ>>>Представьте себе, что после сброса прерывания и выхода из ISR, но до входа в DPC, Ваша плата еще раз сгенерировала прерывание. Другими словами, время между окончанием ISR и началом DPC не определено и, в принципе, может быть достаточно большим.
VC>>Эт я себе ясно представляю, я не представляю другое: если такое явление имело бы место быть, то почему на одноядерном камне не давало бы о себе знать?
ГМ>--
ГМ>Вы, случайно, в DPC Вы поднимаете IRQL до уровня device IRQL (например, чтобы таким образом "защитить" доступ к регистрам платы от ISR)?
эммм... нет, не поднимаю. надо?
Re[7]: Проблемка с драйвером на двуядерном проце
От: Геннадий Майко США  
Дата: 19.09.07 14:14
Оценка:
Здравствуйте, V-ctor,

ГМ>>>>>>Ваша процедура обработки прерывания ISR вполне может быть вызвана второй раз до того, как начнет выполняться DPC, поставленное в очеред вызванной ранее первой ISR (если при выходе из ISR она сбросила признак прерывания в плате). К этому надо быть готовым.

VC>>>>>че-т я тут недопонимаю, почему она будет повторно вызвана если я сбросил первый раз прерывание?
ГМ>>>>--
ГМ>>>>Представьте себе, что после сброса прерывания и выхода из ISR, но до входа в DPC, Ваша плата еще раз сгенерировала прерывание. Другими словами, время между окончанием ISR и началом DPC не определено и, в принципе, может быть достаточно большим.
VC>>>Эт я себе ясно представляю, я не представляю другое: если такое явление имело бы место быть, то почему на одноядерном камне не давало бы о себе знать?
ГМ>>--
ГМ>>Вы, случайно, в DPC Вы поднимаете IRQL до уровня device IRQL (например, чтобы таким образом "защитить" доступ к регистрам платы от ISR)?
VC>эммм... нет, не поднимаю. надо?
--
Well, это зависит от того, к каким именно регистрам обращаются в ISR и DPC и важна ли при этом "атомарная" последовательность обращений.
Но я собственно задавал этот вопрос для того, чтобы выяснить, не "маскируете" ли Вы таким образом прерывания от платы... Похоже, что нет.

C уважением,
Геннадий Майко.
Re[8]: Проблемка с драйвером на двуядерном проце
От: V-ctor  
Дата: 07.11.07 07:55
Оценка:
Решил я проблему, вдруг кому пригодится

решение оказалось простое, достаточно было вынести процедуру инициализации и запуска DMA в KeSynchronizeExecution() и все полечилось.
Почему так? фиг знает вроде казалось бы ну чего страшного если в процессе настройки DMA сработает ISR и просто отметит, что было прерывание, поменяет значения некоторых (не относящихся к DMA) байтиков в плате, запланирует DPC и выйдет? но все полечилось и слава богу. Там в моем камне вообще немного капризный контроллер DMA, поменял чуть порядок инициализации регистров и все, ведет себя необъяснимо
камень повторюсь BF535 (BlackFin)

Правила форума нарушены.
— оверквотинг
Правила можно найти в разделе FAQ данного форума и\или ресурса.
Нарушение правил может повлечь за собой санкции, описанные там же — модератор
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.