Re: virtio_blk - kernel BUG at drivers/virtio/virtio_ring.c:160!

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Oct 22, 2014 at 4:05 AM, Jens Axboe <axboe@xxxxxxxxx> wrote:
> On 10/17/2014 07:27 AM, Christoph Hellwig wrote:
>> On Thu, Oct 16, 2014 at 11:17:39AM -0400, Brian Foster wrote:
>>> Hi all,
>>>
>>> Hopefully this is the right list for this report...
>>>
>>> I hit the following kernel bug reliably by running xfstests test
>>> generic/234 against XFS using 10GB LVM test/scratch volumes on top of a
>>> ~100GB virtio_blk block device. The virt block device is file-backed on
>>> the host.
>>
>> Jens, I thought the segment merging bug was fixed a while ago.  Did we
>> manage to not include parts of it for 3.17?
>
> Mings patch went in after 3.17, iirc. Ming?

Sorry, that patch is wrong[1], attachment patch should fix the issue.

[1] http://marc.info/?l=linux-kernel&m=141290430004361&w=2


Thanks,
-- 
Ming Lei
From dde19549352da3fea516d89bbfa25d08b784e229 Mon Sep 17 00:00:00 2001
From: Ming Lei <tom.leiming@xxxxxxxxx>
Date: Wed, 22 Oct 2014 08:30:30 +0800
Subject: [PATCH] blk-merge: recaculate segment if it isn't less than max
 segments

The problem is introduced by commit 764f612c6c3c231b(blk-merge:
don't compute bi_phys_segments from bi_vcnt for cloned bio),
and merge is needed if number of current segment isn't less than
max segments.

Strictly speaking, bio->bi_vcnt shouldn't be used here since
it may not be accurate in cases of both cloned bio or bio cloned
from, but bio_segments() is a bit expensive, and bi_vcnt is still
the biggest number, so the approach should work.

Signed-off-by: Ming Lei <tom.leiming@xxxxxxxxx>
---
 block/blk-merge.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/block/blk-merge.c b/block/blk-merge.c
index ba99351..b3ac40a 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -99,16 +99,17 @@ void blk_recount_segments(struct request_queue *q, struct bio *bio)
 {
 	bool no_sg_merge = !!test_bit(QUEUE_FLAG_NO_SG_MERGE,
 			&q->queue_flags);
+	bool merge_not_need = bio->bi_vcnt < queue_max_segments(q);
 
 	if (no_sg_merge && !bio_flagged(bio, BIO_CLONED) &&
-			bio->bi_vcnt < queue_max_segments(q))
+			merge_not_need)
 		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,
-				no_sg_merge);
+				no_sg_merge && merge_not_need);
 		bio->bi_next = nxt;
 	}
 
-- 
1.7.9.5


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux