LCOV - code coverage report
Current view: top level - drivers/md - dm-rq.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 263 0.0 %
Date: 2022-03-28 16:04:14 Functions: 0 23 0.0 %
Branches: 0 92 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (C) 2016 Red Hat, Inc. All rights reserved.
       3                 :            :  *
       4                 :            :  * This file is released under the GPL.
       5                 :            :  */
       6                 :            : 
       7                 :            : #include "dm-core.h"
       8                 :            : #include "dm-rq.h"
       9                 :            : 
      10                 :            : #include <linux/elevator.h> /* for rq_end_sector() */
      11                 :            : #include <linux/blk-mq.h>
      12                 :            : 
      13                 :            : #define DM_MSG_PREFIX "core-rq"
      14                 :            : 
      15                 :            : /*
      16                 :            :  * One of these is allocated per request.
      17                 :            :  */
      18                 :            : struct dm_rq_target_io {
      19                 :            :         struct mapped_device *md;
      20                 :            :         struct dm_target *ti;
      21                 :            :         struct request *orig, *clone;
      22                 :            :         struct kthread_work work;
      23                 :            :         blk_status_t error;
      24                 :            :         union map_info info;
      25                 :            :         struct dm_stats_aux stats_aux;
      26                 :            :         unsigned long duration_jiffies;
      27                 :            :         unsigned n_sectors;
      28                 :            :         unsigned completed;
      29                 :            : };
      30                 :            : 
      31                 :            : #define DM_MQ_NR_HW_QUEUES 1
      32                 :            : #define DM_MQ_QUEUE_DEPTH 2048
      33                 :            : static unsigned dm_mq_nr_hw_queues = DM_MQ_NR_HW_QUEUES;
      34                 :            : static unsigned dm_mq_queue_depth = DM_MQ_QUEUE_DEPTH;
      35                 :            : 
      36                 :            : /*
      37                 :            :  * Request-based DM's mempools' reserved IOs set by the user.
      38                 :            :  */
      39                 :            : #define RESERVED_REQUEST_BASED_IOS      256
      40                 :            : static unsigned reserved_rq_based_ios = RESERVED_REQUEST_BASED_IOS;
      41                 :            : 
      42                 :          0 : unsigned dm_get_reserved_rq_based_ios(void)
      43                 :            : {
      44                 :          0 :         return __dm_get_module_param(&reserved_rq_based_ios,
      45                 :            :                                      RESERVED_REQUEST_BASED_IOS, DM_RESERVED_MAX_IOS);
      46                 :            : }
      47                 :            : EXPORT_SYMBOL_GPL(dm_get_reserved_rq_based_ios);
      48                 :            : 
      49                 :          0 : static unsigned dm_get_blk_mq_nr_hw_queues(void)
      50                 :            : {
      51                 :          0 :         return __dm_get_module_param(&dm_mq_nr_hw_queues, 1, 32);
      52                 :            : }
      53                 :            : 
      54                 :          0 : static unsigned dm_get_blk_mq_queue_depth(void)
      55                 :            : {
      56                 :          0 :         return __dm_get_module_param(&dm_mq_queue_depth,
      57                 :            :                                      DM_MQ_QUEUE_DEPTH, BLK_MQ_MAX_DEPTH);
      58                 :            : }
      59                 :            : 
      60                 :          0 : int dm_request_based(struct mapped_device *md)
      61                 :            : {
      62                 :          0 :         return queue_is_mq(md->queue);
      63                 :            : }
      64                 :            : 
      65                 :          0 : void dm_start_queue(struct request_queue *q)
      66                 :            : {
      67                 :          0 :         blk_mq_unquiesce_queue(q);
      68                 :          0 :         blk_mq_kick_requeue_list(q);
      69                 :          0 : }
      70                 :            : 
      71                 :          0 : void dm_stop_queue(struct request_queue *q)
      72                 :            : {
      73         [ #  # ]:          0 :         if (blk_mq_queue_stopped(q))
      74                 :            :                 return;
      75                 :            : 
      76                 :          0 :         blk_mq_quiesce_queue(q);
      77                 :            : }
      78                 :            : 
      79                 :            : /*
      80                 :            :  * Partial completion handling for request-based dm
      81                 :            :  */
      82                 :          0 : static void end_clone_bio(struct bio *clone)
      83                 :            : {
      84                 :          0 :         struct dm_rq_clone_bio_info *info =
      85                 :          0 :                 container_of(clone, struct dm_rq_clone_bio_info, clone);
      86                 :          0 :         struct dm_rq_target_io *tio = info->tio;
      87                 :          0 :         unsigned int nr_bytes = info->orig->bi_iter.bi_size;
      88                 :          0 :         blk_status_t error = clone->bi_status;
      89                 :          0 :         bool is_last = !clone->bi_next;
      90                 :            : 
      91                 :          0 :         bio_put(clone);
      92                 :            : 
      93         [ #  # ]:          0 :         if (tio->error)
      94                 :            :                 /*
      95                 :            :                  * An error has already been detected on the request.
      96                 :            :                  * Once error occurred, just let clone->end_io() handle
      97                 :            :                  * the remainder.
      98                 :            :                  */
      99                 :            :                 return;
     100         [ #  # ]:          0 :         else if (error) {
     101                 :            :                 /*
     102                 :            :                  * Don't notice the error to the upper layer yet.
     103                 :            :                  * The error handling decision is made by the target driver,
     104                 :            :                  * when the request is completed.
     105                 :            :                  */
     106                 :          0 :                 tio->error = error;
     107                 :          0 :                 goto exit;
     108                 :            :         }
     109                 :            : 
     110                 :            :         /*
     111                 :            :          * I/O for the bio successfully completed.
     112                 :            :          * Notice the data completion to the upper layer.
     113                 :            :          */
     114                 :          0 :         tio->completed += nr_bytes;
     115                 :            : 
     116                 :            :         /*
     117                 :            :          * Update the original request.
     118                 :            :          * Do not use blk_mq_end_request() here, because it may complete
     119                 :            :          * the original request before the clone, and break the ordering.
     120                 :            :          */
     121         [ #  # ]:          0 :         if (is_last)
     122                 :          0 :  exit:
     123                 :          0 :                 blk_update_request(tio->orig, BLK_STS_OK, tio->completed);
     124                 :            : }
     125                 :            : 
     126                 :          0 : static struct dm_rq_target_io *tio_from_request(struct request *rq)
     127                 :            : {
     128                 :          0 :         return blk_mq_rq_to_pdu(rq);
     129                 :            : }
     130                 :            : 
     131                 :          0 : static void rq_end_stats(struct mapped_device *md, struct request *orig)
     132                 :            : {
     133         [ #  # ]:          0 :         if (unlikely(dm_stats_used(&md->stats))) {
     134                 :          0 :                 struct dm_rq_target_io *tio = tio_from_request(orig);
     135                 :          0 :                 tio->duration_jiffies = jiffies - tio->duration_jiffies;
     136                 :          0 :                 dm_stats_account_io(&md->stats, rq_data_dir(orig),
     137                 :            :                                     blk_rq_pos(orig), tio->n_sectors, true,
     138                 :            :                                     tio->duration_jiffies, &tio->stats_aux);
     139                 :            :         }
     140                 :          0 : }
     141                 :            : 
     142                 :            : /*
     143                 :            :  * Don't touch any member of the md after calling this function because
     144                 :            :  * the md may be freed in dm_put() at the end of this function.
     145                 :            :  * Or do dm_get() before calling this function and dm_put() later.
     146                 :            :  */
     147                 :          0 : static void rq_completed(struct mapped_device *md)
     148                 :            : {
     149                 :            :         /* nudge anyone waiting on suspend queue */
     150         [ #  # ]:          0 :         if (unlikely(wq_has_sleeper(&md->wait)))
     151                 :          0 :                 wake_up(&md->wait);
     152                 :            : 
     153                 :            :         /*
     154                 :            :          * dm_put() must be at the end of this function. See the comment above
     155                 :            :          */
     156                 :          0 :         dm_put(md);
     157                 :          0 : }
     158                 :            : 
     159                 :            : /*
     160                 :            :  * Complete the clone and the original request.
     161                 :            :  * Must be called without clone's queue lock held,
     162                 :            :  * see end_clone_request() for more details.
     163                 :            :  */
     164                 :          0 : static void dm_end_request(struct request *clone, blk_status_t error)
     165                 :            : {
     166                 :          0 :         struct dm_rq_target_io *tio = clone->end_io_data;
     167                 :          0 :         struct mapped_device *md = tio->md;
     168                 :          0 :         struct request *rq = tio->orig;
     169                 :            : 
     170                 :          0 :         blk_rq_unprep_clone(clone);
     171                 :          0 :         tio->ti->type->release_clone_rq(clone, NULL);
     172                 :            : 
     173                 :          0 :         rq_end_stats(md, rq);
     174                 :          0 :         blk_mq_end_request(rq, error);
     175                 :          0 :         rq_completed(md);
     176                 :          0 : }
     177                 :            : 
     178                 :          0 : static void __dm_mq_kick_requeue_list(struct request_queue *q, unsigned long msecs)
     179                 :            : {
     180                 :          0 :         blk_mq_delay_kick_requeue_list(q, msecs);
     181                 :            : }
     182                 :            : 
     183                 :          0 : void dm_mq_kick_requeue_list(struct mapped_device *md)
     184                 :            : {
     185                 :          0 :         __dm_mq_kick_requeue_list(dm_get_md_queue(md), 0);
     186                 :          0 : }
     187                 :            : EXPORT_SYMBOL(dm_mq_kick_requeue_list);
     188                 :            : 
     189                 :          0 : static void dm_mq_delay_requeue_request(struct request *rq, unsigned long msecs)
     190                 :            : {
     191                 :          0 :         blk_mq_requeue_request(rq, false);
     192                 :          0 :         __dm_mq_kick_requeue_list(rq->q, msecs);
     193                 :            : }
     194                 :            : 
     195                 :          0 : static void dm_requeue_original_request(struct dm_rq_target_io *tio, bool delay_requeue)
     196                 :            : {
     197                 :          0 :         struct mapped_device *md = tio->md;
     198                 :          0 :         struct request *rq = tio->orig;
     199         [ #  # ]:          0 :         unsigned long delay_ms = delay_requeue ? 100 : 0;
     200                 :            : 
     201                 :          0 :         rq_end_stats(md, rq);
     202         [ #  # ]:          0 :         if (tio->clone) {
     203                 :          0 :                 blk_rq_unprep_clone(tio->clone);
     204                 :          0 :                 tio->ti->type->release_clone_rq(tio->clone, NULL);
     205                 :            :         }
     206                 :            : 
     207                 :          0 :         dm_mq_delay_requeue_request(rq, delay_ms);
     208                 :          0 :         rq_completed(md);
     209                 :          0 : }
     210                 :            : 
     211                 :          0 : static void dm_done(struct request *clone, blk_status_t error, bool mapped)
     212                 :            : {
     213                 :          0 :         int r = DM_ENDIO_DONE;
     214                 :          0 :         struct dm_rq_target_io *tio = clone->end_io_data;
     215                 :          0 :         dm_request_endio_fn rq_end_io = NULL;
     216                 :            : 
     217         [ #  # ]:          0 :         if (tio->ti) {
     218                 :          0 :                 rq_end_io = tio->ti->type->rq_end_io;
     219                 :            : 
     220         [ #  # ]:          0 :                 if (mapped && rq_end_io)
     221                 :          0 :                         r = rq_end_io(tio->ti, clone, error, &tio->info);
     222                 :            :         }
     223                 :            : 
     224         [ #  # ]:          0 :         if (unlikely(error == BLK_STS_TARGET)) {
     225         [ #  # ]:          0 :                 if (req_op(clone) == REQ_OP_DISCARD &&
     226         [ #  # ]:          0 :                     !clone->q->limits.max_discard_sectors)
     227                 :          0 :                         disable_discard(tio->md);
     228         [ #  # ]:          0 :                 else if (req_op(clone) == REQ_OP_WRITE_SAME &&
     229         [ #  # ]:          0 :                          !clone->q->limits.max_write_same_sectors)
     230                 :          0 :                         disable_write_same(tio->md);
     231         [ #  # ]:          0 :                 else if (req_op(clone) == REQ_OP_WRITE_ZEROES &&
     232         [ #  # ]:          0 :                          !clone->q->limits.max_write_zeroes_sectors)
     233                 :          0 :                         disable_write_zeroes(tio->md);
     234                 :            :         }
     235                 :            : 
     236   [ #  #  #  #  :          0 :         switch (r) {
                      # ]
     237                 :          0 :         case DM_ENDIO_DONE:
     238                 :            :                 /* The target wants to complete the I/O */
     239                 :          0 :                 dm_end_request(clone, error);
     240                 :          0 :                 break;
     241                 :            :         case DM_ENDIO_INCOMPLETE:
     242                 :            :                 /* The target will handle the I/O */
     243                 :            :                 return;
     244                 :          0 :         case DM_ENDIO_REQUEUE:
     245                 :            :                 /* The target wants to requeue the I/O */
     246                 :          0 :                 dm_requeue_original_request(tio, false);
     247                 :          0 :                 break;
     248                 :          0 :         case DM_ENDIO_DELAY_REQUEUE:
     249                 :            :                 /* The target wants to requeue the I/O after a delay */
     250                 :          0 :                 dm_requeue_original_request(tio, true);
     251                 :          0 :                 break;
     252                 :          0 :         default:
     253                 :          0 :                 DMWARN("unimplemented target endio return value: %d", r);
     254                 :          0 :                 BUG();
     255                 :            :         }
     256                 :            : }
     257                 :            : 
     258                 :            : /*
     259                 :            :  * Request completion handler for request-based dm
     260                 :            :  */
     261                 :          0 : static void dm_softirq_done(struct request *rq)
     262                 :            : {
     263                 :          0 :         bool mapped = true;
     264         [ #  # ]:          0 :         struct dm_rq_target_io *tio = tio_from_request(rq);
     265                 :          0 :         struct request *clone = tio->clone;
     266                 :            : 
     267         [ #  # ]:          0 :         if (!clone) {
     268                 :          0 :                 struct mapped_device *md = tio->md;
     269                 :            : 
     270                 :          0 :                 rq_end_stats(md, rq);
     271                 :          0 :                 blk_mq_end_request(rq, tio->error);
     272                 :          0 :                 rq_completed(md);
     273                 :          0 :                 return;
     274                 :            :         }
     275                 :            : 
     276         [ #  # ]:          0 :         if (rq->rq_flags & RQF_FAILED)
     277                 :          0 :                 mapped = false;
     278                 :            : 
     279                 :          0 :         dm_done(clone, tio->error, mapped);
     280                 :            : }
     281                 :            : 
     282                 :            : /*
     283                 :            :  * Complete the clone and the original request with the error status
     284                 :            :  * through softirq context.
     285                 :            :  */
     286                 :          0 : static void dm_complete_request(struct request *rq, blk_status_t error)
     287                 :            : {
     288                 :          0 :         struct dm_rq_target_io *tio = tio_from_request(rq);
     289                 :            : 
     290                 :          0 :         tio->error = error;
     291                 :          0 :         blk_mq_complete_request(rq);
     292                 :          0 : }
     293                 :            : 
     294                 :            : /*
     295                 :            :  * Complete the not-mapped clone and the original request with the error status
     296                 :            :  * through softirq context.
     297                 :            :  * Target's rq_end_io() function isn't called.
     298                 :            :  * This may be used when the target's clone_and_map_rq() function fails.
     299                 :            :  */
     300                 :          0 : static void dm_kill_unmapped_request(struct request *rq, blk_status_t error)
     301                 :            : {
     302                 :          0 :         rq->rq_flags |= RQF_FAILED;
     303                 :          0 :         dm_complete_request(rq, error);
     304                 :          0 : }
     305                 :            : 
     306                 :          0 : static void end_clone_request(struct request *clone, blk_status_t error)
     307                 :            : {
     308                 :          0 :         struct dm_rq_target_io *tio = clone->end_io_data;
     309                 :            : 
     310                 :          0 :         dm_complete_request(tio->orig, error);
     311                 :          0 : }
     312                 :            : 
     313                 :          0 : static blk_status_t dm_dispatch_clone_request(struct request *clone, struct request *rq)
     314                 :            : {
     315                 :          0 :         blk_status_t r;
     316                 :            : 
     317         [ #  # ]:          0 :         if (blk_queue_io_stat(clone->q))
     318                 :          0 :                 clone->rq_flags |= RQF_IO_STAT;
     319                 :            : 
     320                 :          0 :         clone->start_time_ns = ktime_get_ns();
     321                 :          0 :         r = blk_insert_cloned_request(clone->q, clone);
     322   [ #  #  #  # ]:          0 :         if (r != BLK_STS_OK && r != BLK_STS_RESOURCE && r != BLK_STS_DEV_RESOURCE)
     323                 :            :                 /* must complete clone in terms of original request */
     324                 :          0 :                 dm_complete_request(rq, r);
     325                 :          0 :         return r;
     326                 :            : }
     327                 :            : 
     328                 :          0 : static int dm_rq_bio_constructor(struct bio *bio, struct bio *bio_orig,
     329                 :            :                                  void *data)
     330                 :            : {
     331                 :          0 :         struct dm_rq_target_io *tio = data;
     332                 :          0 :         struct dm_rq_clone_bio_info *info =
     333                 :          0 :                 container_of(bio, struct dm_rq_clone_bio_info, clone);
     334                 :            : 
     335                 :          0 :         info->orig = bio_orig;
     336                 :          0 :         info->tio = tio;
     337                 :          0 :         bio->bi_end_io = end_clone_bio;
     338                 :            : 
     339                 :          0 :         return 0;
     340                 :            : }
     341                 :            : 
     342                 :          0 : static int setup_clone(struct request *clone, struct request *rq,
     343                 :            :                        struct dm_rq_target_io *tio, gfp_t gfp_mask)
     344                 :            : {
     345                 :          0 :         int r;
     346                 :            : 
     347                 :          0 :         r = blk_rq_prep_clone(clone, rq, &tio->md->bs, gfp_mask,
     348                 :            :                               dm_rq_bio_constructor, tio);
     349         [ #  # ]:          0 :         if (r)
     350                 :            :                 return r;
     351                 :            : 
     352                 :          0 :         clone->end_io = end_clone_request;
     353                 :          0 :         clone->end_io_data = tio;
     354                 :            : 
     355                 :          0 :         tio->clone = clone;
     356                 :            : 
     357                 :          0 :         return 0;
     358                 :            : }
     359                 :            : 
     360                 :          0 : static void init_tio(struct dm_rq_target_io *tio, struct request *rq,
     361                 :            :                      struct mapped_device *md)
     362                 :            : {
     363                 :          0 :         tio->md = md;
     364                 :          0 :         tio->ti = NULL;
     365                 :          0 :         tio->clone = NULL;
     366                 :          0 :         tio->orig = rq;
     367                 :          0 :         tio->error = 0;
     368                 :          0 :         tio->completed = 0;
     369                 :            :         /*
     370                 :            :          * Avoid initializing info for blk-mq; it passes
     371                 :            :          * target-specific data through info.ptr
     372                 :            :          * (see: dm_mq_init_request)
     373                 :            :          */
     374                 :          0 :         if (!md->init_tio_pdu)
     375                 :          0 :                 memset(&tio->info, 0, sizeof(tio->info));
     376                 :            : }
     377                 :            : 
     378                 :            : /*
     379                 :            :  * Returns:
     380                 :            :  * DM_MAPIO_*       : the request has been processed as indicated
     381                 :            :  * DM_MAPIO_REQUEUE : the original request needs to be immediately requeued
     382                 :            :  * < 0              : the request was completed due to failure
     383                 :            :  */
     384                 :          0 : static int map_request(struct dm_rq_target_io *tio)
     385                 :            : {
     386                 :          0 :         int r;
     387                 :          0 :         struct dm_target *ti = tio->ti;
     388                 :          0 :         struct mapped_device *md = tio->md;
     389                 :          0 :         struct request *rq = tio->orig;
     390                 :          0 :         struct request *clone = NULL;
     391                 :          0 :         blk_status_t ret;
     392                 :            : 
     393                 :          0 :         r = ti->type->clone_and_map_rq(ti, rq, &tio->info, &clone);
     394   [ #  #  #  #  :          0 :         switch (r) {
                      # ]
     395                 :            :         case DM_MAPIO_SUBMITTED:
     396                 :            :                 /* The target has taken the I/O to submit by itself later */
     397                 :            :                 break;
     398                 :          0 :         case DM_MAPIO_REMAPPED:
     399                 :          0 :                 if (setup_clone(clone, rq, tio, GFP_ATOMIC)) {
     400                 :            :                         /* -ENOMEM */
     401                 :          0 :                         ti->type->release_clone_rq(clone, &tio->info);
     402                 :          0 :                         return DM_MAPIO_REQUEUE;
     403                 :            :                 }
     404                 :            : 
     405                 :            :                 /* The target has remapped the I/O so dispatch it */
     406                 :          0 :                 trace_block_rq_remap(clone->q, clone, disk_devt(dm_disk(md)),
     407                 :            :                                      blk_rq_pos(rq));
     408                 :          0 :                 ret = dm_dispatch_clone_request(clone, rq);
     409         [ #  # ]:          0 :                 if (ret == BLK_STS_RESOURCE || ret == BLK_STS_DEV_RESOURCE) {
     410                 :          0 :                         blk_rq_unprep_clone(clone);
     411         [ #  # ]:          0 :                         blk_mq_cleanup_rq(clone);
     412                 :          0 :                         tio->ti->type->release_clone_rq(clone, &tio->info);
     413                 :          0 :                         tio->clone = NULL;
     414                 :          0 :                         return DM_MAPIO_REQUEUE;
     415                 :            :                 }
     416                 :            :                 break;
     417                 :            :         case DM_MAPIO_REQUEUE:
     418                 :            :                 /* The target wants to requeue the I/O */
     419                 :            :                 break;
     420                 :          0 :         case DM_MAPIO_DELAY_REQUEUE:
     421                 :            :                 /* The target wants to requeue the I/O after a delay */
     422                 :          0 :                 dm_requeue_original_request(tio, true);
     423                 :          0 :                 break;
     424                 :            :         case DM_MAPIO_KILL:
     425                 :            :                 /* The target wants to complete the I/O */
     426                 :          0 :                 dm_kill_unmapped_request(rq, BLK_STS_IOERR);
     427                 :            :                 break;
     428                 :          0 :         default:
     429                 :          0 :                 DMWARN("unimplemented target map return value: %d", r);
     430                 :          0 :                 BUG();
     431                 :            :         }
     432                 :            : 
     433                 :            :         return r;
     434                 :            : }
     435                 :            : 
     436                 :            : /* DEPRECATED: previously used for request-based merge heuristic in dm_request_fn() */
     437                 :          0 : ssize_t dm_attr_rq_based_seq_io_merge_deadline_show(struct mapped_device *md, char *buf)
     438                 :            : {
     439                 :          0 :         return sprintf(buf, "%u\n", 0);
     440                 :            : }
     441                 :            : 
     442                 :          0 : ssize_t dm_attr_rq_based_seq_io_merge_deadline_store(struct mapped_device *md,
     443                 :            :                                                      const char *buf, size_t count)
     444                 :            : {
     445                 :          0 :         return count;
     446                 :            : }
     447                 :            : 
     448                 :          0 : static void dm_start_request(struct mapped_device *md, struct request *orig)
     449                 :            : {
     450                 :          0 :         blk_mq_start_request(orig);
     451                 :            : 
     452         [ #  # ]:          0 :         if (unlikely(dm_stats_used(&md->stats))) {
     453                 :          0 :                 struct dm_rq_target_io *tio = tio_from_request(orig);
     454                 :          0 :                 tio->duration_jiffies = jiffies;
     455                 :          0 :                 tio->n_sectors = blk_rq_sectors(orig);
     456                 :          0 :                 dm_stats_account_io(&md->stats, rq_data_dir(orig),
     457                 :            :                                     blk_rq_pos(orig), tio->n_sectors, false, 0,
     458                 :            :                                     &tio->stats_aux);
     459                 :            :         }
     460                 :            : 
     461                 :            :         /*
     462                 :            :          * Hold the md reference here for the in-flight I/O.
     463                 :            :          * We can't rely on the reference count by device opener,
     464                 :            :          * because the device may be closed during the request completion
     465                 :            :          * when all bios are completed.
     466                 :            :          * See the comment in rq_completed() too.
     467                 :            :          */
     468                 :          0 :         dm_get(md);
     469                 :          0 : }
     470                 :            : 
     471                 :          0 : static int dm_mq_init_request(struct blk_mq_tag_set *set, struct request *rq,
     472                 :            :                               unsigned int hctx_idx, unsigned int numa_node)
     473                 :            : {
     474                 :          0 :         struct mapped_device *md = set->driver_data;
     475         [ #  # ]:          0 :         struct dm_rq_target_io *tio = blk_mq_rq_to_pdu(rq);
     476                 :            : 
     477                 :            :         /*
     478                 :            :          * Must initialize md member of tio, otherwise it won't
     479                 :            :          * be available in dm_mq_queue_rq.
     480                 :            :          */
     481                 :          0 :         tio->md = md;
     482                 :            : 
     483         [ #  # ]:          0 :         if (md->init_tio_pdu) {
     484                 :            :                 /* target-specific per-io data is immediately after the tio */
     485                 :          0 :                 tio->info.ptr = tio + 1;
     486                 :            :         }
     487                 :            : 
     488                 :          0 :         return 0;
     489                 :            : }
     490                 :            : 
     491                 :          0 : static blk_status_t dm_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
     492                 :            :                           const struct blk_mq_queue_data *bd)
     493                 :            : {
     494                 :          0 :         struct request *rq = bd->rq;
     495         [ #  # ]:          0 :         struct dm_rq_target_io *tio = blk_mq_rq_to_pdu(rq);
     496                 :          0 :         struct mapped_device *md = tio->md;
     497                 :          0 :         struct dm_target *ti = md->immutable_target;
     498                 :            : 
     499         [ #  # ]:          0 :         if (unlikely(!ti)) {
     500                 :          0 :                 int srcu_idx;
     501                 :          0 :                 struct dm_table *map = dm_get_live_table(md, &srcu_idx);
     502                 :            : 
     503                 :          0 :                 ti = dm_table_find_target(map, 0);
     504                 :          0 :                 dm_put_live_table(md, srcu_idx);
     505                 :            :         }
     506                 :            : 
     507   [ #  #  #  # ]:          0 :         if (ti->type->busy && ti->type->busy(ti))
     508                 :            :                 return BLK_STS_RESOURCE;
     509                 :            : 
     510                 :          0 :         dm_start_request(md, rq);
     511                 :            : 
     512                 :            :         /* Init tio using md established in .init_request */
     513         [ #  # ]:          0 :         init_tio(tio, rq, md);
     514                 :            : 
     515                 :            :         /*
     516                 :            :          * Establish tio->ti before calling map_request().
     517                 :            :          */
     518                 :          0 :         tio->ti = ti;
     519                 :            : 
     520                 :            :         /* Direct call is fine since .queue_rq allows allocations */
     521         [ #  # ]:          0 :         if (map_request(tio) == DM_MAPIO_REQUEUE) {
     522                 :            :                 /* Undo dm_start_request() before requeuing */
     523                 :          0 :                 rq_end_stats(md, rq);
     524                 :          0 :                 rq_completed(md);
     525                 :          0 :                 return BLK_STS_RESOURCE;
     526                 :            :         }
     527                 :            : 
     528                 :            :         return BLK_STS_OK;
     529                 :            : }
     530                 :            : 
     531                 :            : static const struct blk_mq_ops dm_mq_ops = {
     532                 :            :         .queue_rq = dm_mq_queue_rq,
     533                 :            :         .complete = dm_softirq_done,
     534                 :            :         .init_request = dm_mq_init_request,
     535                 :            : };
     536                 :            : 
     537                 :          0 : int dm_mq_init_request_queue(struct mapped_device *md, struct dm_table *t)
     538                 :            : {
     539                 :          0 :         struct request_queue *q;
     540                 :          0 :         struct dm_target *immutable_tgt;
     541                 :          0 :         int err;
     542                 :            : 
     543                 :          0 :         md->tag_set = kzalloc_node(sizeof(struct blk_mq_tag_set), GFP_KERNEL, md->numa_node_id);
     544         [ #  # ]:          0 :         if (!md->tag_set)
     545                 :            :                 return -ENOMEM;
     546                 :            : 
     547                 :          0 :         md->tag_set->ops = &dm_mq_ops;
     548                 :          0 :         md->tag_set->queue_depth = dm_get_blk_mq_queue_depth();
     549                 :          0 :         md->tag_set->numa_node = md->numa_node_id;
     550                 :          0 :         md->tag_set->flags = BLK_MQ_F_SHOULD_MERGE;
     551                 :          0 :         md->tag_set->nr_hw_queues = dm_get_blk_mq_nr_hw_queues();
     552                 :          0 :         md->tag_set->driver_data = md;
     553                 :            : 
     554                 :          0 :         md->tag_set->cmd_size = sizeof(struct dm_rq_target_io);
     555                 :          0 :         immutable_tgt = dm_table_get_immutable_target(t);
     556   [ #  #  #  # ]:          0 :         if (immutable_tgt && immutable_tgt->per_io_data_size) {
     557                 :            :                 /* any target-specific per-io data is immediately after the tio */
     558                 :          0 :                 md->tag_set->cmd_size += immutable_tgt->per_io_data_size;
     559                 :          0 :                 md->init_tio_pdu = true;
     560                 :            :         }
     561                 :            : 
     562                 :          0 :         err = blk_mq_alloc_tag_set(md->tag_set);
     563         [ #  # ]:          0 :         if (err)
     564                 :          0 :                 goto out_kfree_tag_set;
     565                 :            : 
     566                 :          0 :         q = blk_mq_init_allocated_queue(md->tag_set, md->queue, true);
     567         [ #  # ]:          0 :         if (IS_ERR(q)) {
     568                 :          0 :                 err = PTR_ERR(q);
     569                 :          0 :                 goto out_tag_set;
     570                 :            :         }
     571                 :            : 
     572                 :            :         return 0;
     573                 :            : 
     574                 :            : out_tag_set:
     575                 :          0 :         blk_mq_free_tag_set(md->tag_set);
     576                 :          0 : out_kfree_tag_set:
     577                 :          0 :         kfree(md->tag_set);
     578                 :            : 
     579                 :          0 :         return err;
     580                 :            : }
     581                 :            : 
     582                 :          0 : void dm_mq_cleanup_mapped_device(struct mapped_device *md)
     583                 :            : {
     584         [ #  # ]:          0 :         if (md->tag_set) {
     585                 :          0 :                 blk_mq_free_tag_set(md->tag_set);
     586                 :          0 :                 kfree(md->tag_set);
     587                 :            :         }
     588                 :          0 : }
     589                 :            : 
     590                 :            : module_param(reserved_rq_based_ios, uint, S_IRUGO | S_IWUSR);
     591                 :            : MODULE_PARM_DESC(reserved_rq_based_ios, "Reserved IOs in request-based mempools");
     592                 :            : 
     593                 :            : /* Unused, but preserved for userspace compatibility */
     594                 :            : static bool use_blk_mq = true;
     595                 :            : module_param(use_blk_mq, bool, S_IRUGO | S_IWUSR);
     596                 :            : MODULE_PARM_DESC(use_blk_mq, "Use block multiqueue for request-based DM devices");
     597                 :            : 
     598                 :            : module_param(dm_mq_nr_hw_queues, uint, S_IRUGO | S_IWUSR);
     599                 :            : MODULE_PARM_DESC(dm_mq_nr_hw_queues, "Number of hardware queues for request-based dm-mq devices");
     600                 :            : 
     601                 :            : module_param(dm_mq_queue_depth, uint, S_IRUGO | S_IWUSR);
     602                 :            : MODULE_PARM_DESC(dm_mq_queue_depth, "Queue depth for request-based dm-mq devices");

Generated by: LCOV version 1.14