LCOV - code coverage report
Current view: top level - block - blk-flush.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 156 0.0 %
Date: 2023-07-19 18:55:55 Functions: 0 11 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Functions to sequence PREFLUSH and FUA writes.
       4             :  *
       5             :  * Copyright (C) 2011           Max Planck Institute for Gravitational Physics
       6             :  * Copyright (C) 2011           Tejun Heo <tj@kernel.org>
       7             :  *
       8             :  * REQ_{PREFLUSH|FUA} requests are decomposed to sequences consisted of three
       9             :  * optional steps - PREFLUSH, DATA and POSTFLUSH - according to the request
      10             :  * properties and hardware capability.
      11             :  *
      12             :  * If a request doesn't have data, only REQ_PREFLUSH makes sense, which
      13             :  * indicates a simple flush request.  If there is data, REQ_PREFLUSH indicates
      14             :  * that the device cache should be flushed before the data is executed, and
      15             :  * REQ_FUA means that the data must be on non-volatile media on request
      16             :  * completion.
      17             :  *
      18             :  * If the device doesn't have writeback cache, PREFLUSH and FUA don't make any
      19             :  * difference.  The requests are either completed immediately if there's no data
      20             :  * or executed as normal requests otherwise.
      21             :  *
      22             :  * If the device has writeback cache and supports FUA, REQ_PREFLUSH is
      23             :  * translated to PREFLUSH but REQ_FUA is passed down directly with DATA.
      24             :  *
      25             :  * If the device has writeback cache and doesn't support FUA, REQ_PREFLUSH
      26             :  * is translated to PREFLUSH and REQ_FUA to POSTFLUSH.
      27             :  *
      28             :  * The actual execution of flush is double buffered.  Whenever a request
      29             :  * needs to execute PRE or POSTFLUSH, it queues at
      30             :  * fq->flush_queue[fq->flush_pending_idx].  Once certain criteria are met, a
      31             :  * REQ_OP_FLUSH is issued and the pending_idx is toggled.  When the flush
      32             :  * completes, all the requests which were pending are proceeded to the next
      33             :  * step.  This allows arbitrary merging of different types of PREFLUSH/FUA
      34             :  * requests.
      35             :  *
      36             :  * Currently, the following conditions are used to determine when to issue
      37             :  * flush.
      38             :  *
      39             :  * C1. At any given time, only one flush shall be in progress.  This makes
      40             :  *     double buffering sufficient.
      41             :  *
      42             :  * C2. Flush is deferred if any request is executing DATA of its sequence.
      43             :  *     This avoids issuing separate POSTFLUSHes for requests which shared
      44             :  *     PREFLUSH.
      45             :  *
      46             :  * C3. The second condition is ignored if there is a request which has
      47             :  *     waited longer than FLUSH_PENDING_TIMEOUT.  This is to avoid
      48             :  *     starvation in the unlikely case where there are continuous stream of
      49             :  *     FUA (without PREFLUSH) requests.
      50             :  *
      51             :  * For devices which support FUA, it isn't clear whether C2 (and thus C3)
      52             :  * is beneficial.
      53             :  *
      54             :  * Note that a sequenced PREFLUSH/FUA request with DATA is completed twice.
      55             :  * Once while executing DATA and again after the whole sequence is
      56             :  * complete.  The first completion updates the contained bio but doesn't
      57             :  * finish it so that the bio submitter is notified only after the whole
      58             :  * sequence is complete.  This is implemented by testing RQF_FLUSH_SEQ in
      59             :  * req_bio_endio().
      60             :  *
      61             :  * The above peculiarity requires that each PREFLUSH/FUA request has only one
      62             :  * bio attached to it, which is guaranteed as they aren't allowed to be
      63             :  * merged in the usual way.
      64             :  */
      65             : 
      66             : #include <linux/kernel.h>
      67             : #include <linux/module.h>
      68             : #include <linux/bio.h>
      69             : #include <linux/blkdev.h>
      70             : #include <linux/gfp.h>
      71             : #include <linux/part_stat.h>
      72             : 
      73             : #include "blk.h"
      74             : #include "blk-mq.h"
      75             : #include "blk-mq-sched.h"
      76             : 
      77             : /* PREFLUSH/FUA sequences */
      78             : enum {
      79             :         REQ_FSEQ_PREFLUSH       = (1 << 0), /* pre-flushing in progress */
      80             :         REQ_FSEQ_DATA           = (1 << 1), /* data write in progress */
      81             :         REQ_FSEQ_POSTFLUSH      = (1 << 2), /* post-flushing in progress */
      82             :         REQ_FSEQ_DONE           = (1 << 3),
      83             : 
      84             :         REQ_FSEQ_ACTIONS        = REQ_FSEQ_PREFLUSH | REQ_FSEQ_DATA |
      85             :                                   REQ_FSEQ_POSTFLUSH,
      86             : 
      87             :         /*
      88             :          * If flush has been pending longer than the following timeout,
      89             :          * it's issued even if flush_data requests are still in flight.
      90             :          */
      91             :         FLUSH_PENDING_TIMEOUT   = 5 * HZ,
      92             : };
      93             : 
      94             : static void blk_kick_flush(struct request_queue *q,
      95             :                            struct blk_flush_queue *fq, blk_opf_t flags);
      96             : 
      97             : static inline struct blk_flush_queue *
      98             : blk_get_flush_queue(struct request_queue *q, struct blk_mq_ctx *ctx)
      99             : {
     100           0 :         return blk_mq_map_queue(q, REQ_OP_FLUSH, ctx)->fq;
     101             : }
     102             : 
     103             : static unsigned int blk_flush_policy(unsigned long fflags, struct request *rq)
     104             : {
     105           0 :         unsigned int policy = 0;
     106             : 
     107           0 :         if (blk_rq_sectors(rq))
     108           0 :                 policy |= REQ_FSEQ_DATA;
     109             : 
     110           0 :         if (fflags & (1UL << QUEUE_FLAG_WC)) {
     111           0 :                 if (rq->cmd_flags & REQ_PREFLUSH)
     112           0 :                         policy |= REQ_FSEQ_PREFLUSH;
     113           0 :                 if (!(fflags & (1UL << QUEUE_FLAG_FUA)) &&
     114           0 :                     (rq->cmd_flags & REQ_FUA))
     115           0 :                         policy |= REQ_FSEQ_POSTFLUSH;
     116             :         }
     117             :         return policy;
     118             : }
     119             : 
     120             : static unsigned int blk_flush_cur_seq(struct request *rq)
     121             : {
     122           0 :         return 1 << ffz(rq->flush.seq);
     123             : }
     124             : 
     125             : static void blk_flush_restore_request(struct request *rq)
     126             : {
     127             :         /*
     128             :          * After flush data completion, @rq->bio is %NULL but we need to
     129             :          * complete the bio again.  @rq->biotail is guaranteed to equal the
     130             :          * original @rq->bio.  Restore it.
     131             :          */
     132           0 :         rq->bio = rq->biotail;
     133             : 
     134             :         /* make @rq a normal request */
     135           0 :         rq->rq_flags &= ~RQF_FLUSH_SEQ;
     136           0 :         rq->end_io = rq->flush.saved_end_io;
     137             : }
     138             : 
     139           0 : static void blk_account_io_flush(struct request *rq)
     140             : {
     141           0 :         struct block_device *part = rq->q->disk->part0;
     142             : 
     143           0 :         part_stat_lock();
     144           0 :         part_stat_inc(part, ios[STAT_FLUSH]);
     145           0 :         part_stat_add(part, nsecs[STAT_FLUSH],
     146             :                       ktime_get_ns() - rq->start_time_ns);
     147           0 :         part_stat_unlock();
     148           0 : }
     149             : 
     150             : /**
     151             :  * blk_flush_complete_seq - complete flush sequence
     152             :  * @rq: PREFLUSH/FUA request being sequenced
     153             :  * @fq: flush queue
     154             :  * @seq: sequences to complete (mask of %REQ_FSEQ_*, can be zero)
     155             :  * @error: whether an error occurred
     156             :  *
     157             :  * @rq just completed @seq part of its flush sequence, record the
     158             :  * completion and trigger the next step.
     159             :  *
     160             :  * CONTEXT:
     161             :  * spin_lock_irq(fq->mq_flush_lock)
     162             :  */
     163           0 : static void blk_flush_complete_seq(struct request *rq,
     164             :                                    struct blk_flush_queue *fq,
     165             :                                    unsigned int seq, blk_status_t error)
     166             : {
     167           0 :         struct request_queue *q = rq->q;
     168           0 :         struct list_head *pending = &fq->flush_queue[fq->flush_pending_idx];
     169             :         blk_opf_t cmd_flags;
     170             : 
     171           0 :         BUG_ON(rq->flush.seq & seq);
     172           0 :         rq->flush.seq |= seq;
     173           0 :         cmd_flags = rq->cmd_flags;
     174             : 
     175           0 :         if (likely(!error))
     176           0 :                 seq = blk_flush_cur_seq(rq);
     177             :         else
     178             :                 seq = REQ_FSEQ_DONE;
     179             : 
     180           0 :         switch (seq) {
     181             :         case REQ_FSEQ_PREFLUSH:
     182             :         case REQ_FSEQ_POSTFLUSH:
     183             :                 /* queue for flush */
     184           0 :                 if (list_empty(pending))
     185           0 :                         fq->flush_pending_since = jiffies;
     186           0 :                 list_move_tail(&rq->flush.list, pending);
     187             :                 break;
     188             : 
     189             :         case REQ_FSEQ_DATA:
     190           0 :                 list_move_tail(&rq->flush.list, &fq->flush_data_in_flight);
     191           0 :                 blk_mq_add_to_requeue_list(rq, BLK_MQ_INSERT_AT_HEAD);
     192           0 :                 blk_mq_kick_requeue_list(q);
     193           0 :                 break;
     194             : 
     195             :         case REQ_FSEQ_DONE:
     196             :                 /*
     197             :                  * @rq was previously adjusted by blk_insert_flush() for
     198             :                  * flush sequencing and may already have gone through the
     199             :                  * flush data request completion path.  Restore @rq for
     200             :                  * normal completion and end it.
     201             :                  */
     202           0 :                 list_del_init(&rq->flush.list);
     203           0 :                 blk_flush_restore_request(rq);
     204           0 :                 blk_mq_end_request(rq, error);
     205           0 :                 break;
     206             : 
     207             :         default:
     208           0 :                 BUG();
     209             :         }
     210             : 
     211           0 :         blk_kick_flush(q, fq, cmd_flags);
     212           0 : }
     213             : 
     214           0 : static enum rq_end_io_ret flush_end_io(struct request *flush_rq,
     215             :                                        blk_status_t error)
     216             : {
     217           0 :         struct request_queue *q = flush_rq->q;
     218             :         struct list_head *running;
     219             :         struct request *rq, *n;
     220           0 :         unsigned long flags = 0;
     221           0 :         struct blk_flush_queue *fq = blk_get_flush_queue(q, flush_rq->mq_ctx);
     222             : 
     223             :         /* release the tag's ownership to the req cloned from */
     224           0 :         spin_lock_irqsave(&fq->mq_flush_lock, flags);
     225             : 
     226           0 :         if (!req_ref_put_and_test(flush_rq)) {
     227           0 :                 fq->rq_status = error;
     228           0 :                 spin_unlock_irqrestore(&fq->mq_flush_lock, flags);
     229           0 :                 return RQ_END_IO_NONE;
     230             :         }
     231             : 
     232           0 :         blk_account_io_flush(flush_rq);
     233             :         /*
     234             :          * Flush request has to be marked as IDLE when it is really ended
     235             :          * because its .end_io() is called from timeout code path too for
     236             :          * avoiding use-after-free.
     237             :          */
     238           0 :         WRITE_ONCE(flush_rq->state, MQ_RQ_IDLE);
     239           0 :         if (fq->rq_status != BLK_STS_OK) {
     240           0 :                 error = fq->rq_status;
     241           0 :                 fq->rq_status = BLK_STS_OK;
     242             :         }
     243             : 
     244           0 :         if (!q->elevator) {
     245           0 :                 flush_rq->tag = BLK_MQ_NO_TAG;
     246             :         } else {
     247           0 :                 blk_mq_put_driver_tag(flush_rq);
     248           0 :                 flush_rq->internal_tag = BLK_MQ_NO_TAG;
     249             :         }
     250             : 
     251           0 :         running = &fq->flush_queue[fq->flush_running_idx];
     252           0 :         BUG_ON(fq->flush_pending_idx == fq->flush_running_idx);
     253             : 
     254             :         /* account completion of the flush request */
     255           0 :         fq->flush_running_idx ^= 1;
     256             : 
     257             :         /* and push the waiting requests to the next stage */
     258           0 :         list_for_each_entry_safe(rq, n, running, flush.list) {
     259           0 :                 unsigned int seq = blk_flush_cur_seq(rq);
     260             : 
     261           0 :                 BUG_ON(seq != REQ_FSEQ_PREFLUSH && seq != REQ_FSEQ_POSTFLUSH);
     262           0 :                 blk_flush_complete_seq(rq, fq, seq, error);
     263             :         }
     264             : 
     265           0 :         spin_unlock_irqrestore(&fq->mq_flush_lock, flags);
     266           0 :         return RQ_END_IO_NONE;
     267             : }
     268             : 
     269           0 : bool is_flush_rq(struct request *rq)
     270             : {
     271           0 :         return rq->end_io == flush_end_io;
     272             : }
     273             : 
     274             : /**
     275             :  * blk_kick_flush - consider issuing flush request
     276             :  * @q: request_queue being kicked
     277             :  * @fq: flush queue
     278             :  * @flags: cmd_flags of the original request
     279             :  *
     280             :  * Flush related states of @q have changed, consider issuing flush request.
     281             :  * Please read the comment at the top of this file for more info.
     282             :  *
     283             :  * CONTEXT:
     284             :  * spin_lock_irq(fq->mq_flush_lock)
     285             :  *
     286             :  */
     287           0 : static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq,
     288             :                            blk_opf_t flags)
     289             : {
     290           0 :         struct list_head *pending = &fq->flush_queue[fq->flush_pending_idx];
     291           0 :         struct request *first_rq =
     292           0 :                 list_first_entry(pending, struct request, flush.list);
     293           0 :         struct request *flush_rq = fq->flush_rq;
     294             : 
     295             :         /* C1 described at the top of this file */
     296           0 :         if (fq->flush_pending_idx != fq->flush_running_idx || list_empty(pending))
     297             :                 return;
     298             : 
     299             :         /* C2 and C3 */
     300           0 :         if (!list_empty(&fq->flush_data_in_flight) &&
     301           0 :             time_before(jiffies,
     302             :                         fq->flush_pending_since + FLUSH_PENDING_TIMEOUT))
     303             :                 return;
     304             : 
     305             :         /*
     306             :          * Issue flush and toggle pending_idx.  This makes pending_idx
     307             :          * different from running_idx, which means flush is in flight.
     308             :          */
     309           0 :         fq->flush_pending_idx ^= 1;
     310             : 
     311           0 :         blk_rq_init(q, flush_rq);
     312             : 
     313             :         /*
     314             :          * In case of none scheduler, borrow tag from the first request
     315             :          * since they can't be in flight at the same time. And acquire
     316             :          * the tag's ownership for flush req.
     317             :          *
     318             :          * In case of IO scheduler, flush rq need to borrow scheduler tag
     319             :          * just for cheating put/get driver tag.
     320             :          */
     321           0 :         flush_rq->mq_ctx = first_rq->mq_ctx;
     322           0 :         flush_rq->mq_hctx = first_rq->mq_hctx;
     323             : 
     324           0 :         if (!q->elevator) {
     325           0 :                 flush_rq->tag = first_rq->tag;
     326             : 
     327             :                 /*
     328             :                  * We borrow data request's driver tag, so have to mark
     329             :                  * this flush request as INFLIGHT for avoiding double
     330             :                  * account of this driver tag
     331             :                  */
     332           0 :                 flush_rq->rq_flags |= RQF_MQ_INFLIGHT;
     333             :         } else
     334           0 :                 flush_rq->internal_tag = first_rq->internal_tag;
     335             : 
     336             :         flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH;
     337           0 :         flush_rq->cmd_flags |= (flags & REQ_DRV) | (flags & REQ_FAILFAST_MASK);
     338           0 :         flush_rq->rq_flags |= RQF_FLUSH_SEQ;
     339           0 :         flush_rq->end_io = flush_end_io;
     340             :         /*
     341             :          * Order WRITE ->end_io and WRITE rq->ref, and its pair is the one
     342             :          * implied in refcount_inc_not_zero() called from
     343             :          * blk_mq_find_and_get_req(), which orders WRITE/READ flush_rq->ref
     344             :          * and READ flush_rq->end_io
     345             :          */
     346           0 :         smp_wmb();
     347           0 :         req_ref_set(flush_rq, 1);
     348             : 
     349           0 :         blk_mq_add_to_requeue_list(flush_rq, 0);
     350           0 :         blk_mq_kick_requeue_list(q);
     351             : }
     352             : 
     353           0 : static enum rq_end_io_ret mq_flush_data_end_io(struct request *rq,
     354             :                                                blk_status_t error)
     355             : {
     356           0 :         struct request_queue *q = rq->q;
     357           0 :         struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
     358           0 :         struct blk_mq_ctx *ctx = rq->mq_ctx;
     359             :         unsigned long flags;
     360           0 :         struct blk_flush_queue *fq = blk_get_flush_queue(q, ctx);
     361             : 
     362           0 :         if (q->elevator) {
     363           0 :                 WARN_ON(rq->tag < 0);
     364             :                 blk_mq_put_driver_tag(rq);
     365             :         }
     366             : 
     367             :         /*
     368             :          * After populating an empty queue, kick it to avoid stall.  Read
     369             :          * the comment in flush_end_io().
     370             :          */
     371           0 :         spin_lock_irqsave(&fq->mq_flush_lock, flags);
     372           0 :         blk_flush_complete_seq(rq, fq, REQ_FSEQ_DATA, error);
     373           0 :         spin_unlock_irqrestore(&fq->mq_flush_lock, flags);
     374             : 
     375           0 :         blk_mq_sched_restart(hctx);
     376           0 :         return RQ_END_IO_NONE;
     377             : }
     378             : 
     379             : /**
     380             :  * blk_insert_flush - insert a new PREFLUSH/FUA request
     381             :  * @rq: request to insert
     382             :  *
     383             :  * To be called from __elv_add_request() for %ELEVATOR_INSERT_FLUSH insertions.
     384             :  * or __blk_mq_run_hw_queue() to dispatch request.
     385             :  * @rq is being submitted.  Analyze what needs to be done and put it on the
     386             :  * right queue.
     387             :  */
     388           0 : void blk_insert_flush(struct request *rq)
     389             : {
     390           0 :         struct request_queue *q = rq->q;
     391           0 :         unsigned long fflags = q->queue_flags;       /* may change, cache */
     392           0 :         unsigned int policy = blk_flush_policy(fflags, rq);
     393           0 :         struct blk_flush_queue *fq = blk_get_flush_queue(q, rq->mq_ctx);
     394           0 :         struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
     395             : 
     396             :         /*
     397             :          * @policy now records what operations need to be done.  Adjust
     398             :          * REQ_PREFLUSH and FUA for the driver.
     399             :          */
     400           0 :         rq->cmd_flags &= ~REQ_PREFLUSH;
     401           0 :         if (!(fflags & (1UL << QUEUE_FLAG_FUA)))
     402           0 :                 rq->cmd_flags &= ~REQ_FUA;
     403             : 
     404             :         /*
     405             :          * REQ_PREFLUSH|REQ_FUA implies REQ_SYNC, so if we clear any
     406             :          * of those flags, we have to set REQ_SYNC to avoid skewing
     407             :          * the request accounting.
     408             :          */
     409           0 :         rq->cmd_flags |= REQ_SYNC;
     410             : 
     411             :         /*
     412             :          * An empty flush handed down from a stacking driver may
     413             :          * translate into nothing if the underlying device does not
     414             :          * advertise a write-back cache.  In this case, simply
     415             :          * complete the request.
     416             :          */
     417           0 :         if (!policy) {
     418           0 :                 blk_mq_end_request(rq, 0);
     419           0 :                 return;
     420             :         }
     421             : 
     422           0 :         BUG_ON(rq->bio != rq->biotail); /*assumes zero or single bio rq */
     423             : 
     424             :         /*
     425             :          * If there's data but flush is not necessary, the request can be
     426             :          * processed directly without going through flush machinery.  Queue
     427             :          * for normal execution.
     428             :          */
     429           0 :         if ((policy & REQ_FSEQ_DATA) &&
     430             :             !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) {
     431           0 :                 blk_mq_request_bypass_insert(rq, 0);
     432           0 :                 blk_mq_run_hw_queue(hctx, false);
     433           0 :                 return;
     434             :         }
     435             : 
     436             :         /*
     437             :          * @rq should go through flush machinery.  Mark it part of flush
     438             :          * sequence and submit for further processing.
     439             :          */
     440           0 :         memset(&rq->flush, 0, sizeof(rq->flush));
     441           0 :         INIT_LIST_HEAD(&rq->flush.list);
     442           0 :         rq->rq_flags |= RQF_FLUSH_SEQ;
     443           0 :         rq->flush.saved_end_io = rq->end_io; /* Usually NULL */
     444             : 
     445           0 :         rq->end_io = mq_flush_data_end_io;
     446             : 
     447           0 :         spin_lock_irq(&fq->mq_flush_lock);
     448           0 :         blk_flush_complete_seq(rq, fq, REQ_FSEQ_ACTIONS & ~policy, 0);
     449           0 :         spin_unlock_irq(&fq->mq_flush_lock);
     450             : }
     451             : 
     452             : /**
     453             :  * blkdev_issue_flush - queue a flush
     454             :  * @bdev:       blockdev to issue flush for
     455             :  *
     456             :  * Description:
     457             :  *    Issue a flush for the block device in question.
     458             :  */
     459           0 : int blkdev_issue_flush(struct block_device *bdev)
     460             : {
     461             :         struct bio bio;
     462             : 
     463           0 :         bio_init(&bio, bdev, NULL, 0, REQ_OP_WRITE | REQ_PREFLUSH);
     464           0 :         return submit_bio_wait(&bio);
     465             : }
     466             : EXPORT_SYMBOL(blkdev_issue_flush);
     467             : 
     468           0 : struct blk_flush_queue *blk_alloc_flush_queue(int node, int cmd_size,
     469             :                                               gfp_t flags)
     470             : {
     471             :         struct blk_flush_queue *fq;
     472           0 :         int rq_sz = sizeof(struct request);
     473             : 
     474           0 :         fq = kzalloc_node(sizeof(*fq), flags, node);
     475           0 :         if (!fq)
     476             :                 goto fail;
     477             : 
     478           0 :         spin_lock_init(&fq->mq_flush_lock);
     479             : 
     480           0 :         rq_sz = round_up(rq_sz + cmd_size, cache_line_size());
     481           0 :         fq->flush_rq = kzalloc_node(rq_sz, flags, node);
     482           0 :         if (!fq->flush_rq)
     483             :                 goto fail_rq;
     484             : 
     485           0 :         INIT_LIST_HEAD(&fq->flush_queue[0]);
     486           0 :         INIT_LIST_HEAD(&fq->flush_queue[1]);
     487           0 :         INIT_LIST_HEAD(&fq->flush_data_in_flight);
     488             : 
     489           0 :         return fq;
     490             : 
     491             :  fail_rq:
     492           0 :         kfree(fq);
     493             :  fail:
     494             :         return NULL;
     495             : }
     496             : 
     497           0 : void blk_free_flush_queue(struct blk_flush_queue *fq)
     498             : {
     499             :         /* bio based request queue hasn't flush queue */
     500           0 :         if (!fq)
     501             :                 return;
     502             : 
     503           0 :         kfree(fq->flush_rq);
     504           0 :         kfree(fq);
     505             : }
     506             : 
     507             : /*
     508             :  * Allow driver to set its own lock class to fq->mq_flush_lock for
     509             :  * avoiding lockdep complaint.
     510             :  *
     511             :  * flush_end_io() may be called recursively from some driver, such as
     512             :  * nvme-loop, so lockdep may complain 'possible recursive locking' because
     513             :  * all 'struct blk_flush_queue' instance share same mq_flush_lock lock class
     514             :  * key. We need to assign different lock class for these driver's
     515             :  * fq->mq_flush_lock for avoiding the lockdep warning.
     516             :  *
     517             :  * Use dynamically allocated lock class key for each 'blk_flush_queue'
     518             :  * instance is over-kill, and more worse it introduces horrible boot delay
     519             :  * issue because synchronize_rcu() is implied in lockdep_unregister_key which
     520             :  * is called for each hctx release. SCSI probing may synchronously create and
     521             :  * destroy lots of MQ request_queues for non-existent devices, and some robot
     522             :  * test kernel always enable lockdep option. It is observed that more than half
     523             :  * an hour is taken during SCSI MQ probe with per-fq lock class.
     524             :  */
     525           0 : void blk_mq_hctx_set_fq_lock_class(struct blk_mq_hw_ctx *hctx,
     526             :                 struct lock_class_key *key)
     527             : {
     528             :         lockdep_set_class(&hctx->fq->mq_flush_lock, key);
     529           0 : }
     530             : EXPORT_SYMBOL_GPL(blk_mq_hctx_set_fq_lock_class);

Generated by: LCOV version 1.14