gpt4 book ai didi

linux - Linux 如何知道驱动程序中的延迟工作以及何时使用从硬件设备带来的数据?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:56:04 24 4
gpt4 key购买 nike

当内核试图从硬盘读取一个 block 时,它会发送一个软件中断,该中断将由设备驱动程序处理。如果设备驱动程序通过工作队列将处理请求的工作分为上半部和下半部,那么内核如何知道在下半部完成之前数据不可用?

换句话说,内核如何知道驱动程序尚未获取所需的 block 并将其复制到提供的缓冲区中?

显然,如果内核希望在上半部分执行完毕并返回后数据随时可用,那么它可能会读取垃圾数据。

最佳答案

自 Linux 诞生以来, block 设备驱动程序 API 已经改变了几次,但今天它基本上看起来像下面这样。

初始化函数调用blk_init_queue,为该队列传递一个请求回调和一个可选的锁:

struct request_queue *q;
q = blk_init_queue(my_request_cb, &my_dev->lock);

my_request_cb 是一个回调,它将处理该 block 设备的所有 I/O。当内核 block 驱动层决定时,I/O 请求将被插入此队列,并依次调用 my_request_cb 来处理它们。然后将此队列添加到磁盘:

struct gendisk *disk;
disk->queue = q;

然后磁盘被添加到系统中:

add_disk(disk);

磁盘还有其他信息,如主编号、第一个次编号和其他文件操作(openrelease ioctl 和其他,但没有 read 也没有 write,就像在字符设备中发现的那样)。

现在,my_request_cb 可以在任何时候调用,而不必从在 block 设备上发起读/写的进程的上下文中调用。此调用由内核异步调用。

这个函数声明如下:

static void my_request_cb(struct request_queue *q);

队列 q 包含一个有序的请求到这个 block 设备的列表。然后该函数可能会查看下一个请求 (blk_fetch_request(q))。要将请求标记为已完成,它将调用 blk_end_request_all(根据情况存在其他变体)。

这就是我回答您的问题的地方:当内核的驱动程序调用 blk_end_request_all 或针对该请求的类似函数时,内核知道特定的 block 设备请求已完成。驱动程序不必在 my_request_cb 中结束请求:例如,它可以启动 DMA 传输、重新排队请求、忽略其他请求,并且仅当断言完成 DMA 传输的中断时,结束它,有效地告诉内核这个特定的读/写操作已经完成。

LDD3/chapter 16可以提供帮助,但自 2.6 以来有些事情发生了变化。

关于linux - Linux 如何知道驱动程序中的延迟工作以及何时使用从硬件设备带来的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18729585/

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