Страниц: 1 [2]
  Печать  
Автор Тема: Вытеснение обработчика прерывания таймера  (Прочитано 10629 раз)
Alex_tr
Участник
*
Offline Offline

Сообщений: 21


Просмотр профиля
« Ответ #15 : Мая 19, 2010, 09:52:38 am »


Вам шашечки или ехать? Наивысший приоритет системному таймеру есть смысл в одном случае: если система - часы. В любом другом случае работа по обслуживанию прерывания более приоритетна чем любой поток ждущий таймер.

Чем плох наивысший приоритет таймера? Обслуживание прерывания таймера ест минимальное количество времени, другим драйверам это не сильно помешает. Зато системные часы не убегут гарантированно. Разве четкий системный такт - не одно из преимуществ реал-тайм системы?
Записан
aluv
Sr. Member
****
Offline Offline

Сообщений: 301


Просмотр профиля
« Ответ #16 : Мая 19, 2010, 04:49:48 pm »

Зато системные часы не убегут гарантированно.

Часы убегут только если кварц с большой погрешностью или прерывания от Int 0 теряются.
Записан
ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #17 : Мая 19, 2010, 06:34:48 pm »

Чем плох наивысший приоритет таймера? Обслуживание прерывания таймера ест минимальное количество времени, другим драйверам это не сильно помешает. Зато системные часы не убегут гарантированно. Разве четкий системный такт - не одно из преимуществ реал-тайм системы?
Обслуживание прерываний от устройств, которые не системный таймер, не должно есть больше времени (речь о порядках величин). Не должно быть ни одного обработчика прерывания, который требует больше времени, чем системный тик (я имею ввиду реальный обработчик InterruptAttach(), а не поток InterruptAttachEvent()). Если теряются прерывания таймера, то или тик неразумно быстрый, или драйвер какой-то кривой.
Второе - перераспределение приоритетов контроллеру прерывания не решает но маскирует проблему. В самом начале дискуссии звучат фразы, как будто есть вытесняющая многозадачность при обработке прерываний - это неверно. Задавая приоритеты обработчиков, вы говорите контроллеру прерываний, о каком прерывании сообщить процессору сперва, если активных запросов несколько. Если высокоприоритетное прерывание пришло на мгновение позже, чем низкоприоритетное прерывание но с кривым (долгим) обработчиком, то вся проблема повторится. Потому как пока не обслужится предыдущее прерывание (т.е. ядро сообщит контроллеру прерываний "out 0x20 0x20" ) никакие последующие прерывания не обслуживаются. (много процессорные/ядерные системы с APIC оставим на потом - когда они будут поддерживаться)
Ну и последнее. Если у вас плата PCI это АЦП/ЦАП, которая получает информацию о положении задвижки в реакторе или поплавка на водозаборе и управляет этой задвижкой/шлюзом, то что важнее - обработать запрос от этой платы или от системного таймера? Или у вас коммуникационная система и данные в буферах сетевых карт накапливаются по нескольку раз за системный тик? Примем, что у вас жесткий реал-тайм с аппаратными защитами, авария не произойдет, но каждое переключение на резервный комплект или авост будут расследоваться. Вдруг кто-то вспомнит, что инженер отдал наивысший приоритет в системе таймеру? И, кстати, если у вас хороший кварц, но системное время плывет - это первый признак, что что то не в порядке. И прятать этот непорядок не хорошо.
Записан
ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #18 : Мая 19, 2010, 06:40:25 pm »

А забыл - а что такое четкий системный такт? Разве в виндовс или линукс будет не такой же четкий такт на том же железе с тем же кварцем?
Записан
vshemm
Sr. Member
****
Offline Offline

Сообщений: 317


Просмотр профиля
« Ответ #19 : Мая 20, 2010, 02:41:26 am »

В самом начале дискуссии звучат фразы, как будто есть вытесняющая многозадачность при обработке прерываний - это неверно. Задавая приоритеты обработчиков, вы говорите контроллеру прерываний, о каком прерывании сообщить процессору сперва, если активных запросов несколько. Если высокоприоритетное прерывание пришло на мгновение позже, чем низкоприоритетное прерывание но с кривым (долгим) обработчиком, то вся проблема повторится. Потому как пока не обслужится предыдущее прерывание (т.е. ядро сообщит контроллеру прерываний "out 0x20 0x20" ) никакие последующие прерывания не обслуживаются. (много процессорные/ядерные системы с APIC оставим на потом - когда они будут поддерживаться)
С этим не согласен Wink

