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

Generated by: LCOV version 1.14