|
@@ -1607,6 +1607,25 @@ static inline bool bvec_gap_to_prev(struct request_queue *q,
|
|
return __bvec_gap_to_prev(q, bprv, offset);
|
|
return __bvec_gap_to_prev(q, bprv, offset);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ * Check if the two bvecs from two bios can be merged to one segment.
|
|
|
|
+ * If yes, no need to check gap between the two bios since the 1st bio
|
|
|
|
+ * and the 1st bvec in the 2nd bio can be handled in one segment.
|
|
|
|
+ */
|
|
|
|
+static inline bool bios_segs_mergeable(struct request_queue *q,
|
|
|
|
+ struct bio *prev, struct bio_vec *prev_last_bv,
|
|
|
|
+ struct bio_vec *next_first_bv)
|
|
|
|
+{
|
|
|
|
+ if (!BIOVEC_PHYS_MERGEABLE(prev_last_bv, next_first_bv))
|
|
|
|
+ return false;
|
|
|
|
+ if (!BIOVEC_SEG_BOUNDARY(q, prev_last_bv, next_first_bv))
|
|
|
|
+ return false;
|
|
|
|
+ if (prev->bi_seg_back_size + next_first_bv->bv_len >
|
|
|
|
+ queue_max_segment_size(q))
|
|
|
|
+ return false;
|
|
|
|
+ return true;
|
|
|
|
+}
|
|
|
|
+
|
|
static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
|
|
static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
|
|
struct bio *next)
|
|
struct bio *next)
|
|
{
|
|
{
|
|
@@ -1616,7 +1635,8 @@ static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
|
|
bio_get_last_bvec(prev, &pb);
|
|
bio_get_last_bvec(prev, &pb);
|
|
bio_get_first_bvec(next, &nb);
|
|
bio_get_first_bvec(next, &nb);
|
|
|
|
|
|
- return __bvec_gap_to_prev(q, &pb, nb.bv_offset);
|
|
|
|
|
|
+ if (!bios_segs_mergeable(q, prev, &pb, &nb))
|
|
|
|
+ return __bvec_gap_to_prev(q, &pb, nb.bv_offset);
|
|
}
|
|
}
|
|
|
|
|
|
return false;
|
|
return false;
|