Driver: Use queued spin locks.

This commit is contained in:
Nodir Temirkhodjaev 2017-11-23 09:27:17 +05:00
parent 608294bfe7
commit 21cf3a22f4
3 changed files with 39 additions and 38 deletions

View File

@ -111,7 +111,7 @@ fort_buffer_blocked_write (PFORT_BUFFER buf, UINT32 remote_ip, UINT32 pid,
{
UINT32 len;
PCHAR out;
KIRQL irq;
KLOCK_QUEUE_HANDLE lock_queue;
NTSTATUS status = STATUS_SUCCESS;
if (path_len > FORT_LOG_PATH_MAX) {
@ -120,7 +120,7 @@ fort_buffer_blocked_write (PFORT_BUFFER buf, UINT32 remote_ip, UINT32 pid,
len = FORT_LOG_BLOCKED_SIZE(path_len);
KeAcquireSpinLock(&buf->lock, &irq);
KeAcquireInStackQueuedSpinLock(&buf->lock, &lock_queue);
/* Try to directly write to pending client */
if (buf->out_len) {
@ -159,7 +159,7 @@ fort_buffer_blocked_write (PFORT_BUFFER buf, UINT32 remote_ip, UINT32 pid,
fort_log_blocked_write(out, remote_ip, pid, path_len, path);
end:
KeReleaseSpinLock(&buf->lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
return status;
}
@ -170,10 +170,10 @@ fort_buffer_xmove (PFORT_BUFFER buf, PIRP irp, PVOID out, ULONG out_len,
{
PFORT_BUFFER_DATA data;
UINT32 buf_top;
KIRQL irq;
KLOCK_QUEUE_HANDLE lock_queue;
NTSTATUS status = STATUS_SUCCESS;
KeAcquireSpinLock(&buf->lock, &irq);
KeAcquireInStackQueuedSpinLock(&buf->lock, &lock_queue);
data = buf->data_head;
*info = buf_top = (data ? data->top : 0);
@ -202,7 +202,7 @@ fort_buffer_xmove (PFORT_BUFFER buf, PIRP irp, PVOID out, ULONG out_len,
fort_buffer_data_free(buf);
end:
KeReleaseSpinLock(&buf->lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
return status;
}
@ -210,12 +210,12 @@ fort_buffer_xmove (PFORT_BUFFER buf, PIRP irp, PVOID out, ULONG out_len,
static NTSTATUS
fort_buffer_cancel_pending (PFORT_BUFFER buf, PIRP irp, ULONG_PTR *info)
{
KLOCK_QUEUE_HANDLE lock_queue;
NTSTATUS status = STATUS_CANCELLED;
KIRQL irq;
*info = 0;
KeAcquireSpinLock(&buf->lock, &irq);
KeAcquireInStackQueuedSpinLock(&buf->lock, &lock_queue);
if (irp == buf->irp) {
buf->irp = NULL;
buf->out_len = 0;
@ -227,7 +227,7 @@ fort_buffer_cancel_pending (PFORT_BUFFER buf, PIRP irp, ULONG_PTR *info)
status = STATUS_SUCCESS;
}
}
KeReleaseSpinLock(&buf->lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
return status;
}
@ -235,9 +235,10 @@ fort_buffer_cancel_pending (PFORT_BUFFER buf, PIRP irp, ULONG_PTR *info)
static BOOL
fort_buffer_flush_pending (PFORT_BUFFER buf, PIRP *irp, ULONG_PTR *info)
{
KLOCK_QUEUE_HANDLE lock_queue;
UINT32 out_top;
KeAcquireSpinLockAtDpcLevel(&buf->lock);
KeAcquireInStackQueuedSpinLockAtDpcLevel(&buf->lock, &lock_queue);
out_top = buf->out_top;
if (out_top) {
*info = out_top;
@ -248,7 +249,7 @@ fort_buffer_flush_pending (PFORT_BUFFER buf, PIRP *irp, ULONG_PTR *info)
*irp = buf->irp;
buf->irp = NULL;
}
KeReleaseSpinLockFromDpcLevel(&buf->lock);
KeReleaseInStackQueuedSpinLockFromDpcLevel(&lock_queue);
return out_top != 0;
}

View File

@ -67,9 +67,9 @@ fort_conf_ref_new (const PFORT_CONF conf, ULONG len)
static void
fort_conf_ref_put (PFORT_CONF_REF conf_ref)
{
KIRQL irq;
KLOCK_QUEUE_HANDLE lock_queue;
KeAcquireSpinLock(&g_device->conf_lock, &irq);
KeAcquireInStackQueuedSpinLock(&g_device->conf_lock, &lock_queue);
{
const UINT32 refcount = --conf_ref->refcount;
@ -77,23 +77,23 @@ fort_conf_ref_put (PFORT_CONF_REF conf_ref)
ExFreePoolWithTag(conf_ref, FORT_DEVICE_POOL_TAG);
}
}
KeReleaseSpinLock(&g_device->conf_lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
}
static PFORT_CONF_REF
fort_conf_ref_take (void)
{
PFORT_CONF_REF conf_ref;
KIRQL irq;
KLOCK_QUEUE_HANDLE lock_queue;
KeAcquireSpinLock(&g_device->conf_lock, &irq);
KeAcquireInStackQueuedSpinLock(&g_device->conf_lock, &lock_queue);
{
conf_ref = g_device->conf_ref;
if (conf_ref) {
++conf_ref->refcount;
}
}
KeReleaseSpinLock(&g_device->conf_lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
return conf_ref;
}
@ -103,11 +103,11 @@ fort_conf_ref_set (PFORT_CONF_REF conf_ref)
{
PFORT_CONF_REF old_conf_ref;
FORT_CONF_FLAGS old_conf_flags;
KIRQL irq;
KLOCK_QUEUE_HANDLE lock_queue;
old_conf_ref = fort_conf_ref_take();
KeAcquireSpinLock(&g_device->conf_lock, &irq);
KeAcquireInStackQueuedSpinLock(&g_device->conf_lock, &lock_queue);
{
g_device->conf_ref = conf_ref;
@ -120,7 +120,7 @@ fort_conf_ref_set (PFORT_CONF_REF conf_ref)
g_device->prov_boot = conf_ref->conf.flags.prov_boot;
}
}
KeReleaseSpinLock(&g_device->conf_lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
if (old_conf_ref != NULL) {
old_conf_flags = old_conf_ref->conf.flags;
@ -134,9 +134,9 @@ static FORT_CONF_FLAGS
fort_conf_ref_flags_set (const PFORT_CONF_FLAGS conf_flags)
{
FORT_CONF_FLAGS old_conf_flags;
KIRQL irq;
KLOCK_QUEUE_HANDLE lock_queue;
KeAcquireSpinLock(&g_device->conf_lock, &irq);
KeAcquireInStackQueuedSpinLock(&g_device->conf_lock, &lock_queue);
{
PFORT_CONF_REF conf_ref = g_device->conf_ref;
@ -154,7 +154,7 @@ fort_conf_ref_flags_set (const PFORT_CONF_FLAGS conf_flags)
old_conf_flags.prov_boot = g_device->prov_boot;
}
}
KeReleaseSpinLock(&g_device->conf_lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
return old_conf_flags;
}
@ -461,15 +461,15 @@ fort_device_create (PDEVICE_OBJECT device, PIRP irp)
/* Device opened */
{
KIRQL irq;
KLOCK_QUEUE_HANDLE lock_queue;
KeAcquireSpinLock(&g_device->conf_lock, &irq);
KeAcquireInStackQueuedSpinLock(&g_device->conf_lock, &lock_queue);
if (g_device->is_opened) {
status = STATUS_SHARING_VIOLATION; // Only one client may connect
} else {
g_device->is_opened = TRUE;
}
KeReleaseSpinLock(&g_device->conf_lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
}
fort_request_complete(irp, status);
@ -503,11 +503,11 @@ fort_device_cleanup (PDEVICE_OBJECT device, PIRP irp)
/* Device closed */
{
KIRQL irq;
KLOCK_QUEUE_HANDLE lock_queue;
KeAcquireSpinLock(&g_device->conf_lock, &irq);
KeAcquireInStackQueuedSpinLock(&g_device->conf_lock, &lock_queue);
g_device->is_opened = FALSE;
KeReleaseSpinLock(&g_device->conf_lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
}
fort_request_complete(irp, STATUS_SUCCESS);

View File

@ -142,11 +142,11 @@ static void
fort_stat_flow_associate (PFORT_STAT stat, UINT64 flow_id,
UINT32 callout_id, UINT32 process_id)
{
KIRQL irq;
KLOCK_QUEUE_HANDLE lock_queue;
UINT64 flow_context;
int proc_index;
KeAcquireSpinLock(&stat->lock, &irq);
KeAcquireInStackQueuedSpinLock(&stat->lock, &lock_queue);
proc_index = fort_stat_proc_index(stat, process_id);
if (proc_index == -1) {
@ -165,7 +165,7 @@ fort_stat_flow_associate (PFORT_STAT stat, UINT64 flow_id,
}
end:
KeReleaseSpinLock(&stat->lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
"FORT: flow +: %d\n", process_id);
@ -174,14 +174,14 @@ fort_stat_flow_associate (PFORT_STAT stat, UINT64 flow_id,
static void
fort_stat_flow_delete (PFORT_STAT stat, UINT64 flow_context)
{
KIRQL irq;
KLOCK_QUEUE_HANDLE lock_queue;
const int proc_index = (int) (flow_context >> 32);
KeAcquireSpinLock(&stat->lock, &irq);
KeAcquireInStackQueuedSpinLock(&stat->lock, &lock_queue);
fort_stat_proc_dec(stat, proc_index);
KeReleaseSpinLock(&stat->lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
"FORT: flow -: %d\n", (UINT32) flow_context);
@ -192,11 +192,11 @@ fort_stat_flow_classify (PFORT_STAT stat, UINT64 flow_context,
UINT32 data_len, BOOL inbound)
{
PFORT_STAT_PROC proc;
KIRQL irq;
KLOCK_QUEUE_HANDLE lock_queue;
const UINT32 process_id = (UINT32) flow_context;
const int proc_index = (int) (flow_context >> 32);
KeAcquireSpinLock(&stat->lock, &irq);
KeAcquireInStackQueuedSpinLock(&stat->lock, &lock_queue);
proc = &stat->procs[proc_index];
@ -206,7 +206,7 @@ fort_stat_flow_classify (PFORT_STAT stat, UINT64 flow_context,
proc->out_bytes += data_len;
}
KeReleaseSpinLock(&stat->lock, irq);
KeReleaseInStackQueuedSpinLock(&lock_queue);
DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
"FORT: flow >: %d %d\n", (UINT32) flow_context, data_len);