|
@@ -1672,12 +1672,36 @@ static inline bool bios_segs_mergeable(struct request_queue *q,
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
|
|
|
- struct bio *next)
|
|
|
+static inline bool bio_will_gap(struct request_queue *q,
|
|
|
+ struct request *prev_rq,
|
|
|
+ struct bio *prev,
|
|
|
+ struct bio *next)
|
|
|
{
|
|
|
if (bio_has_data(prev) && queue_virt_boundary(q)) {
|
|
|
struct bio_vec pb, nb;
|
|
|
|
|
|
+ /*
|
|
|
+ * don't merge if the 1st bio starts with non-zero
|
|
|
+ * offset, otherwise it is quite difficult to respect
|
|
|
+ * sg gap limit. We work hard to merge a huge number of small
|
|
|
+ * single bios in case of mkfs.
|
|
|
+ */
|
|
|
+ if (prev_rq)
|
|
|
+ bio_get_first_bvec(prev_rq->bio, &pb);
|
|
|
+ else
|
|
|
+ bio_get_first_bvec(prev, &pb);
|
|
|
+ if (pb.bv_offset)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We don't need to worry about the situation that the
|
|
|
+ * merged segment ends in unaligned virt boundary:
|
|
|
+ *
|
|
|
+ * - if 'pb' ends aligned, the merged segment ends aligned
|
|
|
+ * - if 'pb' ends unaligned, the next bio must include
|
|
|
+ * one single bvec of 'nb', otherwise the 'nb' can't
|
|
|
+ * merge with 'pb'
|
|
|
+ */
|
|
|
bio_get_last_bvec(prev, &pb);
|
|
|
bio_get_first_bvec(next, &nb);
|
|
|
|
|
@@ -1690,12 +1714,12 @@ static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
|
|
|
|
|
|
static inline bool req_gap_back_merge(struct request *req, struct bio *bio)
|
|
|
{
|
|
|
- return bio_will_gap(req->q, req->biotail, bio);
|
|
|
+ return bio_will_gap(req->q, req, req->biotail, bio);
|
|
|
}
|
|
|
|
|
|
static inline bool req_gap_front_merge(struct request *req, struct bio *bio)
|
|
|
{
|
|
|
- return bio_will_gap(req->q, bio, req->bio);
|
|
|
+ return bio_will_gap(req->q, NULL, bio, req->bio);
|
|
|
}
|
|
|
|
|
|
int kblockd_schedule_work(struct work_struct *work);
|