3

我正在尝试为网络连接的硬盘编写设备驱动程序。我想知道锁定/解锁请求队列的正确方法是什么以及在哪里?

澄清:

  1. 我使用创建队列blk_init_queue并将请求处理函数和我创建的锁(即信号量)传递给该函数。
  2. 我的请求处理函数如下所示:

    struct request *req;
    int ret;
    while ((req = blk_fetch_request(q)) != NULL) {
         ret = rb_transfer(req);
    }
    
  3. rb_transfer启动了一个新的内核线程来处理请求。

  4. 一旦处理了请求并完成了数据传输,blk_end_request_cur就会在该请求上调用。

现在,我的问题是如何在上面的循环中保护对请求队列的访问?在一般的驱动程序中?

我试过这样的事情:

struct request *req;
int ret;
while ((req = blk_fetch_request(q)) != NULL) {
     spin_lock(&lock);
     ret = rb_transfer(req);
     spin_unlock(&lock);
}

但这失败并导致内核锁定。

还有其他想法吗?

4

1 回答 1

3

通过将传递的作为第二个参数并禁用中断来调用request_fn您传递给的 。因此,您可以放心地假设没有正在运行的并行线程正在执行 this 。但是,如果您创建一个处理此请求的并行线程,那么同步访问这些线程中的请求完全是您的责任。blk_init_queuespinlockrequest_fn

request_fn被调用的又__blk_run_queue_uncond被函数__blk_run_queue和调用blk_execute_rq_nowait。如果您搜索__blk_run_queue在 linux 内核中调用的函数,您可以看到所有这些函数都是通过持有q->queue_lock传递给 function 的自旋锁来实现的blk_init_queue

于 2013-10-17T07:32:10.993 回答