On Mon, Dec 19, 2016 at 12:16 PM, Jinpu Wang <jinpu.wang@xxxxxxxxxxxxxxxx> wrote: > Hi Neil, > > After apply the patch below, it paniced during boot in > generic_make_request-> bio_list_pop. > Looks related to you do bio_list_init(&bio_list_on_stack); again. >> diff --git a/block/blk-core.c b/block/blk-core.c >> index 14d7c0740dc0..3436b6fc3ef8 100644 >> --- a/block/blk-core.c >> +++ b/block/blk-core.c >> @@ -2036,10 +2036,31 @@ blk_qc_t generic_make_request(struct bio *bio) >> struct request_queue *q = bdev_get_queue(bio->bi_bdev); >> >> if (likely(blk_queue_enter(q, false) == 0)) { >> + struct bio_list hold; >> + struct bio_list lower, same; >> + >> + /* Create a fresh bio_list for all subordinate requests */ >> + bio_list_merge(&hold, &bio_list_on_stack); >> + bio_list_init(&bio_list_on_stack); ??? maybe init hold, and then merge bio_list_on_stack? >> ret = q->make_request_fn(q, bio); >> >> blk_queue_exit(q); >> >> + /* sort new bios into those for a lower level >> + * and those for the same level >> + */ >> + bio_list_init(&lower); >> + bio_list_init(&same); >> + while ((bio = bio_list_pop(&bio_list_on_stack)) != NULL) >> + if (q == bdev_get_queue(bio->bi_bdev)) >> + bio_list_add(&same, bio); >> + else >> + bio_list_add(&lower, bio); >> + /* now assemble so we handle the lowest level first */ >> + bio_list_merge(&bio_list_on_stack, &lower); >> + bio_list_merge(&bio_list_on_stack, &same); >> + bio_list_merge(&bio_list_on_stack, &hold); >> + >> bio = bio_list_pop(current->bio_list); >> } else { >> struct bio *bio_next = bio_list_pop(current->bio_list); > > Seems we don't need bio_list hold at all, lower and seem merge back to bio_list_on_stack? I'm currently testing patch below, so far so good. diff --git a/block/blk-core.c b/block/blk-core.c index e8d15d8..9c56cf7 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -2064,10 +2064,24 @@ blk_qc_t generic_make_request(struct bio *bio) struct request_queue *q = bdev_get_queue(bio->bi_bdev); if (likely(blk_queue_enter(q, __GFP_DIRECT_RECLAIM) == 0)) { + struct bio_list lower, same; ret = q->make_request_fn(q, bio); blk_queue_exit(q); + /* sort new bios into those for a lower level + * and those for the same level + */ + bio_list_init(&lower); + bio_list_init(&same); + while ((bio = bio_list_pop(&bio_list_on_stack)) != NULL) + if (q == bdev_get_queue(bio->bi_bdev)) + bio_list_add(&same, bio); + else + bio_list_add(&lower, bio); + /* now assemble so we handle the lowest level first */ + bio_list_merge(&bio_list_on_stack, &lower); + bio_list_merge(&bio_list_on_stack, &same); bio = bio_list_pop(current->bio_list); } else { -- Jinpu Wang Linux Kernel Developer ProfitBricks GmbH Greifswalder Str. 207 D - 10405 Berlin Tel: +49 30 577 008 042 Fax: +49 30 577 008 299 Email: jinpu.wang@xxxxxxxxxxxxxxxx URL: https://www.profitbricks.de Sitz der Gesellschaft: Berlin Registergericht: Amtsgericht Charlottenburg, HRB 125506 B Geschäftsführer: Achim Weiss -- To unsubscribe from this list: send the line "unsubscribe linux-raid" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html