linux/block/blk-merge.c
<<
>>
Prefs
   1/*
   2 * Functions related to segment and merge handling
   3 */
   4#include <linux/kernel.h>
   5#include <linux/module.h>
   6#include <linux/bio.h>
   7#include <linux/blkdev.h>
   8#include <linux/scatterlist.h>
   9
  10#include "blk.h"
  11
  12static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
  13                                             struct bio *bio)
  14{
  15        struct bio_vec *bv, *bvprv = NULL;
  16        int cluster, i, high, highprv = 1;
  17        unsigned int seg_size, nr_phys_segs;
  18        struct bio *fbio, *bbio;
  19
  20        if (!bio)
  21                return 0;
  22
  23        fbio = bio;
  24        cluster = blk_queue_cluster(q);
  25        seg_size = 0;
  26        nr_phys_segs = 0;
  27        for_each_bio(bio) {
  28                bio_for_each_segment(bv, bio, i) {
  29                        /*
  30                         * the trick here is making sure that a high page is
  31                         * never considered part of another segment, since that
  32                         * might change with the bounce page.
  33                         */
  34                        high = page_to_pfn(bv->bv_page) > queue_bounce_pfn(q);
  35                        if (high || highprv)
  36                                goto new_segment;
  37                        if (cluster) {
  38                                if (seg_size + bv->bv_len
  39                                    > queue_max_segment_size(q))
  40                                        goto new_segment;
  41                                if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv))
  42                                        goto new_segment;
  43                                if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv))
  44                                        goto new_segment;
  45
  46                                seg_size += bv->bv_len;
  47                                bvprv = bv;
  48                                continue;
  49                        }
  50new_segment:
  51                        if (nr_phys_segs == 1 && seg_size >
  52                            fbio->bi_seg_front_size)
  53                                fbio->bi_seg_front_size = seg_size;
  54
  55                        nr_phys_segs++;
  56                        bvprv = bv;
  57                        seg_size = bv->bv_len;
  58                        highprv = high;
  59                }
  60                bbio = bio;
  61        }
  62
  63        if (nr_phys_segs == 1 && seg_size > fbio->bi_seg_front_size)
  64                fbio->bi_seg_front_size = seg_size;
  65        if (seg_size > bbio->bi_seg_back_size)
  66                bbio->bi_seg_back_size = seg_size;
  67
  68        return nr_phys_segs;
  69}
  70
  71void blk_recalc_rq_segments(struct request *rq)
  72{
  73        rq->nr_phys_segments = __blk_recalc_rq_segments(rq->q, rq->bio);
  74}
  75
  76void blk_recount_segments(struct request_queue *q, struct bio *bio)
  77{
  78        struct bio *nxt = bio->bi_next;
  79
  80        bio->bi_next = NULL;
  81        bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio);
  82        bio->bi_next = nxt;
  83        bio->bi_flags |= (1 << BIO_SEG_VALID);
  84}
  85EXPORT_SYMBOL(blk_recount_segments);
  86
  87static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
  88                                   struct bio *nxt)
  89{
  90        if (!blk_queue_cluster(q))
  91                return 0;
  92
  93        if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
  94            queue_max_segment_size(q))
  95                return 0;
  96
  97        if (!bio_has_data(bio))
  98                return 1;
  99
 100        if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
 101                return 0;
 102
 103        /*
 104         * bio and nxt are contiguous in memory; check if the queue allows
 105         * these two to be merged into one
 106         */
 107        if (BIO_SEG_BOUNDARY(q, bio, nxt))
 108                return 1;
 109
 110        return 0;
 111}
 112
 113/*
 114 * map a request to scatterlist, return number of sg entries setup. Caller
 115 * must make sure sg can hold rq->nr_phys_segments entries
 116 */
 117int blk_rq_map_sg(struct request_queue *q, struct request *rq,
 118                  struct scatterlist *sglist)
 119{
 120        struct bio_vec *bvec, *bvprv;
 121        struct req_iterator iter;
 122        struct scatterlist *sg;
 123        int nsegs, cluster;
 124
 125        nsegs = 0;
 126        cluster = blk_queue_cluster(q);
 127
 128        /*
 129         * for each bio in rq
 130         */
 131        bvprv = NULL;
 132        sg = NULL;
 133        rq_for_each_segment(bvec, rq, iter) {
 134                int nbytes = bvec->bv_len;
 135
 136                if (bvprv && cluster) {
 137                        if (sg->length + nbytes > queue_max_segment_size(q))
 138                                goto new_segment;
 139
 140                        if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
 141                                goto new_segment;
 142                        if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
 143                                goto new_segment;
 144
 145                        sg->length += nbytes;
 146                } else {
 147new_segment:
 148                        if (!sg)
 149                                sg = sglist;
 150                        else {
 151                                /*
 152                                 * If the driver previously mapped a shorter
 153                                 * list, we could see a termination bit
 154                                 * prematurely unless it fully inits the sg
 155                                 * table on each mapping. We KNOW that there
 156                                 * must be more entries here or the driver
 157                                 * would be buggy, so force clear the
 158                                 * termination bit to avoid doing a full
 159                                 * sg_init_table() in drivers for each command.
 160                                 */
 161                                sg->page_link &= ~0x02;
 162                                sg = sg_next(sg);
 163                        }
 164
 165                        sg_set_page(sg, bvec->bv_page, nbytes, bvec->bv_offset);
 166                        nsegs++;
 167                }
 168                bvprv = bvec;
 169        } /* segments in rq */
 170
 171
 172        if (unlikely(rq->cmd_flags & REQ_COPY_USER) &&
 173            (blk_rq_bytes(rq) & q->dma_pad_mask)) {
 174                unsigned int pad_len =
 175                        (q->dma_pad_mask & ~blk_rq_bytes(rq)) + 1;
 176
 177                sg->length += pad_len;
 178                rq->extra_len += pad_len;
 179        }
 180
 181        if (q->dma_drain_size && q->dma_drain_needed(rq)) {
 182                if (rq->cmd_flags & REQ_WRITE)
 183                        memset(q->dma_drain_buffer, 0, q->dma_drain_size);
 184
 185                sg->page_link &= ~0x02;
 186                sg = sg_next(sg);
 187                sg_set_page(sg, virt_to_page(q->dma_drain_buffer),
 188                            q->dma_drain_size,
 189                            ((unsigned long)q->dma_drain_buffer) &
 190                            (PAGE_SIZE - 1));
 191                nsegs++;
 192                rq->extra_len += q->dma_drain_size;
 193        }
 194
 195        if (sg)
 196                sg_mark_end(sg);
 197
 198        return nsegs;
 199}
 200EXPORT_SYMBOL(blk_rq_map_sg);
 201
 202static inline int ll_new_hw_segment(struct request_queue *q,
 203                                    struct request *req,
 204                                    struct bio *bio)
 205{
 206        int nr_phys_segs = bio_phys_segments(q, bio);
 207
 208        if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(q))
 209                goto no_merge;
 210
 211        if (bio_integrity(bio) && blk_integrity_merge_bio(q, req, bio))
 212                goto no_merge;
 213
 214        /*
 215         * This will form the start of a new hw segment.  Bump both
 216         * counters.
 217         */
 218        req->nr_phys_segments += nr_phys_segs;
 219        return 1;
 220
 221no_merge:
 222        req->cmd_flags |= REQ_NOMERGE;
 223        if (req == q->last_merge)
 224                q->last_merge = NULL;
 225        return 0;
 226}
 227
 228int ll_back_merge_fn(struct request_queue *q, struct request *req,
 229                     struct bio *bio)
 230{
 231        unsigned short max_sectors;
 232
 233        if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC))
 234                max_sectors = queue_max_hw_sectors(q);
 235        else
 236                max_sectors = queue_max_sectors(q);
 237
 238        if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
 239                req->cmd_flags |= REQ_NOMERGE;
 240                if (req == q->last_merge)
 241                        q->last_merge = NULL;
 242                return 0;
 243        }
 244        if (!bio_flagged(req->biotail, BIO_SEG_VALID))
 245                blk_recount_segments(q, req->biotail);
 246        if (!bio_flagged(bio, BIO_SEG_VALID))
 247                blk_recount_segments(q, bio);
 248
 249        return ll_new_hw_segment(q, req, bio);
 250}
 251
 252int ll_front_merge_fn(struct request_queue *q, struct request *req,
 253                      struct bio *bio)
 254{
 255        unsigned short max_sectors;
 256
 257        if (unlikely(req->cmd_type == REQ_TYPE_BLOCK_PC))
 258                max_sectors = queue_max_hw_sectors(q);
 259        else
 260                max_sectors = queue_max_sectors(q);
 261
 262
 263        if (blk_rq_sectors(req) + bio_sectors(bio) > max_sectors) {
 264                req->cmd_flags |= REQ_NOMERGE;
 265                if (req == q->last_merge)
 266                        q->last_merge = NULL;
 267                return 0;
 268        }
 269        if (!bio_flagged(bio, BIO_SEG_VALID))
 270                blk_recount_segments(q, bio);
 271        if (!bio_flagged(req->bio, BIO_SEG_VALID))
 272                blk_recount_segments(q, req->bio);
 273
 274        return ll_new_hw_segment(q, req, bio);
 275}
 276
 277static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
 278                                struct request *next)
 279{
 280        int total_phys_segments;
 281        unsigned int seg_size =
 282                req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;
 283
 284        /*
 285         * First check if the either of the requests are re-queued
 286         * requests.  Can't merge them if they are.
 287         */
 288        if (req->special || next->special)
 289                return 0;
 290
 291        /*
 292         * Will it become too large?
 293         */
 294        if ((blk_rq_sectors(req) + blk_rq_sectors(next)) > queue_max_sectors(q))
 295                return 0;
 296
 297        total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
 298        if (blk_phys_contig_segment(q, req->biotail, next->bio)) {
 299                if (req->nr_phys_segments == 1)
 300                        req->bio->bi_seg_front_size = seg_size;
 301                if (next->nr_phys_segments == 1)
 302                        next->biotail->bi_seg_back_size = seg_size;
 303                total_phys_segments--;
 304        }
 305
 306        if (total_phys_segments > queue_max_segments(q))
 307                return 0;
 308
 309        if (blk_integrity_rq(req) && blk_integrity_merge_rq(q, req, next))
 310                return 0;
 311
 312        /* Merge is OK... */
 313        req->nr_phys_segments = total_phys_segments;
 314        return 1;
 315}
 316
 317/**
 318 * blk_rq_set_mixed_merge - mark a request as mixed merge
 319 * @rq: request to mark as mixed merge
 320 *
 321 * Description:
 322 *     @rq is about to be mixed merged.  Make sure the attributes
 323 *     which can be mixed are set in each bio and mark @rq as mixed
 324 *     merged.
 325 */
 326void blk_rq_set_mixed_merge(struct request *rq)
 327{
 328        unsigned int ff = rq->cmd_flags & REQ_FAILFAST_MASK;
 329        struct bio *bio;
 330
 331        if (rq->cmd_flags & REQ_MIXED_MERGE)
 332                return;
 333
 334        /*
 335         * @rq will no longer represent mixable attributes for all the
 336         * contained bios.  It will just track those of the first one.
 337         * Distributes the attributs to each bio.
 338         */
 339        for (bio = rq->bio; bio; bio = bio->bi_next) {
 340                WARN_ON_ONCE((bio->bi_rw & REQ_FAILFAST_MASK) &&
 341                             (bio->bi_rw & REQ_FAILFAST_MASK) != ff);
 342                bio->bi_rw |= ff;
 343        }
 344        rq->cmd_flags |= REQ_MIXED_MERGE;
 345}
 346
 347static void blk_account_io_merge(struct request *req)
 348{
 349        if (blk_do_io_stat(req)) {
 350                struct hd_struct *part;
 351                int cpu;
 352
 353                cpu = part_stat_lock();
 354                part = req->part;
 355
 356                part_round_stats(cpu, part);
 357                part_dec_in_flight(part, rq_data_dir(req));
 358
 359                hd_struct_put(part);
 360                part_stat_unlock();
 361        }
 362}
 363
 364/*
 365 * Has to be called with the request spinlock acquired
 366 */
 367static int attempt_merge(struct request_queue *q, struct request *req,
 368                          struct request *next)
 369{
 370        if (!rq_mergeable(req) || !rq_mergeable(next))
 371                return 0;
 372
 373        /*
 374         * Don't merge file system requests and discard requests
 375         */
 376        if ((req->cmd_flags & REQ_DISCARD) != (next->cmd_flags & REQ_DISCARD))
 377                return 0;
 378
 379        /*
 380         * Don't merge discard requests and secure discard requests
 381         */
 382        if ((req->cmd_flags & REQ_SECURE) != (next->cmd_flags & REQ_SECURE))
 383                return 0;
 384
 385        /*
 386         * not contiguous
 387         */
 388        if (blk_rq_pos(req) + blk_rq_sectors(req) != blk_rq_pos(next))
 389                return 0;
 390
 391        if (rq_data_dir(req) != rq_data_dir(next)
 392            || req->rq_disk != next->rq_disk
 393            || next->special)
 394                return 0;
 395
 396        /*
 397         * If we are allowed to merge, then append bio list
 398         * from next to rq and release next. merge_requests_fn
 399         * will have updated segment counts, update sector
 400         * counts here.
 401         */
 402        if (!ll_merge_requests_fn(q, req, next))
 403                return 0;
 404
 405        /*
 406         * If failfast settings disagree or any of the two is already
 407         * a mixed merge, mark both as mixed before proceeding.  This
 408         * makes sure that all involved bios have mixable attributes
 409         * set properly.
 410         */
 411        if ((req->cmd_flags | next->cmd_flags) & REQ_MIXED_MERGE ||
 412            (req->cmd_flags & REQ_FAILFAST_MASK) !=
 413            (next->cmd_flags & REQ_FAILFAST_MASK)) {
 414                blk_rq_set_mixed_merge(req);
 415                blk_rq_set_mixed_merge(next);
 416        }
 417
 418        /*
 419         * At this point we have either done a back merge
 420         * or front merge. We need the smaller start_time of
 421         * the merged requests to be the current request
 422         * for accounting purposes.
 423         */
 424        if (time_after(req->start_time, next->start_time))
 425                req->start_time = next->start_time;
 426
 427        req->biotail->bi_next = next->bio;
 428        req->biotail = next->biotail;
 429
 430        req->__data_len += blk_rq_bytes(next);
 431
 432        elv_merge_requests(q, req, next);
 433
 434        /*
 435         * 'next' is going away, so update stats accordingly
 436         */
 437        blk_account_io_merge(next);
 438
 439        req->ioprio = ioprio_best(req->ioprio, next->ioprio);
 440        if (blk_rq_cpu_valid(next))
 441                req->cpu = next->cpu;
 442
 443        /* owner-ship of bio passed from next to req */
 444        next->bio = NULL;
 445        __blk_put_request(q, next);
 446        return 1;
 447}
 448
 449int attempt_back_merge(struct request_queue *q, struct request *rq)
 450{
 451        struct request *next = elv_latter_request(q, rq);
 452
 453        if (next)
 454                return attempt_merge(q, rq, next);
 455
 456        return 0;
 457}
 458
 459int attempt_front_merge(struct request_queue *q, struct request *rq)
 460{
 461        struct request *prev = elv_former_request(q, rq);
 462
 463        if (prev)
 464                return attempt_merge(q, prev, rq);
 465
 466        return 0;
 467}
 468
 469int blk_attempt_req_merge(struct request_queue *q, struct request *rq,
 470                          struct request *next)
 471{
 472        return attempt_merge(q, rq, next);
 473}
 474
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.