我目前正在为块设备创建 Linux 驱动程序。这已经持续了一段时间,我最近将驱动程序设计从 bio-mode 更改为 request-mode(我曾经处理 struct bio,但现在我正在处理 struct request),它使功能更简单,但是这一变化还提出了一些我正在寻求建议的新问题。我还使用 kthread 进行后台维护和定期刷新驱动程序设备循环缓冲区中的条目。
我难以处理或完全理解的问题之一是在输入更改分区或文件系统类型的命令后 sbin/blkid 进程的缓慢和存在。在我目前的设计中,每当我运行 fdisk 或 mkfs 或任何修改分区/FS 类型的命令时,通过 ps -ef 终端命令检查正在运行的进程时,blkid 进程随后运行,大约需要一两分钟才能完成并更新磁盘工具中的驱动器信息(用户看到)。这当然是等的太久了,在输入另一个修改分区/FS类型的命令之前我必须等待,否则驱动器信息会混乱,分区表丢失等。
我发现当我回到我以前的 bio-mode 驱动程序(没有 kthread)时,这个 blkid 任务也在与上面相同的命令之后运行,但完成得非常快!我刚刚意识到 blkid 是因为它现在很慢,而不是因为它很容易完成。所以我决定使用我的驱动程序代码,删除东西以查看哪个代码段导致 blkid 缓慢,最终发现 kthread 的存在与 blkid 的缓慢相关。
我的 kthread BTW 的主体如下所示:
while (kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irq(&lock);
< driver code here... >
spin_unlock_irq(&lock);
schedule_timeout(msecs_to_jiffies(250));
}
这是我对我的 kthread 所做的:
- 慢慢删除代码,直到在 spin_lock/unlock 调用之间没有留下任何东西。sbin/blkid 仍然很慢。
- 删除 kthread 并将其替换为定期到期、自行重置的计时器,并在每次到期时调用一个函数,我将 kthread 驱动程序代码的内容移至该函数。sbin/blkid 仍然很慢。
- 将 schedule_timeout 时间值从 250 毫秒更改为 1 秒 - blkid 变得更慢 > 3 分钟。如果我将它减少到 50 毫秒,它与 250 毫秒超时期间一样慢。
我真的很困惑——我的驱动程序 kthread 和 blkid 是如何交互的,它会减慢 blkid 的速度?