首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从驱动程序主线程获取时的KSPIN_LOCK块

从驱动程序主线程获取时的KSPIN_LOCK块
EN

Stack Overflow用户
提问于 2019-04-03 23:43:42
回答 1查看 229关注 0票数 1

我有一个KSPIN_LOCK,它在PsCreateSystemThread驱动程序的主线程和我用PsCreateSystemThread创建的一些线程之间共享。问题是,如果我试图获得自旋锁,而不解除阻塞,则主线程阻塞。我很困惑为什么会这样..。据我所知,这可能与主线程在驱动程序IRQL上运行,而其他线程在PASSIVE_LEVEL上运行这一事实有关。

注意:如果我只运行主线程,那么获取/释放锁就可以了。

注意:我使用函数KeAcquireSpinLockKeReleaseSpinLock来获取/释放锁。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-04 16:19:11

这是我的“卡住”自旋锁的清单:

  1. 确保使用KeInitializeSpinLock初始化了自旋锁。如果KSPIN_LOCK持有未初始化的垃圾,那么第一次获取它的尝试很可能永远旋转。
  2. 检查是否以递归/嵌套的方式获取它。KSPIN_LOCK不支持递归,如果您尝试它,它将永远旋转。
  3. 必须在IRQL <= DISPATCH_LEVEL获得正常的自旋锁。如果您需要在DIRQL中工作的东西,请查看[1][2]
  4. 检查是否有泄漏。如果一个处理器获得了自旋锁,但忘记了释放它,那么当试图获取锁时,下一个处理器将永远旋转。
  5. 确保没有内存安全问题。如果代码随机地在自旋锁的顶部写入一个非零值,这将导致它看起来被获取,而下一个获取将永远旋转。

使用驱动程序验证程序可以轻松和自动地发现其中的一些问题;如果您还没有使用它,请使用它。如果您将自旋锁封装在一个添加自己断言的小助手中,则可能会发现其他问题。例如:

代码语言:javascript
运行
复制
typedef struct _MY_LOCK {
    KSPIN_LOCK Lock;
    ULONG OwningProcessor;
    KIRQL OldIrql;
} MY_LOCK;

void MyInitialize(MY_LOCK *lock) {
    KeInitializeSpinLock(&lock->Lock);
    lock->OwningProcessor = (ULONG)-1;
}

void MyAcquire(MY_LOCK *lock) {
    ULONG current = KeGetCurrentProcessorIndex();
    NT_ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
    NT_ASSERT(current != lock->OwningProcessor); // check for recursion
    KeAcquireSpinLock(&lock->Lock, &lock->OldIrql);
    NT_ASSERT(lock->OwningProcessor == (ULONG)-1); // check lock was inited
    lock->OwningProcessor = current;
}

void MyRelease(MY_LOCK *lock) {
    NT_ASSERT(KeGetCurrentProcessorIndex() == lock->OwningProcessor);
    lock->OwningProcessor = (ULONG)-1;
    KeReleaseSpinLock(&lock->Lock, lock->OldIrql);
}

KSPIN_LOCK的包装器很常见。KSPIN_LOCK就像一款赛车,它的所有可选功能都被去掉,以最大限度地提高原始速度。如果你不计算微秒,你可能会合理地决定增加加热的座位和调频收音机,包装在上面这样的低水平KSPIN_LOCK。(如果你需要的话,使用#ifdefs的魔力,你总是可以把安全气囊从你的零售建筑中拿出来。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55505845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档