воскресенье, 13 октября 2013 г.

Бесконечный цикл в Driver Entry

Увидел на wasm.ru любопытный топик:

http://wasm.ru/forum/viewtopic.php?pid=538900#p538900

Содержание:

IRQL = 0. DriverEntry.
Если сделать бесконечный цикл, то на системе с одним процессором всё жутко начинает лагать - обычные приложения только через секунд 10 реагирует на клик мыши. Почему такое происходит? Ведь у кода драйвера IRQL =  0   =>  по хорошему процессор должен отдавать равное количество времени и драйверу и пользовательскому коду(он ведь выполняется тоже на IRQL = 0).

Далее в топике идут пространные рассуждения на тему.

Мне показалось это интересным, и в данной заметке я тоже порассуждаю, есть ли разница между выполнением кода в р0 в driver entry при irql ==PASSIVE LEVEL и в р3( где как известно, весь код также выполняется на PASSIVE LEVEL ).

Разница, разумеется есть. Дело вот в чем: driver entry драйвера выполняется в workitem'e, причем управление из workitem'a не вернется до тех пор, пока не отработает driver entry.

А workitem'ы, они же системные потоки это ценный ресурс, как подсказывает нам MSDN: System worker threads are a limited resource.

По факту, в системе есть несколько очередей с рабочими потоками;

typedef enum _WORK_QUEUE_TYPE
{
    CriticalWorkQueue,
    DelayedWorkQueue,
    HyperCriticalWorkQueue,
    MaximumWorkQueue
} WORK_QUEUE_TYPE;

KQUEUE ExWorkerQueue[MaximumWorkQueue];

Каждый тип очереди воркитемов разребает определенное количество потоков.

Как выше уже писалось, точка входа драйвера обрабатывается в воркитеме, и если там бесконечный цикл - мы просто забираем у системы один из системных потоков. А для DelayedWorkQueue очереди их всего 2-3!

Так в чем проблема? Забираем и забираем, что с того?

Проблема в том, что воркитемы активно используются системой, это и обнуление страниц( C2-level Security требование ) и Wmi/Etw и аудит и errorlog и реестр и page writer и прочие.

Безусловно, наиболее критичные для системы воркитемы находятся в CriticalWorkQueue, которую обслуживает большое количество системных потоков. Однако, на быстродействие системы может повлиять и воркитемы из DelayedWorkQueue, что видимо и происходит в описанном на wasm случае.

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