Commit 14ccb66b authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

block: remove the bi_phys_segments field in struct bio



We only need the number of segments in the blk-mq submission path.
Remove the field from struct bio, and return it from a variant of
blk_queue_split instead of that it can passed as an argument to
those functions that need the value.

This also means we stop recounting segments except for cloning
and partial segments.

To keep the number of arguments in this how path down remove
pointless struct request_queue arguments from any of the functions
that had it and grew a nr_segs argument.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent f924cdde
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -436,7 +436,6 @@ struct bio {
       struct bvec_iter	bi_iter;	/* current index into bio_vec array */

       unsigned int	bi_size;     /* total size in bytes */
       unsigned short 	bi_phys_segments; /* segments after physaddr coalesce*/
       unsigned short	bi_hw_segments; /* segments after DMA remapping */
       unsigned int	bi_max;	     /* max bio_vecs we can hold
                                        used as index into pool */
+3 −2
Original line number Diff line number Diff line
@@ -2027,7 +2027,8 @@ static void bfq_remove_request(struct request_queue *q,

}

static bool bfq_bio_merge(struct blk_mq_hw_ctx *hctx, struct bio *bio)
static bool bfq_bio_merge(struct blk_mq_hw_ctx *hctx, struct bio *bio,
		unsigned int nr_segs)
{
	struct request_queue *q = hctx->queue;
	struct bfq_data *bfqd = q->elevator->elevator_data;
@@ -2050,7 +2051,7 @@ static bool bfq_bio_merge(struct blk_mq_hw_ctx *hctx, struct bio *bio)
		bfqd->bio_bfqq = NULL;
	bfqd->bio_bic = bic;

	ret = blk_mq_sched_try_merge(q, bio, &free);
	ret = blk_mq_sched_try_merge(q, bio, nr_segs, &free);

	if (free)
		blk_mq_free_request(free);
+1 −14
Original line number Diff line number Diff line
@@ -558,14 +558,6 @@ void bio_put(struct bio *bio)
}
EXPORT_SYMBOL(bio_put);

int bio_phys_segments(struct request_queue *q, struct bio *bio)
{
	if (unlikely(!bio_flagged(bio, BIO_SEG_VALID)))
		blk_recount_segments(q, bio);

	return bio->bi_phys_segments;
}

/**
 * 	__bio_clone_fast - clone a bio that shares the original bio's biovec
 * 	@bio: destination bio
@@ -739,7 +731,7 @@ static int __bio_add_pc_page(struct request_queue *q, struct bio *bio,
	if (bio_full(bio))
		return 0;

	if (bio->bi_phys_segments >= queue_max_segments(q))
	if (bio->bi_vcnt >= queue_max_segments(q))
		return 0;

	bvec = &bio->bi_io_vec[bio->bi_vcnt];
@@ -749,8 +741,6 @@ static int __bio_add_pc_page(struct request_queue *q, struct bio *bio,
	bio->bi_vcnt++;
 done:
	bio->bi_iter.bi_size += len;
	bio->bi_phys_segments = bio->bi_vcnt;
	bio_set_flag(bio, BIO_SEG_VALID);
	return len;
}

@@ -1909,10 +1899,7 @@ void bio_trim(struct bio *bio, int offset, int size)
	if (offset == 0 && size == bio->bi_iter.bi_size)
		return;

	bio_clear_flag(bio, BIO_SEG_VALID);

	bio_advance(bio, offset << 9);

	bio->bi_iter.bi_size = size;

	if (bio_integrity(bio))
+14 −18
Original line number Diff line number Diff line
@@ -550,15 +550,15 @@ void blk_put_request(struct request *req)
}
EXPORT_SYMBOL(blk_put_request);

bool bio_attempt_back_merge(struct request_queue *q, struct request *req,
			    struct bio *bio)
bool bio_attempt_back_merge(struct request *req, struct bio *bio,
		unsigned int nr_segs)
{
	const int ff = bio->bi_opf & REQ_FAILFAST_MASK;

	if (!ll_back_merge_fn(q, req, bio))
	if (!ll_back_merge_fn(req, bio, nr_segs))
		return false;

	trace_block_bio_backmerge(q, req, bio);
	trace_block_bio_backmerge(req->q, req, bio);

	if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff)
		blk_rq_set_mixed_merge(req);
@@ -571,15 +571,15 @@ bool bio_attempt_back_merge(struct request_queue *q, struct request *req,
	return true;
}

bool bio_attempt_front_merge(struct request_queue *q, struct request *req,
			     struct bio *bio)
bool bio_attempt_front_merge(struct request *req, struct bio *bio,
		unsigned int nr_segs)
{
	const int ff = bio->bi_opf & REQ_FAILFAST_MASK;

	if (!ll_front_merge_fn(q, req, bio))
	if (!ll_front_merge_fn(req, bio, nr_segs))
		return false;

	trace_block_bio_frontmerge(q, req, bio);
	trace_block_bio_frontmerge(req->q, req, bio);

	if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff)
		blk_rq_set_mixed_merge(req);
@@ -621,6 +621,7 @@ no_merge:
 * blk_attempt_plug_merge - try to merge with %current's plugged list
 * @q: request_queue new bio is being queued at
 * @bio: new bio being queued
 * @nr_segs: number of segments in @bio
 * @same_queue_rq: pointer to &struct request that gets filled in when
 * another request associated with @q is found on the plug list
 * (optional, may be %NULL)
@@ -639,7 +640,7 @@ no_merge:
 * Caller must ensure !blk_queue_nomerges(q) beforehand.
 */
bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,
			    struct request **same_queue_rq)
		unsigned int nr_segs, struct request **same_queue_rq)
{
	struct blk_plug *plug;
	struct request *rq;
@@ -668,10 +669,10 @@ bool blk_attempt_plug_merge(struct request_queue *q, struct bio *bio,

		switch (blk_try_merge(rq, bio)) {
		case ELEVATOR_BACK_MERGE:
			merged = bio_attempt_back_merge(q, rq, bio);
			merged = bio_attempt_back_merge(rq, bio, nr_segs);
			break;
		case ELEVATOR_FRONT_MERGE:
			merged = bio_attempt_front_merge(q, rq, bio);
			merged = bio_attempt_front_merge(rq, bio, nr_segs);
			break;
		case ELEVATOR_DISCARD_MERGE:
			merged = bio_attempt_discard_merge(q, rq, bio);
@@ -1427,14 +1428,9 @@ bool blk_update_request(struct request *req, blk_status_t error,
}
EXPORT_SYMBOL_GPL(blk_update_request);

void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
		     struct bio *bio)
void blk_rq_bio_prep(struct request *rq, struct bio *bio, unsigned int nr_segs)
{
	if (bio_has_data(bio))
		rq->nr_phys_segments = bio_phys_segments(q, bio);
	else if (bio_op(bio) == REQ_OP_DISCARD)
		rq->nr_phys_segments = 1;

	rq->nr_phys_segments = nr_segs;
	rq->__data_len = bio->bi_iter.bi_size;
	rq->bio = rq->biotail = bio;
	rq->ioprio = bio_prio(bio);
+8 −2
Original line number Diff line number Diff line
@@ -18,13 +18,19 @@
int blk_rq_append_bio(struct request *rq, struct bio **bio)
{
	struct bio *orig_bio = *bio;
	struct bvec_iter iter;
	struct bio_vec bv;
	unsigned int nr_segs = 0;

	blk_queue_bounce(rq->q, bio);

	bio_for_each_bvec(bv, *bio, iter)
		nr_segs++;

	if (!rq->bio) {
		blk_rq_bio_prep(rq->q, rq, *bio);
		blk_rq_bio_prep(rq, *bio, nr_segs);
	} else {
		if (!ll_back_merge_fn(rq->q, rq, *bio)) {
		if (!ll_back_merge_fn(rq, *bio, nr_segs)) {
			if (orig_bio != *bio) {
				bio_put(*bio);
				*bio = orig_bio;
Loading