Здравствуйте, Аноним, Вы писали:
SS>>Вы путаете IRQL и приоритеты потоков
А>В двух словах, если не сложно, что же это такое — IRQL ?
Поток не имеет такого атрибута, как IRQL (в отличие от приоритета, который используется планировщиком). IRQL — это атрибут источника прерывания. Если приоритет прерывания выше, чем текущий IRQL на процессоре, то процессор вызывает обработчик этого прерывания, сохранив контекст прерванного потока. Перед тем как прерывание будет обслужено, текущий IRQL повышается до уровня, сопоставленного источнику прерывания. После этого IRQL понижается до прежнего уровня, и возобновляется выполнение прерванного потока (или материализуются новые прерывания, которые были замаскированы, пока IRQL на процессоре был высоким).
В режиме ядра вы можете менять текущий IRQL, вызывая функции KeRaise/KeLowerIrql, тем самым запрещая или разрешая определенные прерывания. Например, повысив IRQL до DPC/DISPATCH_LEVEL, вы запретите перепланировку потока, которая запускается в виде программного прерывания (DPC) на DISPATCH_LEVEL. Этот факт используется при реализации спинлока на однопроцессорной машине, например.
Кстати, именно потому, что на IRQL >= DISPATCH_LEVEL, запрещена перепланировка и переключение задач, на этих уровнях IRQL нельзя ждать на объекте синхронизации. Ведь если объект синхронизации занят, системе пришлось выполнить перепланировку, которая невозможна на IRQL >= DISPATCH_LEVEL. Из этого имеется еще одно интересное следствие — нельзя обращаться к выгружаемой памяти, т.к. в результате обработки ошибки страницы, нужно будет опять-таки ждать, пока страница загрузится в память.
ГМ>Вы написали "для того, чтобы некоторой поток не был прерван другим потоком", а похоже, что при этом Вы имели в виду "для того, чтобы некоторой поток не был прерван". Чувствуете разницу? ГМ>Так на какой вопрос отвечать?
Э-хе-хех... Это одно и то же на самом деле. Я довольно точно сформулировал вопрос. Поток может быть прерван кем? Только другим потоком, верно? Ну вот. Те же обработчики прерываний тоже ведь работают в каком-то потоке ядра. Двоякого толкования моего вопроса быть не может, я имел в виду именно то, что сказал. Меня не интересует, будет ли поток уничтожен или нет, будет он приостановлен или нет, будет он прерван планировщиком или же по прерыванию/исключению. Мне нужно, чтобы в каждый момент определённого интервала выполнялся мой и только мой код.
Что такое IRQL ?
От:
Аноним
Дата:
30.03.07 12:39
Оценка:
Вот пользовался этим и никогда не знал что же это обозначает. Нашёл пару статей, интересную книжку и сделал вывод такой:
Interrupt Request Level (IRQL) — это некое свойство потока (чем то похожее на приоритет). Оно означает, что потоки с более низким IRQL не смогут вытеснить поток с более высоким IRQL.
Повышение IRQL изпользуется для того, чтобы поток смог выполнить какие-либо важные действия немедленно. Посколько поток с высоким IRQL не может быть вытеснен другими, то такой поток должен закончить свою работу как можно скорее и понизить свой IRQL обратно.
Вопросы:
1. Правильно ли я понял, и если нет, то как правильно?
2. Если правильно, то если у какого-либо потока максимальный IRQL (= 31 вроде), означает ли это, что его не сможет вытеснить никакой другой поток?
Здравствуйте, Аноним, Вы писали:
А>1. Правильно ли я понял, и если нет, то как правильно? А>2. Если правильно, то если у какого-либо потока максимальный IRQL (= 31 вроде), означает ли это, что его не сможет вытеснить никакой другой поток?
Вы путаете IRQL и приоритеты потоков
Re[2]: Что такое IRQL ?
От:
Аноним
Дата:
30.03.07 12:56
Оценка:
SS>Вы путаете IRQL и приоритеты потоков
В двух словах, если не сложно, что же это такое — IRQL ?
Здравствуйте, Аноним, Вы писали:
А>Interrupt Request Level (IRQL) — это некое свойство потока (чем то похожее на приоритет). Оно означает, что потоки с более низким IRQL не смогут вытеснить поток с более высоким IRQL.
нет,
IRQL — per processor, показывает какие прерывания будет обрабатывать процессор, IRQL может изменяться системой
Спасибо за исчерпывающее объяснение!
Т.е. если все процессоры поднять до IRQL = DISPATCH_LEVEL, то поток, который сделал это, гарантированно не будет прерван другими потоками, да?
Здравствуйте, Аноним, Вы писали:
А>Т.е. если все процессоры поднять до IRQL = DISPATCH_LEVEL, то поток, который сделал это, гарантированно не будет прерван другими потоками, да?
Потоку достаточно поднять IRQL до DISPATCH_LEVEL на текущем процессоре, чтобы избежать переключения задач на текущем процессоре. При этом выполнение потока может быть прервано для обслуживания прерываний от устройств.
Re[6]: Что такое IRQL ?
От:
Аноним
Дата:
30.03.07 14:13
Оценка:
SS>Потоку достаточно поднять IRQL до DISPATCH_LEVEL на текущем процессоре, чтобы избежать переключения задач на текущем процессоре. При этом выполнение потока может быть прервано для обслуживания прерываний от устройств.
Понял. Т.е. чтобы поток вообще не был прерван никем, нужно сделать две вещи:
1. Поднять IRQL на всех процессорах до DISPATCH_LEVEL
2. Запретить прерывания — cli
Здравствуйте, Аноним, Вы писали:
А>Понял. Т.е. чтобы поток вообще не был прерван никем, нужно сделать две вещи:
Мне кажется вы смешивате переключение задач, которое инициируется планировщиком, и прерывание потока, в результате обработки прерывания или исключения. Обработка прерывания/исключения происходит без переключения задач.
А>1. Поднять IRQL на всех процессорах до DISPATCH_LEVEL
Чтобы запретить переключение задач на текущем процессоре, можно поднять IRQL до уровня DISPATCH_LEVEL. Это гарантирует, что поток не будет вытеснен в результате перепланировки. Это отнюдть не означает, что выполнение потока не может быть прервано для обработки прерывания или исключения.
А>2. Запретить прерывания — cli
Зачем? Чего добиться хотите?
Re[8]: Что такое IRQL ?
От:
Аноним
Дата:
30.03.07 14:56
Оценка:
SS>Зачем? Чего добиться хотите?
Если все процессоры перевести на DISPATCH_LEVEL, то это позволить уберечь поток от перепланировки. Но вы сказали, что поток может быть также прерван и по прерыванию или исключению. Если недопускать (методом прямых рук ) возникновения исключений, то остаются прерывания. Т.о. если их запретить, то не останеться факторов, которые могли бы инициировать перепланировку. А значит поток не будет прерван. Я прав?
Здравствуйте, Sergey Storozhevykh, Вы писали:
SS>Зачем? Чего добиться хотите?
Предположу, что речь идет о том, как атомарно пропатчить ядро — не имея риска, что во время изменения какого-то адреса поток на другом процессоре выполнит заменяемый код.
Здравствуйте, Аноним, Вы писали:
А>Вот пользовался этим и никогда не знал что же это обозначает. Нашёл пару статей, интересную книжку и сделал вывод такой:
А>Interrupt Request Level (IRQL) — это некое свойство потока (чем то похожее на приоритет). Оно означает, что потоки с более низким IRQL не смогут вытеснить поток с более высоким IRQL.
А>Повышение IRQL изпользуется для того, чтобы поток смог выполнить какие-либо важные действия немедленно. Посколько поток с высоким IRQL не может быть вытеснен другими, то такой поток должен закончить свою работу как можно скорее и понизить свой IRQL обратно.
А>Вопросы:
А>1. Правильно ли я понял, и если нет, то как правильно? А>2. Если правильно, то если у какого-либо потока максимальный IRQL (= 31 вроде), означает ли это, что его не сможет вытеснить никакой другой поток?
--
Прочитайте дополнительно вот эту статью "Scheduling, Thread Context, and IRQL", вполне возможно, после этого Вы сами сможете ответить на эти вопросы.
C уважением,
Геннадий Майко.
Re[2]: Что такое IRQL ?
От:
Аноним
Дата:
30.03.07 16:49
Оценка:
ГМ>Прочитайте дополнительно вот эту статью "Scheduling, Thread Context, and IRQL", вполне возможно, после этого Вы сами сможете ответить на эти вопросы.
Вот за статью — огромное спасибо.
Я так понял, следующий абзац отвечает на вопрос о вытеснении потоков:
DISPATCH_LEVEL DISPATCH_LEVEL is the highest software interrupt level and the first processor-specific level. The Windows thread scheduling and dispatching components (collectively called “the dispatcher”) run at IRQLDISPATCH_LEVEL. Some other kernel-mode support routines, some driver routines, and all deferred procedure calls (DPCs) also run at IRQLDISPATCH_LEVEL. While the processor operates at this level, one thread cannot pre-empt another; only a hardware interrupt can interrupt the running thread. To maximize overall system throughput, driver code that runs at DISPATCH_LEVEL should perform only the minimum amount of required processing.
А это про ограничения кода, выполняющегося на этом IRQL:
Because code that is running at DISPATCH_LEVEL cannot be pre-empted, the operations that a driver can perform at DISPATCH_LEVEL are restricted. Any code that must wait for an object that another thread sets or signals asynchronously—such as an event, semaphore, mutex, or timer—cannot run at DISPATCH_LEVEL because the waiting thread cannot block while waiting for the other thread to perform the action. Waiting for a nonzero period on such an object while at DISPATCH_LEVEL causes the system to deadlock and eventually to crash.
Хотя впрочем, об этом мне уже говорили. Просто скажите, я прав или нет в следующем утверждении, это для меня самое главное.
Я утверждаю, что для того, чтобы некоторой поток не был прерван другим потоком, необходимо и достаточно на всех процессорах сделать две вещи:
1. Перевести процессор на DISPATCH_LEVEL
2. Запретить прерывания — cli
Здравствуйте, Аноним,
А>Я утверждаю, что для того, чтобы некоторой поток не был прерван другим потоком, необходимо и достаточно на всех процессорах сделать две вещи:
А>1. Перевести процессор на DISPATCH_LEVEL А>2. Запретить прерывания — cli
А>Так это или нет?
--
Если Вы действительно спрашиваете то, что выделено выше, то нет. Для этого достаточно поднять IRQL данного процессора до DISPATCH_LEVEL — "While the processor operates at this level, one thread cannot pre-empt another". Однако это не значит, что поток не может быть прерван вообще.
C уважением,
Геннадий Майко.
Re[4]: Что такое IRQL ?
От:
Аноним
Дата:
30.03.07 17:04
Оценка:
ГМ>Если Вы действительно спрашиваете то, что выделено выше, то нет. Для этого достаточно поднять IRQL данного процессора до DISPATCH_LEVEL — "While the processor operates at this level, one thread cannot pre-empt another". Однако это не значит, что поток не может быть прерван вообще.
Позвольте, а как же прерывания?! Ведь код обработчика прерывания (например, от девайса) вытеснит мой код! Для этого я и хочу запрещать прерывания.
Здравствуйте, Аноним, Вы писали:
ГМ>>Если Вы действительно спрашиваете то, что выделено выше, то нет. Для этого достаточно поднять IRQL данного процессора до DISPATCH_LEVEL — "While the processor operates at this level, one thread cannot pre-empt another". Однако это не значит, что поток не может быть прерван вообще.
А>Позвольте, а как же прерывания?! Ведь код обработчика прерывания (например, от девайса) вытеснит мой код! Для этого я и хочу запрещать прерывания.
--
Извините, я могу отвечать только на Ваши вопросы; я не могу отвечать на то, что Вы подумали, формулирую Ваш вопрос.
Вы написали "для того, чтобы некоторой поток не был прерван другим потоком", а похоже, что при этом Вы имели в виду "для того, чтобы некоторой поток не был прерван". Чувствуете разницу?
Так на какой вопрос отвечать?
C уважением,
Геннадий Майко.
Re[9]: Что такое IRQL ?
От:
Аноним
Дата:
30.03.07 17:39
Оценка:
I>Предположу, что речь идет о том, как атомарно пропатчить ядро — не имея риска, что во время изменения какого-то адреса поток на другом процессоре выполнит заменяемый код.
Похоже на то, но в таком случае разочарую опикстартера — это все не поможет если другой поток был прерван в процессе исполнения патчиваемого кода.
Здравствуйте, Аноним, Вы писали:
ГМ>>Вы написали "для того, чтобы некоторой поток не был прерван другим потоком", а похоже, что при этом Вы имели в виду "для того, чтобы некоторой поток не был прерван". Чувствуете разницу? ГМ>>Так на какой вопрос отвечать?
А>Э-хе-хех... Это одно и то же на самом деле. Я довольно точно сформулировал вопрос. Поток может быть прерван кем? Только другим потоком, верно?
--
Нет, не правильно.
Поток может быть прерван не только другим потоком, но и, например, обработчиком прерывания, DPC, APC.
А>Те же обработчики прерываний тоже ведь работают в каком-то потоке ядра.
--
Нет, не правильно.
Обработчики прерывания не работают в каком-то (конкретном) потоке. Они прерывают текущий, в общем случае неопределенный и неизвестный (arbitrary) поток на некотором процессоре и работают в его контексте.
А>Мне нужно, чтобы в каждый момент определённого интервала выполнялся мой и только мой код.
А>Я утверждаю, что для того, чтобы некоторой поток не был прерван другим потоком, необходимо и достаточно на всех процессорах сделать две вещи:
А>1. Перевести процессор на DISPATCH_LEVEL А>2. Запретить прерывания — cli
--
Если убрать слова "другим потоком" выше, то в принципе да, так можно попытаться сделать.
С уважением,
Геннадий Майко.
Re[8]: Что такое IRQL ?
От:
Аноним
Дата:
30.03.07 17:57
Оценка:
ГМ>Обработчики прерывания не работают в каком-то (конкретном) потоке. Они прерывают текущий, в общем случае неопределенный и неизвестный (arbitrary) поток на некотором процессоре и работают в его контексте.
Понял, спасибо.
А>>Я утверждаю, что для того, чтобы некоторой поток не был прерван другим потоком, необходимо и достаточно на всех процессорах сделать две вещи: А>>1. Перевести процессор на DISPATCH_LEVEL А>>2. Запретить прерывания — cli
ГМ>Если убрать слова "другим потоком" выше, то в принципе да, так можно попытаться сделать.
Хорошо, теперь я понимаю, какую разницу между "поток прерван" и "поток прерван другим потоком" вы имели в виду и извиняюсь за свою самоуверенность Просто я не знал, где выполняются обработчики прерываний
Настораживают меня только ваши слова "можно попытаться сделать" В чём здесь загвоздка?
Здравствуйте, Аноним,
А>Настораживают меня только ваши слова "можно попытаться сделать" В чём здесь загвоздка?
--
— Как гарантированно и одновременно получить управление на всех процессорах?
— Как запретить прерывания, не прибегая к ассемблерным коммандам?
C уважением,
Геннадий Майко.
Re[10]: Что такое IRQL ?
От:
Аноним
Дата:
30.03.07 18:31
Оценка:
ГМ>- Как гарантированно и одновременно получить управление на всех процессорах?
Я думал сделать так:
1. KeFlushQueuedDpcs()
2. кол-во процессоров, переведённый на DISPATCH_LEVEL:
ULONG guDispatchProcessors = 0;
3. проверить текущий IRQL:
if (KeGetCurerntIrql () != DISPATCH_LEVEL) return FALSE;
Затем в цикле по KeNumberProcessors (для всех процессоров, кроме текущего):
9. следующий код не будет вытеснен другим и не будет прерван...
Что скажете? Может помочь? Вычитал похожее в одной книжке, наверно её автор знал, что писал, тем более что во всём остальном он не наврал. Хотелось бы услышать ваше мнение.
ГМ>- Как запретить прерывания, не прибегая к ассемблерным коммандам?
убедительная просьба следить за объемом цитирования — модератор
А>Что скажете? Может помочь? Вычитал похожее в одной книжке, наверно её автор знал, что писал, тем более что во всём остальном он не наврал. Хотелось бы услышать ваше мнение.
--
Да, за исключением кое-каких мелочей, в целом верно.
Я уже писал об этом здесь
Здравствуйте, <Аноним>, Вы писали:
А>2. Запретить прерывания — cli
Это поднимет IRQL до HIGH_LEVEL
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, <Аноним>, Вы писали:
А>это все не поможет если другой поток был прерван в процессе исполнения патчиваемого кода.
Это всё значит, что выполняемый на IRQL >= DISPATCH_LEVEL код можно патчить.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, Sergey Storozhevykh, Вы писали:
SS>Поток не имеет такого атрибута, как IRQL (в отличие от приоритета, который используется планировщиком). IRQL — это атрибут источника прерывания.
И процессора вместе с ним. В системах, из которых растут ноги NT (RSX-11, к примеру), оно так и называется — "приоритет процессора" и "приоритет источника прерывания".
Здравствуйте, Евгений Музыченко,
SS>>Поток не имеет такого атрибута, как IRQL (в отличие от приоритета, который используется планировщиком). IRQL — это атрибут источника прерывания.
ЕМ>И процессора вместе с ним.
--
Точнее, "IRQLs at or above DISPATCH_LEVEL are processor specific...IRQLs below DISPATCH_LEVEL are thread specific."
Здравствуйте, Геннадий Майко, Вы писали:
ГМ>Точнее, "IRQLs at or above DISPATCH_LEVEL are processor specific...IRQLs below DISPATCH_LEVEL are thread specific."
Ну да, с единственной поправкой на APC_LEVEL И тот явно был введен лишь для того, чтобы не придумывать новой сущности.
Здравствуйте, Евгений Музыченко,
ГМ>>Точнее, "IRQLs at or above DISPATCH_LEVEL are processor specific...IRQLs below DISPATCH_LEVEL are thread specific."
ЕМ>Ну да, с единственной поправкой на APC_LEVEL И тот явно был введен лишь для того, чтобы не придумывать новой сущности.
--
Если быть еще точнее , между PASSIVE_LEVEL и APC_LEVEL есть еще один уровень — "IRQL PASSIVE_LEVEL in a critical region".
C уважением,
Геннадий Майко.
Re[12]: Что такое IRQL ?
От:
Аноним
Дата:
02.04.07 06:50
Оценка:
ГМ>Да, за исключением кое-каких мелочей, в целом верно.
Спасибо. Мне было очень интересно ваше мнение. Единственное для меня остался непонятный момент — зачем в DPC routine повышать IRQL до IPI_LEVEL — 1:
Функция DPC:
1. Raise IRQL to the IPI_LEVEL — 1. This will prevent the folowing code in this DPC from the hardware inperrupts on this particular processor.
ГМ>Well, а если команда запрета прерывания процессора называется не cli?
А разве на этапе исполения есть разница как она называется?
ГМ>Я надеюсь, Вы не будете использовать этот подход для атомарного изменения участка кода?
Именно для этого я и хочу его заюзать. А также для модификации некоторых структур ярда.
Вы видите здесь проблему? Где именно?
Здравствуйте, Аноним,
ГМ>>Да, за исключением кое-каких мелочей, в целом верно.
А> Единственное для меня остался непонятный момент — зачем в DPC routine повышать IRQL до IPI_LEVEL — 1:
А>
А>Функция DPC:
А>1. Raise IRQL to the IPI_LEVEL — 1. This will prevent the folowing code in this DPC from the hardware inperrupts on this particular processor.
--
Здесь же написано — чтобы DPC не была прервана ничем и, следовательно, монопольно "захватила" данный CPU. В принципе, это же нужно сделать и в основной ветке перед выполнением участка кода.
ГМ>>Well, а если команда запрета прерывания процессора называется не cli?
А>А разве на этапе исполения есть разница как она называется?
--
Я имел в виду (намекал), что лучше не пользоваться ассемблерными вставками — вдруг процессор не будет иметь такой команды и драйвер не скомпилируется...
ГМ>>Я надеюсь, Вы не будете использовать этот подход для атомарного изменения участка кода?
А>Именно для этого я и хочу его заюзать. А также для модификации некоторых структур ярда. А>Вы видите здесь проблему? Где именно?
--
Я об этом уже неоднократно писал и еще раз повторю — А что произойдет, если на другом процессоре как раз выполняется код, который замещается? Или поток был вытеснен как раз тогда, когда он выполнялся внутри этого участка?
С уважением,
Геннадий Майко.
Re[14]: Что такое IRQL ?
От:
Аноним
Дата:
02.04.07 07:36
Оценка:
ГМ>Здесь же написано — чтобы DPC не была прервана ничем и, следовательно, монопольно "захватила" данный CPU. В принципе, это же нужно сделать и в основной ветке перед выполнением участка кода.
Понял, спасибо.
ГМ>Я имел в виду (намекал), что лучше не пользоваться ассемблерными вставками — вдруг процессор не будет иметь такой команды и драйвер не скомпилируется...
Но ведь я-то знаю, что мой компилятор и целевой процессор поддерживают эту команду, так что здесь всё в порядке
ГМ>Я об этом уже неоднократно писал и еще раз повторю — А что произойдет, если на другом процессоре как раз выполняется код, который замещается? Или поток был вытеснен как раз тогда, когда он выполнялся внутри этого участка?
Да, есть такая проблема. Но от этого никуда не денешься. Хотя я сильно подозреваю, есть-таки жутко извращённый метод. Суть его в том, чтобы постоянно перечислять контексты всех потоков в системе и уловить-таки момент, когда ни один из потоков не будет выполняться в целевом участке. И в этот самый момент заморозить все потоки. Или просто поднять IRQL. Изврат конечно и далеко небезглючный вариант, но всё же лучше так, чем вообще без подстраховки.
Ну а в моём случае вероятностью попадания какого-либо потока в участок, который патчится, можно пренебречь.
Здравствуйте, Аноним,
А>Да, есть такая проблема. Но от этого никуда не денешься. Хотя я сильно подозреваю, есть-таки жутко извращённый метод. Суть его в том, чтобы постоянно перечислять контексты всех потоков в системе и уловить-таки момент, когда ни один из потоков не будет выполняться в целевом участке. И в этот самый момент заморозить все потоки. Или просто поднять IRQL. Изврат конечно и далеко небезглючный вариант, но всё же лучше так, чем вообще без подстраховки.
--
Мне кажется, что решить эту проблему можно с помощью своего мини-отладчика. И быть готовым к тому, что операция замены участка кода может закончиться неудачно.
А>Ну а в моём случае вероятностью попадания какого-либо потока в участок, который патчится, можно пренебречь.
--
Не забудьте сообщить, что за продукт Вы ваяете, чтобы мы держались от него подальше...
C уважением,
Геннадий Майко.
Re[16]: Что такое IRQL ?
От:
Аноним
Дата:
02.04.07 07:53
Оценка:
ГМ>Не забудьте сообщить, что за продукт Вы ваяете, чтобы мы держались от него подальше...
Где-то я уже слышал эту фразу
А ваяю я внутрений софт, не для паблика, так что будьте спокойны.