1*d6d48196SJens Axboe /* 2*d6d48196SJens Axboe * Functions related to segment and merge handling 3*d6d48196SJens Axboe */ 4*d6d48196SJens Axboe #include <linux/kernel.h> 5*d6d48196SJens Axboe #include <linux/module.h> 6*d6d48196SJens Axboe #include <linux/bio.h> 7*d6d48196SJens Axboe #include <linux/blkdev.h> 8*d6d48196SJens Axboe #include <linux/scatterlist.h> 9*d6d48196SJens Axboe 10*d6d48196SJens Axboe #include "blk.h" 11*d6d48196SJens Axboe 12*d6d48196SJens Axboe void blk_recalc_rq_sectors(struct request *rq, int nsect) 13*d6d48196SJens Axboe { 14*d6d48196SJens Axboe if (blk_fs_request(rq)) { 15*d6d48196SJens Axboe rq->hard_sector += nsect; 16*d6d48196SJens Axboe rq->hard_nr_sectors -= nsect; 17*d6d48196SJens Axboe 18*d6d48196SJens Axboe /* 19*d6d48196SJens Axboe * Move the I/O submission pointers ahead if required. 20*d6d48196SJens Axboe */ 21*d6d48196SJens Axboe if ((rq->nr_sectors >= rq->hard_nr_sectors) && 22*d6d48196SJens Axboe (rq->sector <= rq->hard_sector)) { 23*d6d48196SJens Axboe rq->sector = rq->hard_sector; 24*d6d48196SJens Axboe rq->nr_sectors = rq->hard_nr_sectors; 25*d6d48196SJens Axboe rq->hard_cur_sectors = bio_cur_sectors(rq->bio); 26*d6d48196SJens Axboe rq->current_nr_sectors = rq->hard_cur_sectors; 27*d6d48196SJens Axboe rq->buffer = bio_data(rq->bio); 28*d6d48196SJens Axboe } 29*d6d48196SJens Axboe 30*d6d48196SJens Axboe /* 31*d6d48196SJens Axboe * if total number of sectors is less than the first segment 32*d6d48196SJens Axboe * size, something has gone terribly wrong 33*d6d48196SJens Axboe */ 34*d6d48196SJens Axboe if (rq->nr_sectors < rq->current_nr_sectors) { 35*d6d48196SJens Axboe printk("blk: request botched\n"); 36*d6d48196SJens Axboe rq->nr_sectors = rq->current_nr_sectors; 37*d6d48196SJens Axboe } 38*d6d48196SJens Axboe } 39*d6d48196SJens Axboe } 40*d6d48196SJens Axboe 41*d6d48196SJens Axboe void blk_recalc_rq_segments(struct request *rq) 42*d6d48196SJens Axboe { 43*d6d48196SJens Axboe int nr_phys_segs; 44*d6d48196SJens Axboe int nr_hw_segs; 45*d6d48196SJens Axboe unsigned int phys_size; 46*d6d48196SJens Axboe unsigned int hw_size; 47*d6d48196SJens Axboe struct bio_vec *bv, *bvprv = NULL; 48*d6d48196SJens Axboe int seg_size; 49*d6d48196SJens Axboe int hw_seg_size; 50*d6d48196SJens Axboe int cluster; 51*d6d48196SJens Axboe struct req_iterator iter; 52*d6d48196SJens Axboe int high, highprv = 1; 53*d6d48196SJens Axboe struct request_queue *q = rq->q; 54*d6d48196SJens Axboe 55*d6d48196SJens Axboe if (!rq->bio) 56*d6d48196SJens Axboe return; 57*d6d48196SJens Axboe 58*d6d48196SJens Axboe cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER); 59*d6d48196SJens Axboe hw_seg_size = seg_size = 0; 60*d6d48196SJens Axboe phys_size = hw_size = nr_phys_segs = nr_hw_segs = 0; 61*d6d48196SJens Axboe rq_for_each_segment(bv, rq, iter) { 62*d6d48196SJens Axboe /* 63*d6d48196SJens Axboe * the trick here is making sure that a high page is never 64*d6d48196SJens Axboe * considered part of another segment, since that might 65*d6d48196SJens Axboe * change with the bounce page. 66*d6d48196SJens Axboe */ 67*d6d48196SJens Axboe high = page_to_pfn(bv->bv_page) > q->bounce_pfn; 68*d6d48196SJens Axboe if (high || highprv) 69*d6d48196SJens Axboe goto new_hw_segment; 70*d6d48196SJens Axboe if (cluster) { 71*d6d48196SJens Axboe if (seg_size + bv->bv_len > q->max_segment_size) 72*d6d48196SJens Axboe goto new_segment; 73*d6d48196SJens Axboe if (!BIOVEC_PHYS_MERGEABLE(bvprv, bv)) 74*d6d48196SJens Axboe goto new_segment; 75*d6d48196SJens Axboe if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bv)) 76*d6d48196SJens Axboe goto new_segment; 77*d6d48196SJens Axboe if (BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv->bv_len)) 78*d6d48196SJens Axboe goto new_hw_segment; 79*d6d48196SJens Axboe 80*d6d48196SJens Axboe seg_size += bv->bv_len; 81*d6d48196SJens Axboe hw_seg_size += bv->bv_len; 82*d6d48196SJens Axboe bvprv = bv; 83*d6d48196SJens Axboe continue; 84*d6d48196SJens Axboe } 85*d6d48196SJens Axboe new_segment: 86*d6d48196SJens Axboe if (BIOVEC_VIRT_MERGEABLE(bvprv, bv) && 87*d6d48196SJens Axboe !BIOVEC_VIRT_OVERSIZE(hw_seg_size + bv->bv_len)) 88*d6d48196SJens Axboe hw_seg_size += bv->bv_len; 89*d6d48196SJens Axboe else { 90*d6d48196SJens Axboe new_hw_segment: 91*d6d48196SJens Axboe if (nr_hw_segs == 1 && 92*d6d48196SJens Axboe hw_seg_size > rq->bio->bi_hw_front_size) 93*d6d48196SJens Axboe rq->bio->bi_hw_front_size = hw_seg_size; 94*d6d48196SJens Axboe hw_seg_size = BIOVEC_VIRT_START_SIZE(bv) + bv->bv_len; 95*d6d48196SJens Axboe nr_hw_segs++; 96*d6d48196SJens Axboe } 97*d6d48196SJens Axboe 98*d6d48196SJens Axboe nr_phys_segs++; 99*d6d48196SJens Axboe bvprv = bv; 100*d6d48196SJens Axboe seg_size = bv->bv_len; 101*d6d48196SJens Axboe highprv = high; 102*d6d48196SJens Axboe } 103*d6d48196SJens Axboe 104*d6d48196SJens Axboe if (nr_hw_segs == 1 && 105*d6d48196SJens Axboe hw_seg_size > rq->bio->bi_hw_front_size) 106*d6d48196SJens Axboe rq->bio->bi_hw_front_size = hw_seg_size; 107*d6d48196SJens Axboe if (hw_seg_size > rq->biotail->bi_hw_back_size) 108*d6d48196SJens Axboe rq->biotail->bi_hw_back_size = hw_seg_size; 109*d6d48196SJens Axboe rq->nr_phys_segments = nr_phys_segs; 110*d6d48196SJens Axboe rq->nr_hw_segments = nr_hw_segs; 111*d6d48196SJens Axboe } 112*d6d48196SJens Axboe 113*d6d48196SJens Axboe void blk_recount_segments(struct request_queue *q, struct bio *bio) 114*d6d48196SJens Axboe { 115*d6d48196SJens Axboe struct request rq; 116*d6d48196SJens Axboe struct bio *nxt = bio->bi_next; 117*d6d48196SJens Axboe rq.q = q; 118*d6d48196SJens Axboe rq.bio = rq.biotail = bio; 119*d6d48196SJens Axboe bio->bi_next = NULL; 120*d6d48196SJens Axboe blk_recalc_rq_segments(&rq); 121*d6d48196SJens Axboe bio->bi_next = nxt; 122*d6d48196SJens Axboe bio->bi_phys_segments = rq.nr_phys_segments; 123*d6d48196SJens Axboe bio->bi_hw_segments = rq.nr_hw_segments; 124*d6d48196SJens Axboe bio->bi_flags |= (1 << BIO_SEG_VALID); 125*d6d48196SJens Axboe } 126*d6d48196SJens Axboe EXPORT_SYMBOL(blk_recount_segments); 127*d6d48196SJens Axboe 128*d6d48196SJens Axboe static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, 129*d6d48196SJens Axboe struct bio *nxt) 130*d6d48196SJens Axboe { 131*d6d48196SJens Axboe if (!(q->queue_flags & (1 << QUEUE_FLAG_CLUSTER))) 132*d6d48196SJens Axboe return 0; 133*d6d48196SJens Axboe 134*d6d48196SJens Axboe if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt))) 135*d6d48196SJens Axboe return 0; 136*d6d48196SJens Axboe if (bio->bi_size + nxt->bi_size > q->max_segment_size) 137*d6d48196SJens Axboe return 0; 138*d6d48196SJens Axboe 139*d6d48196SJens Axboe /* 140*d6d48196SJens Axboe * bio and nxt are contigous in memory, check if the queue allows 141*d6d48196SJens Axboe * these two to be merged into one 142*d6d48196SJens Axboe */ 143*d6d48196SJens Axboe if (BIO_SEG_BOUNDARY(q, bio, nxt)) 144*d6d48196SJens Axboe return 1; 145*d6d48196SJens Axboe 146*d6d48196SJens Axboe return 0; 147*d6d48196SJens Axboe } 148*d6d48196SJens Axboe 149*d6d48196SJens Axboe static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio, 150*d6d48196SJens Axboe struct bio *nxt) 151*d6d48196SJens Axboe { 152*d6d48196SJens Axboe if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) 153*d6d48196SJens Axboe blk_recount_segments(q, bio); 154*d6d48196SJens Axboe if (unlikely(!bio_flagged(nxt, BIO_SEG_VALID))) 155*d6d48196SJens Axboe blk_recount_segments(q, nxt); 156*d6d48196SJens Axboe if (!BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)) || 157*d6d48196SJens Axboe BIOVEC_VIRT_OVERSIZE(bio->bi_hw_back_size + nxt->bi_hw_front_size)) 158*d6d48196SJens Axboe return 0; 159*d6d48196SJens Axboe if (bio->bi_hw_back_size + nxt->bi_hw_front_size > q->max_segment_size) 160*d6d48196SJens Axboe return 0; 161*d6d48196SJens Axboe 162*d6d48196SJens Axboe return 1; 163*d6d48196SJens Axboe } 164*d6d48196SJens Axboe 165*d6d48196SJens Axboe /* 166*d6d48196SJens Axboe * map a request to scatterlist, return number of sg entries setup. Caller 167*d6d48196SJens Axboe * must make sure sg can hold rq->nr_phys_segments entries 168*d6d48196SJens Axboe */ 169*d6d48196SJens Axboe int blk_rq_map_sg(struct request_queue *q, struct request *rq, 170*d6d48196SJens Axboe struct scatterlist *sglist) 171*d6d48196SJens Axboe { 172*d6d48196SJens Axboe struct bio_vec *bvec, *bvprv; 173*d6d48196SJens Axboe struct req_iterator iter; 174*d6d48196SJens Axboe struct scatterlist *sg; 175*d6d48196SJens Axboe int nsegs, cluster; 176*d6d48196SJens Axboe 177*d6d48196SJens Axboe nsegs = 0; 178*d6d48196SJens Axboe cluster = q->queue_flags & (1 << QUEUE_FLAG_CLUSTER); 179*d6d48196SJens Axboe 180*d6d48196SJens Axboe /* 181*d6d48196SJens Axboe * for each bio in rq 182*d6d48196SJens Axboe */ 183*d6d48196SJens Axboe bvprv = NULL; 184*d6d48196SJens Axboe sg = NULL; 185*d6d48196SJens Axboe rq_for_each_segment(bvec, rq, iter) { 186*d6d48196SJens Axboe int nbytes = bvec->bv_len; 187*d6d48196SJens Axboe 188*d6d48196SJens Axboe if (bvprv && cluster) { 189*d6d48196SJens Axboe if (sg->length + nbytes > q->max_segment_size) 190*d6d48196SJens Axboe goto new_segment; 191*d6d48196SJens Axboe 192*d6d48196SJens Axboe if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) 193*d6d48196SJens Axboe goto new_segment; 194*d6d48196SJens Axboe if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec)) 195*d6d48196SJens Axboe goto new_segment; 196*d6d48196SJens Axboe 197*d6d48196SJens Axboe sg->length += nbytes; 198*d6d48196SJens Axboe } else { 199*d6d48196SJens Axboe new_segment: 200*d6d48196SJens Axboe if (!sg) 201*d6d48196SJens Axboe sg = sglist; 202*d6d48196SJens Axboe else { 203*d6d48196SJens Axboe /* 204*d6d48196SJens Axboe * If the driver previously mapped a shorter 205*d6d48196SJens Axboe * list, we could see a termination bit 206*d6d48196SJens Axboe * prematurely unless it fully inits the sg 207*d6d48196SJens Axboe * table on each mapping. We KNOW that there 208*d6d48196SJens Axboe * must be more entries here or the driver 209*d6d48196SJens Axboe * would be buggy, so force clear the 210*d6d48196SJens Axboe * termination bit to avoid doing a full 211*d6d48196SJens Axboe * sg_init_table() in drivers for each command. 212*d6d48196SJens Axboe */ 213*d6d48196SJens Axboe sg->page_link &= ~0x02; 214*d6d48196SJens Axboe sg = sg_next(sg); 215*d6d48196SJens Axboe } 216*d6d48196SJens Axboe 217*d6d48196SJens Axboe sg_set_page(sg, bvec->bv_page, nbytes, bvec->bv_offset); 218*d6d48196SJens Axboe nsegs++; 219*d6d48196SJens Axboe } 220*d6d48196SJens Axboe bvprv = bvec; 221*d6d48196SJens Axboe } /* segments in rq */ 222*d6d48196SJens Axboe 223*d6d48196SJens Axboe if (q->dma_drain_size) { 224*d6d48196SJens Axboe sg->page_link &= ~0x02; 225*d6d48196SJens Axboe sg = sg_next(sg); 226*d6d48196SJens Axboe sg_set_page(sg, virt_to_page(q->dma_drain_buffer), 227*d6d48196SJens Axboe q->dma_drain_size, 228*d6d48196SJens Axboe ((unsigned long)q->dma_drain_buffer) & 229*d6d48196SJens Axboe (PAGE_SIZE - 1)); 230*d6d48196SJens Axboe nsegs++; 231*d6d48196SJens Axboe } 232*d6d48196SJens Axboe 233*d6d48196SJens Axboe if (sg) 234*d6d48196SJens Axboe sg_mark_end(sg); 235*d6d48196SJens Axboe 236*d6d48196SJens Axboe return nsegs; 237*d6d48196SJens Axboe } 238*d6d48196SJens Axboe 239*d6d48196SJens Axboe EXPORT_SYMBOL(blk_rq_map_sg); 240*d6d48196SJens Axboe 241*d6d48196SJens Axboe static inline int ll_new_mergeable(struct request_queue *q, 242*d6d48196SJens Axboe struct request *req, 243*d6d48196SJens Axboe struct bio *bio) 244*d6d48196SJens Axboe { 245*d6d48196SJens Axboe int nr_phys_segs = bio_phys_segments(q, bio); 246*d6d48196SJens Axboe 247*d6d48196SJens Axboe if (req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) { 248*d6d48196SJens Axboe req->cmd_flags |= REQ_NOMERGE; 249*d6d48196SJens Axboe if (req == q->last_merge) 250*d6d48196SJens Axboe q->last_merge = NULL; 251*d6d48196SJens Axboe return 0; 252*d6d48196SJens Axboe } 253*d6d48196SJens Axboe 254*d6d48196SJens Axboe /* 255*d6d48196SJens Axboe * A hw segment is just getting larger, bump just the phys 256*d6d48196SJens Axboe * counter. 257*d6d48196SJens Axboe */ 258*d6d48196SJens Axboe req->nr_phys_segments += nr_phys_segs; 259*d6d48196SJens Axboe return 1; 260*d6d48196SJens Axboe } 261*d6d48196SJens Axboe 262*d6d48196SJens Axboe static inline int ll_new_hw_segment(struct request_queue *q, 263*d6d48196SJens Axboe struct request *req, 264*d6d48196SJens Axboe struct bio *bio) 265*d6d48196SJens Axboe { 266*d6d48196SJens Axboe int nr_hw_segs = bio_hw_segments(q, bio); 267*d6d48196SJens Axboe int nr_phys_segs = bio_phys_segments(q, bio); 268*d6d48196SJens Axboe 269*d6d48196SJens Axboe if (req->nr_hw_segments + nr_hw_segs > q->max_hw_segments 270*d6d48196SJens Axboe || req->nr_phys_segments + nr_phys_segs > q->max_phys_segments) { 271*d6d48196SJens Axboe req->cmd_flags |= REQ_NOMERGE; 272*d6d48196SJens Axboe if (req == q->last_merge) 273*d6d48196SJens Axboe q->last_merge = NULL; 274*d6d48196SJens Axboe return 0; 275*d6d48196SJens Axboe } 276*d6d48196SJens Axboe 277*d6d48196SJens Axboe /* 278*d6d48196SJens Axboe * This will form the start of a new hw segment. Bump both 279*d6d48196SJens Axboe * counters. 280*d6d48196SJens Axboe */ 281*d6d48196SJens Axboe req->nr_hw_segments += nr_hw_segs; 282*d6d48196SJens Axboe req->nr_phys_segments += nr_phys_segs; 283*d6d48196SJens Axboe return 1; 284*d6d48196SJens Axboe } 285*d6d48196SJens Axboe 286*d6d48196SJens Axboe int ll_back_merge_fn(struct request_queue *q, struct request *req, 287*d6d48196SJens Axboe struct bio *bio) 288*d6d48196SJens Axboe { 289*d6d48196SJens Axboe unsigned short max_sectors; 290*d6d48196SJens Axboe int len; 291*d6d48196SJens Axboe 292*d6d48196SJens Axboe if (unlikely(blk_pc_request(req))) 293*d6d48196SJens Axboe max_sectors = q->max_hw_sectors; 294*d6d48196SJens Axboe else 295*d6d48196SJens Axboe max_sectors = q->max_sectors; 296*d6d48196SJens Axboe 297*d6d48196SJens Axboe if (req->nr_sectors + bio_sectors(bio) > max_sectors) { 298*d6d48196SJens Axboe req->cmd_flags |= REQ_NOMERGE; 299*d6d48196SJens Axboe if (req == q->last_merge) 300*d6d48196SJens Axboe q->last_merge = NULL; 301*d6d48196SJens Axboe return 0; 302*d6d48196SJens Axboe } 303*d6d48196SJens Axboe if (unlikely(!bio_flagged(req->biotail, BIO_SEG_VALID))) 304*d6d48196SJens Axboe blk_recount_segments(q, req->biotail); 305*d6d48196SJens Axboe if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) 306*d6d48196SJens Axboe blk_recount_segments(q, bio); 307*d6d48196SJens Axboe len = req->biotail->bi_hw_back_size + bio->bi_hw_front_size; 308*d6d48196SJens Axboe if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(req->biotail), __BVEC_START(bio)) && 309*d6d48196SJens Axboe !BIOVEC_VIRT_OVERSIZE(len)) { 310*d6d48196SJens Axboe int mergeable = ll_new_mergeable(q, req, bio); 311*d6d48196SJens Axboe 312*d6d48196SJens Axboe if (mergeable) { 313*d6d48196SJens Axboe if (req->nr_hw_segments == 1) 314*d6d48196SJens Axboe req->bio->bi_hw_front_size = len; 315*d6d48196SJens Axboe if (bio->bi_hw_segments == 1) 316*d6d48196SJens Axboe bio->bi_hw_back_size = len; 317*d6d48196SJens Axboe } 318*d6d48196SJens Axboe return mergeable; 319*d6d48196SJens Axboe } 320*d6d48196SJens Axboe 321*d6d48196SJens Axboe return ll_new_hw_segment(q, req, bio); 322*d6d48196SJens Axboe } 323*d6d48196SJens Axboe 324*d6d48196SJens Axboe int ll_front_merge_fn(struct request_queue *q, struct request *req, 325*d6d48196SJens Axboe struct bio *bio) 326*d6d48196SJens Axboe { 327*d6d48196SJens Axboe unsigned short max_sectors; 328*d6d48196SJens Axboe int len; 329*d6d48196SJens Axboe 330*d6d48196SJens Axboe if (unlikely(blk_pc_request(req))) 331*d6d48196SJens Axboe max_sectors = q->max_hw_sectors; 332*d6d48196SJens Axboe else 333*d6d48196SJens Axboe max_sectors = q->max_sectors; 334*d6d48196SJens Axboe 335*d6d48196SJens Axboe 336*d6d48196SJens Axboe if (req->nr_sectors + bio_sectors(bio) > max_sectors) { 337*d6d48196SJens Axboe req->cmd_flags |= REQ_NOMERGE; 338*d6d48196SJens Axboe if (req == q->last_merge) 339*d6d48196SJens Axboe q->last_merge = NULL; 340*d6d48196SJens Axboe return 0; 341*d6d48196SJens Axboe } 342*d6d48196SJens Axboe len = bio->bi_hw_back_size + req->bio->bi_hw_front_size; 343*d6d48196SJens Axboe if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) 344*d6d48196SJens Axboe blk_recount_segments(q, bio); 345*d6d48196SJens Axboe if (unlikely(!bio_flagged(req->bio, BIO_SEG_VALID))) 346*d6d48196SJens Axboe blk_recount_segments(q, req->bio); 347*d6d48196SJens Axboe if (BIOVEC_VIRT_MERGEABLE(__BVEC_END(bio), __BVEC_START(req->bio)) && 348*d6d48196SJens Axboe !BIOVEC_VIRT_OVERSIZE(len)) { 349*d6d48196SJens Axboe int mergeable = ll_new_mergeable(q, req, bio); 350*d6d48196SJens Axboe 351*d6d48196SJens Axboe if (mergeable) { 352*d6d48196SJens Axboe if (bio->bi_hw_segments == 1) 353*d6d48196SJens Axboe bio->bi_hw_front_size = len; 354*d6d48196SJens Axboe if (req->nr_hw_segments == 1) 355*d6d48196SJens Axboe req->biotail->bi_hw_back_size = len; 356*d6d48196SJens Axboe } 357*d6d48196SJens Axboe return mergeable; 358*d6d48196SJens Axboe } 359*d6d48196SJens Axboe 360*d6d48196SJens Axboe return ll_new_hw_segment(q, req, bio); 361*d6d48196SJens Axboe } 362*d6d48196SJens Axboe 363*d6d48196SJens Axboe static int ll_merge_requests_fn(struct request_queue *q, struct request *req, 364*d6d48196SJens Axboe struct request *next) 365*d6d48196SJens Axboe { 366*d6d48196SJens Axboe int total_phys_segments; 367*d6d48196SJens Axboe int total_hw_segments; 368*d6d48196SJens Axboe 369*d6d48196SJens Axboe /* 370*d6d48196SJens Axboe * First check if the either of the requests are re-queued 371*d6d48196SJens Axboe * requests. Can't merge them if they are. 372*d6d48196SJens Axboe */ 373*d6d48196SJens Axboe if (req->special || next->special) 374*d6d48196SJens Axboe return 0; 375*d6d48196SJens Axboe 376*d6d48196SJens Axboe /* 377*d6d48196SJens Axboe * Will it become too large? 378*d6d48196SJens Axboe */ 379*d6d48196SJens Axboe if ((req->nr_sectors + next->nr_sectors) > q->max_sectors) 380*d6d48196SJens Axboe return 0; 381*d6d48196SJens Axboe 382*d6d48196SJens Axboe total_phys_segments = req->nr_phys_segments + next->nr_phys_segments; 383*d6d48196SJens Axboe if (blk_phys_contig_segment(q, req->biotail, next->bio)) 384*d6d48196SJens Axboe total_phys_segments--; 385*d6d48196SJens Axboe 386*d6d48196SJens Axboe if (total_phys_segments > q->max_phys_segments) 387*d6d48196SJens Axboe return 0; 388*d6d48196SJens Axboe 389*d6d48196SJens Axboe total_hw_segments = req->nr_hw_segments + next->nr_hw_segments; 390*d6d48196SJens Axboe if (blk_hw_contig_segment(q, req->biotail, next->bio)) { 391*d6d48196SJens Axboe int len = req->biotail->bi_hw_back_size + next->bio->bi_hw_front_size; 392*d6d48196SJens Axboe /* 393*d6d48196SJens Axboe * propagate the combined length to the end of the requests 394*d6d48196SJens Axboe */ 395*d6d48196SJens Axboe if (req->nr_hw_segments == 1) 396*d6d48196SJens Axboe req->bio->bi_hw_front_size = len; 397*d6d48196SJens Axboe if (next->nr_hw_segments == 1) 398*d6d48196SJens Axboe next->biotail->bi_hw_back_size = len; 399*d6d48196SJens Axboe total_hw_segments--; 400*d6d48196SJens Axboe } 401*d6d48196SJens Axboe 402*d6d48196SJens Axboe if (total_hw_segments > q->max_hw_segments) 403*d6d48196SJens Axboe return 0; 404*d6d48196SJens Axboe 405*d6d48196SJens Axboe /* Merge is OK... */ 406*d6d48196SJens Axboe req->nr_phys_segments = total_phys_segments; 407*d6d48196SJens Axboe req->nr_hw_segments = total_hw_segments; 408*d6d48196SJens Axboe return 1; 409*d6d48196SJens Axboe } 410*d6d48196SJens Axboe 411*d6d48196SJens Axboe /* 412*d6d48196SJens Axboe * Has to be called with the request spinlock acquired 413*d6d48196SJens Axboe */ 414*d6d48196SJens Axboe static int attempt_merge(struct request_queue *q, struct request *req, 415*d6d48196SJens Axboe struct request *next) 416*d6d48196SJens Axboe { 417*d6d48196SJens Axboe if (!rq_mergeable(req) || !rq_mergeable(next)) 418*d6d48196SJens Axboe return 0; 419*d6d48196SJens Axboe 420*d6d48196SJens Axboe /* 421*d6d48196SJens Axboe * not contiguous 422*d6d48196SJens Axboe */ 423*d6d48196SJens Axboe if (req->sector + req->nr_sectors != next->sector) 424*d6d48196SJens Axboe return 0; 425*d6d48196SJens Axboe 426*d6d48196SJens Axboe if (rq_data_dir(req) != rq_data_dir(next) 427*d6d48196SJens Axboe || req->rq_disk != next->rq_disk 428*d6d48196SJens Axboe || next->special) 429*d6d48196SJens Axboe return 0; 430*d6d48196SJens Axboe 431*d6d48196SJens Axboe /* 432*d6d48196SJens Axboe * If we are allowed to merge, then append bio list 433*d6d48196SJens Axboe * from next to rq and release next. merge_requests_fn 434*d6d48196SJens Axboe * will have updated segment counts, update sector 435*d6d48196SJens Axboe * counts here. 436*d6d48196SJens Axboe */ 437*d6d48196SJens Axboe if (!ll_merge_requests_fn(q, req, next)) 438*d6d48196SJens Axboe return 0; 439*d6d48196SJens Axboe 440*d6d48196SJens Axboe /* 441*d6d48196SJens Axboe * At this point we have either done a back merge 442*d6d48196SJens Axboe * or front merge. We need the smaller start_time of 443*d6d48196SJens Axboe * the merged requests to be the current request 444*d6d48196SJens Axboe * for accounting purposes. 445*d6d48196SJens Axboe */ 446*d6d48196SJens Axboe if (time_after(req->start_time, next->start_time)) 447*d6d48196SJens Axboe req->start_time = next->start_time; 448*d6d48196SJens Axboe 449*d6d48196SJens Axboe req->biotail->bi_next = next->bio; 450*d6d48196SJens Axboe req->biotail = next->biotail; 451*d6d48196SJens Axboe 452*d6d48196SJens Axboe req->nr_sectors = req->hard_nr_sectors += next->hard_nr_sectors; 453*d6d48196SJens Axboe 454*d6d48196SJens Axboe elv_merge_requests(q, req, next); 455*d6d48196SJens Axboe 456*d6d48196SJens Axboe if (req->rq_disk) { 457*d6d48196SJens Axboe disk_round_stats(req->rq_disk); 458*d6d48196SJens Axboe req->rq_disk->in_flight--; 459*d6d48196SJens Axboe } 460*d6d48196SJens Axboe 461*d6d48196SJens Axboe req->ioprio = ioprio_best(req->ioprio, next->ioprio); 462*d6d48196SJens Axboe 463*d6d48196SJens Axboe __blk_put_request(q, next); 464*d6d48196SJens Axboe return 1; 465*d6d48196SJens Axboe } 466*d6d48196SJens Axboe 467*d6d48196SJens Axboe int attempt_back_merge(struct request_queue *q, struct request *rq) 468*d6d48196SJens Axboe { 469*d6d48196SJens Axboe struct request *next = elv_latter_request(q, rq); 470*d6d48196SJens Axboe 471*d6d48196SJens Axboe if (next) 472*d6d48196SJens Axboe return attempt_merge(q, rq, next); 473*d6d48196SJens Axboe 474*d6d48196SJens Axboe return 0; 475*d6d48196SJens Axboe } 476*d6d48196SJens Axboe 477*d6d48196SJens Axboe int attempt_front_merge(struct request_queue *q, struct request *rq) 478*d6d48196SJens Axboe { 479*d6d48196SJens Axboe struct request *prev = elv_former_request(q, rq); 480*d6d48196SJens Axboe 481*d6d48196SJens Axboe if (prev) 482*d6d48196SJens Axboe return attempt_merge(q, prev, rq); 483*d6d48196SJens Axboe 484*d6d48196SJens Axboe return 0; 485*d6d48196SJens Axboe } 486