gpt4 book ai didi

c - Linux 设备驱动访问控制

转载 作者:IT王子 更新时间:2023-10-29 00:53:57 25 4
gpt4 key购买 nike

我正在为一些新颖的硬件实现一个设备驱动程序,并希望一次只允许一个进程访问该设备。并发读/写操作会使硬件困惑到很可能需要进行硬重置的程度。我还有以下问题:

  1. 在示例代码中from Linux Device Drivers , open() 调用使用锁,但 close() 不使用。这里不是仍然存在竞争条件,或者 scull_s_count 的递减保证是原子的吗?基本上,在这个例子中,我想知道如果一个进程试图打开设备而另一个进程正在结束并关闭它会发生什么。

  2. 我假设我不需要在我的 read() 中检查我的打开标志的状态(我正在做类似于示例的 scull_s_count 的事情) write() 调用,因为进入这些调用的唯一方法是用户空间应用程序是否已经通过成功调用 收到了 fd >打开()。这个假设正确吗?

感谢 tadman 的评论,我对内核的 atomic_t 机制进行了最粗略的搜索。这是我现在拥有的一些伪代码:

int open(struct inode *inode, struct file *filp) {
spin_lock(&lock);
if (atomic_read(&open_flag)) {
spin_unlock(&lock);
return -EBUSY;
}
atomic_set(&open_flag, 1);
/* do other open() related stuff */
spin_unlock(&lock);
return 0;
}

int close(struct inode *inode, struct file *filp) {
int rc;
/* do close() stuff */
atomic_set(&open_flag, 0);
return rc;
}

open_flag 是一个 atomic_t,它是用 kzalloc() 分配的更大结构的一部分。结果,它被初始化为零。

因此,这里的代码表明锁的目的是防止多个进程/线程同时打开设备,而open_flag是一个atomic_t 防止了我在上面的问题 1 中担心的竞争条件。这个实现是否足够?另外,我仍在寻找问题 2 的答案。

示例代码使用自旋锁,但互斥锁会更合适吗?代码部分相对较小,几乎没有争用,因此进入休眠和唤醒的性能可能低于旋转。始终从用户上下文访问锁/互斥量,因此您应该可以安全休眠。

最佳答案

你举的例子确实有问题。减量绝对不能保证是原子的,而且几乎肯定不会。

但实际上,我认为没有编译器/CPU 组合会生成可能会失败的代码。可能发生的最坏情况是一个 CPU 核心可以完成关闭,然后另一个核心可以调用打开并恢复忙碌,因为它有一个陈旧的标志缓存值。

Linux 为此提供了atomic_* 函数以及*_bit 原子位标志操作。请参阅内核文档中的 core_api/atomic_ops.rst。

一个正确而简单的模式示例如下所示:

unsigned long mydriver_flags;
#define IN_USE_BIT 0

static int mydriver_open(struct inode *inode, struct file *filp)
{
if (test_and_set_bit(IN_USE_BIT, &mydriver_flags))
return -EBUSY;
/* continue with open */
return 0;
}

static int mydriver_close(struct inode *inode, struct file *filp)
{
/* do close stuff first */
smp_mb__before_atomic();
clear_bit(IN_USE_BIT, &mydriver_flags);
return 0;
}

真正的驱动程序应该有一个设备状态结构,对于每个设备,其中包含 mydriver_flags。而不是像示例中那样对整个驱动程序使用单个全局变量。

也就是说,您尝试做的事情可能不是一个好主意。即使一次只有一个进程 可以打开设备,进程打开的文件描述符也会在进程中的所有线程 之间共享。多个线程可以同时对同一文件描述符进行 read()write() 调用。

如果一个进程打开了一个文件描述符并调用了fork(),这个描述符将被继承到新进程中。尽管有上述“单次打开”限制,但多个进程可以同时打开设备。

因此您仍然必须在驱动程序的文件操作中保持线程安全,因为用户仍然可以让多个线程/进程同时打开设备并进行同时调用。如果您已经确保安全,为什么要阻止用户这样做呢?也许他们知道自己在做什么,并且会确保驱动程序的多个开场白会“轮流”而不是进行冲突调用?

还要考虑在 open 调用中使用 O_EXCL 标志以使单个 open 可选的可能性。

关于c - Linux 设备驱动访问控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50106895/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com