|
@@ -13,7 +13,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
|
|
struct bio *bio)
|
|
struct bio *bio)
|
|
{
|
|
{
|
|
struct bio_vec bv, bvprv = { NULL };
|
|
struct bio_vec bv, bvprv = { NULL };
|
|
- int cluster, high, highprv = 1;
|
|
|
|
|
|
+ int cluster, high, highprv = 1, no_sg_merge;
|
|
unsigned int seg_size, nr_phys_segs;
|
|
unsigned int seg_size, nr_phys_segs;
|
|
struct bio *fbio, *bbio;
|
|
struct bio *fbio, *bbio;
|
|
struct bvec_iter iter;
|
|
struct bvec_iter iter;
|
|
@@ -35,12 +35,21 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
|
|
cluster = blk_queue_cluster(q);
|
|
cluster = blk_queue_cluster(q);
|
|
seg_size = 0;
|
|
seg_size = 0;
|
|
nr_phys_segs = 0;
|
|
nr_phys_segs = 0;
|
|
|
|
+ no_sg_merge = test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags);
|
|
|
|
+ high = 0;
|
|
for_each_bio(bio) {
|
|
for_each_bio(bio) {
|
|
bio_for_each_segment(bv, bio, iter) {
|
|
bio_for_each_segment(bv, bio, iter) {
|
|
|
|
+ /*
|
|
|
|
+ * If SG merging is disabled, each bio vector is
|
|
|
|
+ * a segment
|
|
|
|
+ */
|
|
|
|
+ if (no_sg_merge)
|
|
|
|
+ goto new_segment;
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* the trick here is making sure that a high page is
|
|
* the trick here is making sure that a high page is
|
|
- * never considered part of another segment, since that
|
|
|
|
- * might change with the bounce page.
|
|
|
|
|
|
+ * never considered part of another segment, since
|
|
|
|
+ * that might change with the bounce page.
|
|
*/
|
|
*/
|
|
high = page_to_pfn(bv.bv_page) > queue_bounce_pfn(q);
|
|
high = page_to_pfn(bv.bv_page) > queue_bounce_pfn(q);
|
|
if (!high && !highprv && cluster) {
|
|
if (!high && !highprv && cluster) {
|
|
@@ -84,11 +93,16 @@ void blk_recalc_rq_segments(struct request *rq)
|
|
|
|
|
|
void blk_recount_segments(struct request_queue *q, struct bio *bio)
|
|
void blk_recount_segments(struct request_queue *q, struct bio *bio)
|
|
{
|
|
{
|
|
- struct bio *nxt = bio->bi_next;
|
|
|
|
|
|
+ if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags))
|
|
|
|
+ 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);
|
|
|
|
+ bio->bi_next = nxt;
|
|
|
|
+ }
|
|
|
|
|
|
- bio->bi_next = NULL;
|
|
|
|
- bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio);
|
|
|
|
- bio->bi_next = nxt;
|
|
|
|
bio->bi_flags |= (1 << BIO_SEG_VALID);
|
|
bio->bi_flags |= (1 << BIO_SEG_VALID);
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(blk_recount_segments);
|
|
EXPORT_SYMBOL(blk_recount_segments);
|