Рассмотрим стандартный PIC (8259A). Обычно его использовали(-ют) в двух режимах: с аппаратной организацией приоритетов и без приоритетов вообще. В первом случае при возникновении прерывания маскируются все прерывания, уровень которых ниже или равен заданному (про настройку приоритетов тут уже говорили - это именно они), после чего на процессоре разрешаются прерывания и вызывается ISR. ISR работает с железкой, сбрасывает в ней источник прерывания и возвращает управление. Во время его работы вполне могут возникнуть новые, более приоритетные прерывания - схема остается той же: маскирование линий и вызов уже другого ISR. После возврата из ISR PIC-у посылается non-specific EOI, который размаскирует самую высокоприоритетное линию. Далее, если есть ждущие обработку более низкоприоритетные прерывания, происходит возврат в их прерванный ISR и т.д., пока будет хоть одно pending interrupt.
Во втором случае все тоже самое, только перед вызовом ISR маскируется одна линия. Соответственно, по окончанию работы ISR PIC-у посылается specific-EOI, который размаскирует только конкретную логическую линию.
Есть еще и третий вариант, с auto-EOI, но его мы трогать не будем Smiley.

В ранних unix использовался первый вариант, с меппингом аппаратных приоритетов на софтварные. Потом от этого постепенно отошли за ненадобностью (да и APIC с MSI появились), и используют второй вариант. Однако, во вмогих unix можно указать спец флаг при установке ISR для того, чтобы он работал при полностью заблокированных прерываниях (на локальном процессоре, на других CPU маскируется только данная линия). Разумеется, такой ISR должен выполняться быстро.

В Windows NT используют первый вариант с меппингом на IRQL. Типа, контроллеры прерываний разные бывают, сделаем-ка мы унифицированный дизайн. Там таймеру действительно дают высокий левел, выше него только IPI и всякая шняга типа power fail. Ниже - софтварные IRQL. В образовавшееся окно последовательно мепятся хардварные линии, при большом их количестве мепинг начинается с начала окна. Забавно, но в более новых версиях Windows размеры окна значительно уменьшили (до 8, если не ошибаюсь - лень смотреть). Так вот, при приходе прерывания замепленного, скажем, на IRQL15, маскируются все IRQL-ы ниже 16.

В QNX6, судя по всему, используется первый вариант как он есть, т.е. без дополнительных абстракций вроде IRQL. Соответственно, ISR-ы могут вытесняться более высокоприоритетными. Возможно, у ТС irq3 имел самый высокий приоритет по той же причине - чтобы irq10-15 имели более низкий приоритет, чем irq3-8 (на 14 и 15 сидят IDE устройства, обработчики которых могут тормозить). Ну а приоритет таймера при таком раскладе оказывается посередине, что в общем то, логично.

Напоследок хотелось бы повторить то, что говорили до меня: если изменения аппаратных приоритетов меняют поведение системы, значит дизайн этот системы плохой (сюда также относятся сторонние драйвера с "жирными" ISR-ми).

P.S. См. также Interrupt latency и Nested interrupts в http://www.qnx.com/developers/docs/6.3.2/neutrino/sys_arch/kernel.html
Записан
ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #20 : Мая 20, 2010, 06:54:02 am »

Рассмотрим стандартный PIC (8259A). Обычно его использовали(-ют) в двух режимах: с аппаратной организацией приоритетов и без приоритетов вообще. В первом случае при возникновении прерывания маскируются все прерывания, уровень которых ниже или равен заданному (про настройку приоритетов тут уже говорили - это именно они), после чего на процессоре разрешаются прерывания и вызывается ISR. ISR работает с железкой, сбрасывает в ней источник прерывания и возвращает управление. Во время его работы вполне могут возникнуть новые, более приоритетные прерывания - схема остается той же: маскирование линий и вызов уже другого ISR. После возврата из ISR PIC-у посылается non-specific EOI, который размаскирует самую высокоприоритетное линию. Далее, если есть ждущие обработку более низкоприоритетные прерывания, происходит возврат в их прерванный ISR и т.д., пока будет хоть одно pending interrupt.
Согласен. Не дали соврать. Что впрочем не отменяет всего другого сказанного. Второго и третьего варианта использования я не встречал. По виндовс НТ есть интересная статья:
http://www.joseflores.com/jf/docs/ExploringIrql.html
Если не рассматривать smp hal и поддержку apic, то в виндовс, в отличие от qnx драйвер может подсунуть свой обработчик примерно как InterruptAttachEvent, но никак не как InterruptAttach, при этом такой ожидающий прерывания поток выполняется на высоком приоритете - ни один юзерский поток не может быть выше, а в ядре только обработчики критических ошибок и профайлера выше, и этот поток может толкнуть другой поток (DPC) уже с более низким приоритетом, но все равно еще достаточно высоким.
Записан
Alex_tr
Участник
*
Offline Offline

