C Linux块设备驱动程序:如何处理REQ_丢弃

C Linux块设备驱动程序:如何处理REQ_丢弃,c,linux,kernel,block-device,C,Linux,Kernel,Block Device,我有一个块设备驱动程序,在一个商业产品中工作了一年多。最近,我尝试通过启用丢弃和使用REQ\u DISCARD标志处理请求来添加对精简资源调配的支持。每当我从任何上下文调用blk_end_request的任何变体,对于这些类型的请求,我似乎至少会得到一个BUG()输出,最坏的是挂起或oops(变体包括blk_end_request_all和前缀为的解锁版本)。另外,当我尝试以这种方式完成请求时(对于正常的读/写请求来说,这很好),上面的文件系统驱动程序ext4有时甚至使用相同的请求指针重新发出相

我有一个块设备驱动程序,在一个商业产品中工作了一年多。最近,我尝试通过启用丢弃和使用
REQ\u DISCARD
标志处理请求来添加对精简资源调配的支持。每当我从任何上下文调用
blk_end_request
的任何变体,对于这些类型的请求,我似乎至少会得到一个
BUG()
输出,最坏的是挂起或oops(变体包括
blk_end_request_all
和前缀为
的解锁版本)。另外,当我尝试以这种方式完成请求时(对于正常的读/写请求来说,这很好),上面的文件系统驱动程序ext4有时甚至使用相同的请求指针重新发出相同的
REQ\u DISCARD
请求。下面是一个简化的请求函数(传递给
blk\u init\u queue
),它演示了这个问题。这大约是我最早能够处理请求的时候,因此它消除了几乎所有的代码,这同样适用于正常的读/写

// This is a simplified version of the function that's passed into blk_init_queue
static void
my_request_fn(struct request_queue * queue)
{
    struct request * req;

    while ((req = blk_fetch_request(queue)) != NULL) {

        if (rq_data_dir(req) && (req->cmd_flags & REQ_DISCARD)) {
            printk(KERN_INFO "Received DISCARD request from process %d, sector=%lu, req %p\n",
                   pid_nr(task_pid(current)),
                   blk_rq_pos(req),
                   req);
            // FIXME: this is a lie
            __blk_end_request_all(req, 0);
            continue;
        }

// ... more code hidden for brevity
    }
}
这些请求是否需要以根本不同的方式处理?我试着查看其他驱动程序,例如sd、md、xenblk等。。。但它们完全不同,所以不清楚。我想基本的问题是如何正确处理REQ\u放弃请求并通知/发出完成信号?


如果这是一个已知的bug,uname-a报告的我的内核版本是
Linux-mydevbox 3.2.0-54-generic\82 Ubuntu-SMP-Tue-Sep-10 20:08:42 UTC 2013 x86\u 64 x86\u 64 GNU/Linux

,我发布在这里是因为我太不知所措了。解决方法很简单,也许这会帮助其他有同样问题的人。有新的限制与
放弃功能相关。其中两个在下面

// WARNING: these values are bad, do not use
queue->limits.discard_zeroes_data = 1;
queue->limits.max_discard_sectors = 1;
queue->limits.discard_granularity = 2048;
我以某种方式转换了最后两个值,因此丢弃粒度非常大,最大扇区数仅为1。在注释掉第三行(这应该只是一个提示)并确定第二行的RHS值之后,一切都正常了!这些值如下所示

queue->limits.discard_zeroes_data = 1;
queue->limits.max_discard_sectors = 2048
// queue->limits.discard_granularity = 1;

如果您在处理请求丢弃请求时遇到间歇性崩溃和
BUG()
堆栈跟踪,请仔细检查您的配置。

您说“通过启用丢弃”,我正在尝试做同样的事情,我看了又看,我没有看到。设置限制还不够,如何设置在何处为块设备启用丢弃?谢谢。我想我找到了blk_队列_标志集(队列_标志_丢弃,队列);