blk-mq: add helper to insert requests from irq context
authorChristoph Hellwig <hch@lst.de>
Wed, 28 May 2014 14:08:02 +0000 (08:08 -0600)
committerJens Axboe <axboe@fb.com>
Wed, 28 May 2014 14:08:02 +0000 (08:08 -0600)
Both the cache flush state machine and the SCSI midlayer want to submit
requests from irq context, and the current per-request requeue_work
unfortunately causes corruption due to sharing with the csd field for
flushes.  Replace them with a per-request_queue list of requests to
be requeued.

Based on an earlier test by Ming Lei.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reported-by: Ming Lei <tom.leiming@gmail.com>
Tested-by: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
block/blk-flush.c
block/blk-mq.c
include/linux/blk-mq.h
include/linux/blkdev.h

index ec7a224..ef608b3 100644 (file)
@@ -130,21 +130,13 @@ static void blk_flush_restore_request(struct request *rq)
        blk_clear_rq_complete(rq);
 }
 
-static void mq_flush_run(struct work_struct *work)
-{
-       struct request *rq;
-
-       rq = container_of(work, struct request, requeue_work);
-
-       memset(&rq->csd, 0, sizeof(rq->csd));
-       blk_mq_insert_request(rq, false, true, false);
-}
-
 static bool blk_flush_queue_rq(struct request *rq, bool add_front)
 {
        if (rq->q->mq_ops) {
-               INIT_WORK(&rq->requeue_work, mq_flush_run);
-               kblockd_schedule_work(&rq->requeue_work);
+               struct request_queue *q = rq->q;
+
+               blk_mq_add_to_requeue_list(rq, add_front);
+               blk_mq_kick_requeue_list(q);
                return false;
        } else {
                if (add_front)
diff --cc block/blk-mq.c
Simple merge
Simple merge
Simple merge