Driver: Improve flushing deferred packets.

This commit is contained in:
Nodir Temirkhodjaev 2018-02-18 08:28:20 +05:00
parent 1a5c45472c
commit 56b5065ffd
2 changed files with 22 additions and 16 deletions

View File

@ -729,6 +729,12 @@ fort_callout_force_reauth (PDEVICE_OBJECT device,
return status; return status;
} }
static void
fort_callout_defer_flush (BOOL dispatchLevel)
{
fort_defer_flush(&g_device->defer, fort_transport_inject_complete, dispatchLevel);
}
static void static void
fort_callout_timer (void) fort_callout_timer (void)
{ {
@ -777,17 +783,7 @@ fort_callout_timer (void)
} }
/* Flush deferred packets */ /* Flush deferred packets */
fort_defer_dpc_flush(&g_device->defer, fort_transport_inject_complete); fort_callout_defer_flush(TRUE);
}
static void
fort_callout_timer_force (void)
{
KLOCK_QUEUE_HANDLE lock_queue;
KeAcquireInStackQueuedSpinLock(&g_device->conf_lock, &lock_queue);
fort_callout_timer(); /* Should be called from DISPATCH_LEVEL! */
KeReleaseInStackQueuedSpinLock(&lock_queue);
} }
static NTSTATUS static NTSTATUS
@ -958,7 +954,7 @@ fort_power_callback (PVOID context, PVOID event, PVOID specifics)
g_device->power_off = power_off; g_device->power_off = power_off;
if (power_off) { if (power_off) {
fort_callout_timer_force(); fort_callout_defer_flush(FALSE);
} }
} }
@ -1002,7 +998,7 @@ fort_driver_unload (PDRIVER_OBJECT driver)
UNICODE_STRING device_link; UNICODE_STRING device_link;
if (g_device != NULL) { if (g_device != NULL) {
fort_callout_timer_force(); fort_callout_defer_flush(FALSE);
fort_timer_close(&g_device->timer); fort_timer_close(&g_device->timer);
fort_defer_close(&g_device->defer); fort_defer_close(&g_device->defer);

View File

@ -325,19 +325,29 @@ fort_defer_inject_out (PFORT_DEFER defer, PFORT_PACKET pkt,
} }
static void static void
fort_defer_dpc_flush (PFORT_DEFER defer, FORT_INJECT_COMPLETE_FUNC complete_func) fort_defer_flush (PFORT_DEFER defer,
FORT_INJECT_COMPLETE_FUNC complete_func,
BOOL dispatchLevel)
{ {
KLOCK_QUEUE_HANDLE lock_queue; KLOCK_QUEUE_HANDLE lock_queue;
PFORT_PACKET pkt; PFORT_PACKET pkt;
KeAcquireInStackQueuedSpinLockAtDpcLevel(&defer->lock, &lock_queue); if (dispatchLevel) {
KeAcquireInStackQueuedSpinLockAtDpcLevel(&defer->lock, &lock_queue);
} else {
KeAcquireInStackQueuedSpinLock(&defer->lock, &lock_queue);
}
pkt = defer->packet_head; pkt = defer->packet_head;
if (pkt != NULL) { if (pkt != NULL) {
defer->packet_head = defer->packet_tail = NULL; defer->packet_head = defer->packet_tail = NULL;
} }
KeReleaseInStackQueuedSpinLockFromDpcLevel(&lock_queue); if (dispatchLevel) {
KeReleaseInStackQueuedSpinLockFromDpcLevel(&lock_queue);
} else {
KeReleaseInStackQueuedSpinLock(&lock_queue);
}
while (pkt != NULL) { while (pkt != NULL) {
PFORT_PACKET pkt_next = pkt->next; PFORT_PACKET pkt_next = pkt->next;