Сообщений: 21


Просмотр профиля
« Ответ #21 : Мая 20, 2010, 11:48:06 am »


Напоследок хотелось бы повторить то, что говорили до меня: если изменения аппаратных приоритетов меняют поведение системы, значит дизайн этот системы плохой (сюда также относятся сторонние драйвера с "жирными" ISR-ми).

Все-таки хотелось услышать разумные доводы, почему "плохо". Система настраивается для конкретных целей под конкретную аппаратуру и разработчик может поменять приоритеты прерываний, назначив наивысший тому, которому он считает нужным. Так никто и не прояснил, чем может помешать наивысший париортиет таймера. Если ISR "жирный", то прерваться на обработку таймера ему врятли помешает.
Записан
QNX Worker
Jr. Member
**
Offline Offline

Сообщений: 99


Просмотр профиля
« Ответ #22 : Мая 20, 2010, 02:27:33 pm »

...Если устройство вызывает более 1000 прерываний в секунду, то нужно менять либо устройство, либо архитектуру драйвера и опрашивать устройство по другому...
Не согласен. У меня, например, под 6.4.1 устройство и система нормально работают имея более 5000 прерываний в секунду. Просто обработчик прерывания маленький надо делать. Вот и все.
Записан
LH
Full Member
***
Offline Offline

Сообщений: 128


Просмотр профиля
« Ответ #23 : Мая 20, 2010, 06:52:27 pm »

Цитировать
...Если устройство вызывает более 1000 прерываний в секунду, то нужно менять либо устройство, либо архитектуру драйвера и опрашивать устройство по другому...

У меня такой же вопрос к lestat: контроллер последовательного обмена USART на скорости 115200 производит примерно 10 000 прерываний в секунду при приеме данных. При каждом прерывании делается вызов tti() в системную библиотеку io-char. Что Вы предлагаете изменить в драйвере?

Записан
ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #24 : Мая 20, 2010, 09:19:34 pm »

115200 bod / 10 bit per char = 11520 char per second
8 bytes FIFO threshold -> 1440 interrupts per second
That was one of the reasons they invented FIFO...
Записан
ed1k
QOR.Moderator
*****
Offline Offline

Сообщений: 739


Просмотр профиля WWW
« Ответ #25 : Мая 20, 2010, 09:39:44 pm »

Рассмотрим стандартный PIC (8259A). Обычно его использовали(-ют) в двух режимах: с аппаратной организацией приоритетов и без приоритетов вообще. В первом случае при возникновении прерывания маскируются все прерывания, уровень которых ниже или равен заданному (про настройку приоритетов тут уже говорили - это именно они), после чего на процессоре разрешаются прерывания и вызывается ISR. ISR работает с железкой, сбрасывает в ней источник прерывания и возвращает управление. Во время его работы вполне могут возникнуть новые, более приоритетные прерывания - схема остается той же: маскирование линий и вызов уже другого ISR. После возврата из ISR PIC-у посылается non-specific EOI, который размаскирует самую высокоприоритетное линию. Далее, если есть ждущие обработку более низкоприоритетные прерывания, происходит возврат в их прерванный ISR и т.д., пока будет хоть одно pending interrupt.
Согласен. Не дали соврать.
Забыл добавить, что для полноты картины, нужно рассматривать связку 8259-х86, а именно, то, что ЦПУ входит в обработчик со сброшенным в ноль флагом разрешения прерываний, и чтобы обработчики таки вытесняли друг друга, прерывания должны разрешаться внутри обработчиков прерываний. И еще историческая справка - обработчики часто работают с портами ввода-вывода и прочими регистрами, так уж получилось, что было много железа, которое требовало полного владения шиной на весь цикл многобайтного обмена, т.е. нельзя было полупроинициализировать какую-то микросхему или полуобслужить VGA видеокарту, потом побыстрому обработать прерывание таймера, а потом закончить инициализацию-обслуживание.
Записан
Страниц: 1 [2]
  Печать  
 
Перейти в: