From patchwork Thu Nov 23 22:52:16 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: NeilBrown X-Patchwork-Id: 10073361 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5B211602DC for ; Thu, 23 Nov 2017 22:52:45 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4D63529FE8 for ; Thu, 23 Nov 2017 22:52:45 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 424832A0A6; Thu, 23 Nov 2017 22:52:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EFCD529FE8 for ; Thu, 23 Nov 2017 22:52:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752460AbdKWWw3 (ORCPT ); Thu, 23 Nov 2017 17:52:29 -0500 Received: from mx2.suse.de ([195.135.220.15]:36834 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753411AbdKWWw2 (ORCPT ); Thu, 23 Nov 2017 17:52:28 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 61F13AB0C; Thu, 23 Nov 2017 22:52:26 +0000 (UTC) From: NeilBrown To: Mikulas Patocka Date: Fri, 24 Nov 2017 09:52:16 +1100 Cc: Mike Snitzer , Jens Axboe , "linux-kernel\@vger.kernel.org" , linux-block@vger.kernel.org, device-mapper development , Zdenek Kabelac Subject: [PATCH] dm: use cloned bio as head, not remainder, in __split_and_process_bio() In-Reply-To: References: <149776047907.23258.8058071140236879834.stgit@noble> <20170618184143.GA10920@kernel.dk> <87poe13rmm.fsf@notabene.neil.brown.name> <87a7zg31vx.fsf@notabene.neil.brown.name> <20171121013533.GA14520@redhat.com> <20171121121049.GA17014@redhat.com> <20171121124311.GA17243@redhat.com> <20171121194709.GA18903@redhat.com> <20171121225119.GA19630@redhat.com> <87bmjv0xos.fsf@notabene.neil.brown.name> Message-ID: <878tewzjz3.fsf@notabene.neil.brown.name> MIME-Version: 1.0 Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When we use bio_clone_bioset() to split off the front part of a bio and chain the two together and submit the remainder to generic_make_request(), it is important that the newly allocated bio is used as the head to be processed immediately, and the original bio gets "bio_advance()"d and sent to generic_make_request() as the remainder. If the newly allocated bio is used as the remainder, and if it then needs to be split again, then the next bio_clone_bioset() call will be made while holding a reference a bio (result of the first clone) from the same bioset. This can potentially exhaust the bioset mempool and result in a memory allocation deadlock. So the result of the bio_clone_bioset() must be attached to the new dm_io struct, and the original must be resubmitted. The current code is backwards. Note that there is no race caused by reassigning cio.io->bio after already calling __map_bio(). This bio will only be dereferenced again after dec_pending() has found io->io_count to be zero, and this cannot happen before the dec_pending() call at the end of __split_and_process_bio(). Reported-by: Mikulas Patocka Signed-off-by: NeilBrown --- Hi, I think this should resolve the problem Mikulas noticed that the bios form a deep chain instead of a wide tree. Thanks, NeilBrown drivers/md/dm.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 99ec215f7dcb..2e0e10a1c030 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -1482,12 +1482,19 @@ static void __split_and_process_bio(struct mapped_device *md, * Remainder must be passed to generic_make_request() * so that it gets handled *after* bios already submitted * have been completely processed. + * We take a clone of the original to store in + * ci.io->bio to be used by end_io_acct() and + * for dec_pending to use for completion handling. + * As this path is not used for REQ_OP_ZONE_REPORT, + * the usage of io->bio in dm_remap_zone_report() + * won't be affected by this reassignment. */ struct bio *b = bio_clone_bioset(bio, GFP_NOIO, md->queue->bio_split); - bio_advance(b, (bio_sectors(b) - ci.sector_count) << 9); + ci.io->bio = b; + bio_advance(bio, (bio_sectors(bio) - ci.sector_count) << 9); bio_chain(b, bio); - generic_make_request(b); + generic_make_request(bio); break; } }