Mark Russinovich - Sysinternals Freeware - Information for Windows NT and Windows 2000 - Advanced DPCs

Здесь есть возможность читать онлайн «Mark Russinovich - Sysinternals Freeware - Information for Windows NT and Windows 2000 - Advanced DPCs» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Sysinternals Freeware - Information for Windows NT and Windows 2000 - Advanced DPCs: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Sysinternals Freeware - Information for Windows NT and Windows 2000 - Advanced DPCs»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Note: This article assumes you have some experience with NT device driver development.

Sysinternals Freeware - Information for Windows NT and Windows 2000 - Advanced DPCs — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Sysinternals Freeware - Information for Windows NT and Windows 2000 - Advanced DPCs», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Introduction

DPCs are a fundamental building block in NT's interrupt handling architecture. Interrupt servicing typically consists of two driver-provided components: an interrupt service routine (ISR) and a Deferred Procedure Call (DPC). ISR's execute at IRQL's above DISPATCH_LEVEL in the DIRQL range. Because one of NT's design goals is to spend as little time as possible at elevated IRQL, ISR's usually perform minimal interactions with their devices, normally just reading some state and getting the device to stop interrupting. The mechanism by which an ISR can finish processing at a lower IRQL is a DPC. Some time after an ISR requests a DPC, its DPC function will be called by NT at DISPATCH_LEVEL. While there are restrictions on what can be done at DISPATCH_LEVEL (e.g. touching pageable memory or blocking the thread), virtually nothing can be done from within an ISR. And of course, it is always possible to queue a worker thread work-item from a DPC so that interrupt processing can continue at PASSIVE_LEVEL.

While the NT DDK does a fairly good job of documenting DPCs and their use, there are some advanced DPC features that are not even mentioned. You might not find an immediate use for these features, but knowing that they are there can aid in your future driver designs. In this article I'm going to to describe how NT processes DPCs and document the exported NT functions that provide driver writers a finer degree of control over DPCs than the default APIs.

I/O Manager DPCs

Deferred Procedure Calls are managed in NT by a DPC kernel objects (as opposed to Executive objects such as semaphores, events, file objects). There are two ways that DPCs can be used. If a device will only have one interrupt in progress at time, then the I/O Manager's DPC functions can be used. This course would be the one that would be a logical choice if you are using system IRP queuing.

Two functions are used when you rely on the I/O Manager's DPC management. The first, IoInitializeDpcRequest, initializes a dpc object and associates it with a particular device object. If you refer to the NT DDK kernel-mode function reference you'll see that it takes just two parameters: a device object and the address of a deferred procedure call function being registered. The DPC object that is initialized is the one that is contained in a device object.

When your ISR wants to request a DPC it calls the I/O Manager function, IoRequestDpc. this function takes a pointer to a device object, a pointer to an IRP, and a context parameter. At some later point the deferred procedure call that was registered for the device will be called and is passed the DPC object, a pointer to the device object, pointer to the IRP, and the context argument.

Kernel DPCs

Underneath the I/O Manager functions described above are the Kernel functions that actually implement basic DPC functionality. A driver for a device that accepts multiple simultaneous I/O requests must use the Kernel functions directly, bypassing the I/O Manager convenience routines. There is a strong parallel between the two interfaces, however. Instead of calling IoInitializeDpcRequest, a driver's entry invokes the function KeInitializeDpcto initialize a dpc object. KeInitializeDpctakes a driver-allocated DPC object, a pointer to the deferred function and a context parameter that will be passed to the function. As with most driver-allocated data structures that are handed to the Kernel, the DPC object must be allocated from non-paged memory such as non-paged pool, driver static global non-paged memory, or in a device object extension.

Later, in an ISR, the driver calls KeInsertQueueDpcrather than IoRequestDpc. the parameter list for KeInsertQueueDpcis shorter than for IoRequestDpc – it takes a pointer to the DPC object initialized with KeInitializeDpcand two additional arguments that are simply passed through to the DPC routine. The DPC function receives a pointer to the DPC object, the context parameter that was passed to KeInitializeDpc, and the two system variables from KeInsertQueueDpc.

The I/O Manager's IoInitializeDpcRequestis actually nothing more than a wrapper around KeInitializeDpc.

#define IoInitializeDpcRequest( DeviceObject, DpcRoutine ) (\

KeInitializeDpc( &(DeviceObject)->Dpc, \

(PKDEFERRED_ROUTINE) (DpcRoutine), \

(DeviceObject) ) )

A device object has both a field for an IRP, which would be used for serially-oriented I/O devices, and a field for a DPC, which is the DPC object used in I/O Manager-DPC functions. Similarly, IoRequestDpcis a macro that calls KeInsertQueueDpc.

#define IoRequestDpc( DeviceObject, Irp, Context ) ( \

KeInsertQueueDpc( &(DeviceObject)->Dpc, (Irp), (Context) ) )

It obtains the DPC object pointer for the call from the device object.

The DPC Object

typedef struct {SHORT

SHORT Type;

UCHAR Number;

UCHAR Importance;

LIST_ENTRY DpcListEntry;

PKDEFERRED_ROUTINE DeferredRoutine;

PVOID DeferredContext;

PVOID SystemArgument1;

PVOID SystemArgument2;

PULONG Lock;

} KDPC, *PKDPC;

The self-explantory fields are DeferredRoutine, DeferredContext, and SystemArgument1 and SystemArgument2. DeferredRoutine and DeferredContext are obtained from the parameters that are passed to KeInitializeDpc. the system arguments are set in the call to KeInsertQueueDpc. However, if the call to KeInsertQueueDpcwas made through the IoRequestDpcmacro then SystemArgument1 is taken from the IRP parameter and SystemArgument2 corresponds to the Context parameter.

The Type field is also pretty obvious. Each object, whether it is an Executive or Kernel object, is tagged with a type so that functions can ensure that they are handed objects of the type that they expect. The Kernel object type values are simply determined from an enumerated list that contains entries for APCs, Events, Processes, Queues, Semaphores, Timers, as well as DPCs.

The final four fields, Number, Importance, DpcListEntry and Lock are more obscure and are undocumented. I'll describe each of these in the following sections.

DPC Targeting and Priorities

The NT DDK describes KeInsertQueueDpcas taking a dpc object and placing it in the DPC queue, and then issuing a software interrupt at DISPATCH_LEVEL which will cause the system to "drain" the DPC queue and execute the DPC functions. This is not entirely true. Rather than have one system-wide queue for DPC objects, NT maintains a separate DPC queue for each processor in a multiprocessor system. The queue's head is in the Processor Region Control Block (PRCB). Which queue does a DPC object get put on? One might guess that when a DPC is queued that it ends up on the DPC queue of the processor on which KeInsertQueueDpcis called. this is true for non-targetted DPCs. When DPCs are initialized with KeInitializeDpcthe number field is set to 0, which marks the DPC as non-targeted, that is, it will execute on the processor it is queued from. Figure 1 shows the typical flow of control for DPC queuing.

Figure 1 Interrupt Control Flow DPCs can be targeted so that they will only - фото 1

Figure 1. Interrupt Control Flow

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Sysinternals Freeware - Information for Windows NT and Windows 2000 - Advanced DPCs»

Представляем Вашему вниманию похожие книги на «Sysinternals Freeware - Information for Windows NT and Windows 2000 - Advanced DPCs» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Sysinternals Freeware - Information for Windows NT and Windows 2000 - Advanced DPCs»

Обсуждение, отзывы о книге «Sysinternals Freeware - Information for Windows NT and Windows 2000 - Advanced DPCs» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x