From: Mike Snitzer <snitzer@redhat.com>
To: Jeff Moyer <jmoyer@redhat.com>
Cc: axboe@kernel.dk, dm-devel@redhat.com,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: dm: propagate QUEUE_FLAG_NO_SG_MERGE
Date: Sun, 10 Aug 2014 21:11:08 -0400 [thread overview]
Message-ID: <20140811011108.GA13946@redhat.com> (raw)
In-Reply-To: <x49iom3hvle.fsf@segfault.boston.devel.redhat.com>
On Fri, Aug 08 2014 at 11:03am -0400,
Jeff Moyer <jmoyer@redhat.com> wrote:
> Hi,
>
> Commit 05f1dd5 introduced a new queue flag: QUEUE_FLAG_NO_SG_MERGE.
> This gets set by default in blk_mq_init_queue for mq-enabled devices.
> The effect of the flag is to bypass the SG segment merging. Instead,
> the bio->bi_vcnt is used as the number of hardware segments.
>
> With a device mapper target on top of a device with
> QUEUE_FLAG_NO_SG_MERGE set, we can end up sending down more segments
> than a driver is prepared to handle. I ran into this when backporting
> the virtio_blk mq support. It triggerred this BUG_ON, in
> virtio_queue_rq:
>
> BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems);
>
> The queue's max is set here:
> blk_queue_max_segments(q, vblk->sg_elems-2);
>
> Basically, what happens is that a bio is built up for the dm device
> (which does not have the QUEUE_FLAG_NO_SG_MERGE flag set) using
> bio_add_page. That path will call into __blk_recalc_rq_segments, so
> what you end up with is bi_phys_segments being much smaller than bi_vcnt
> (and bi_vcnt grows beyond the maximum sg elements). Then, when the bio
> is submitted, it gets cloned. When the cloned bio is submitted, it will
> end up in blk_recount_segments, here:
>
> if (test_bit(QUEUE_FLAG_NO_SG_MERGE, &q->queue_flags))
> bio->bi_phys_segments = bio->bi_vcnt;
>
> and now we've set bio->bi_phys_segments to a number that is beyond what
> was registered as queue_max_segments by the driver.
>
> The right way to fix this is to propagate the queue flag up the stack.
> Attached is a patch that does this, tested and confirmed to fix the
> problem in my environment.
>
> The rules for propagating the flag are simple:
> - if the flag is set for any underlying device, it must be set for the
> upper device
> - consequently, if the flag is not set for any underlying device, it
> should not be set for the upper device.
Hi Jeff,
Thanks for the patch. But I think you need the following tweak.
Otherwise if the DM table is reloaded (and the devices in the table
happen to change) the flag won't get cleared as needed.
I've folded this in and staged it in linux-next for 3.17 here:
https://git.kernel.org/cgit/linux/kernel/git/device-mapper/linux-dm.git/commit/?h=for-next&id=200612ec33e555a356eebc717630b866ae2b694f
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index feedafd..f9c6cb8 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -1509,7 +1509,9 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
if (!dm_table_supports_write_same(t))
q->limits.max_write_same_sectors = 0;
- if (!dm_table_all_devices_attribute(t, queue_supports_sg_merge))
+ if (dm_table_all_devices_attribute(t, queue_supports_sg_merge))
+ queue_flag_clear_unlocked(QUEUE_FLAG_NO_SG_MERGE, q);
+ else
queue_flag_set_unlocked(QUEUE_FLAG_NO_SG_MERGE, q);
dm_table_set_integrity(t);
prev parent reply other threads:[~2014-08-11 1:11 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-08 15:03 [patch] dm: propagate QUEUE_FLAG_NO_SG_MERGE Jeff Moyer
2014-08-08 15:24 ` Greg KH
2014-08-11 1:11 ` Mike Snitzer [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140811011108.GA13946@redhat.com \
--to=snitzer@redhat.com \
--cc=axboe@kernel.dk \
--cc=dm-devel@redhat.com \
--cc=jmoyer@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).