static inline int ll_new_hw_segment(struct request_queue *q, struct request *req, struct bio *bio) { int nr_phys_segs = bio_phys_segments(q, bio); if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(q)) goto no_merge; if (blk_integrity_merge_bio(q, req, bio) == false) goto no_merge; /* * This will form the start of a new hw segment. Bump both * counters. */ req->nr_phys_segments += nr_phys_segs; return 1; no_merge: req->cmd_flags |= REQ_NOMERGE; if (req == q->last_merge) q->last_merge = NULL; return 0; }
void blk_recount_segments(struct request_queue *q, struct bio *bio) { if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) && bio->bi_vcnt < queue_max_segments(q)) bio->bi_phys_segments = bio->bi_vcnt; else { struct bio *nxt = bio->bi_next; bio->bi_next = NULL; bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false); bio->bi_next = nxt; } bio->bi_flags |= (1 << BIO_SEG_VALID); }
static int ll_merge_requests_fn(struct request_queue *q, struct request *req, struct request *next) { int total_phys_segments; unsigned int seg_size = req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size; /* * First check if the either of the requests are re-queued * requests. Can't merge them if they are. */ if (req_no_special_merge(req) || req_no_special_merge(next)) return 0; if (test_bit(QUEUE_FLAG_SG_GAPS, &q->queue_flags) && req_gap_to_prev(req, next)) return 0; /* * Will it become too large? */ if ((blk_rq_sectors(req) + blk_rq_sectors(next)) > blk_rq_get_max_sectors(req)) return 0; total_phys_segments = req->nr_phys_segments + next->nr_phys_segments; if (blk_phys_contig_segment(q, req->biotail, next->bio)) { if (req->nr_phys_segments == 1) req->bio->bi_seg_front_size = seg_size; if (next->nr_phys_segments == 1) next->biotail->bi_seg_back_size = seg_size; total_phys_segments--; } if (total_phys_segments > queue_max_segments(q)) return 0; if (blk_integrity_merge_rq(q, req, next) == false) return 0; /* Merge is OK... */ req->nr_phys_segments = total_phys_segments; return 1; }
void blk_recount_segments(struct request_queue *q, struct bio *bio) { bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags); if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) && bio->bi_vcnt < queue_max_segments(q)) bio->bi_phys_segments = bio->bi_vcnt; else { struct bio *nxt = bio->bi_next; bio->bi_next = NULL; bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, no_sg_merge); bio->bi_next = nxt; } bio->bi_flags |= (1 << BIO_SEG_VALID); }
void blk_recount_segments(struct request_queue *q, struct bio *bio) { unsigned short seg_cnt; /* estimate segment number by bi_vcnt for non-cloned bio */ if (bio_flagged(bio, BIO_CLONED)) seg_cnt = bio_segments(bio); else seg_cnt = bio->bi_vcnt; if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags) && (seg_cnt < queue_max_segments(q))) bio->bi_phys_segments = seg_cnt; else { struct bio *nxt = bio->bi_next; bio->bi_next = NULL; bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, false); bio->bi_next = nxt; } bio->bi_flags |= (1 << BIO_SEG_VALID); }
static ssize_t queue_max_segments_show(struct request_queue *q, char *page) { return queue_var_show(queue_max_segments(q), (page)); }