Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp587299pxb; Tue, 5 Apr 2022 15:03:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyNNZIytAenj4qZKiSdYsZvnxrZoQg7AQO+lHD7ezjJn2xHGNVtiXXtxQJXPol+iE/x8V74 X-Received: by 2002:a17:90a:b10c:b0:1ca:ba2d:d67d with SMTP id z12-20020a17090ab10c00b001caba2dd67dmr6439796pjq.127.1649196216381; Tue, 05 Apr 2022 15:03:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649196216; cv=none; d=google.com; s=arc-20160816; b=f4OAetgQgCs5PVpapgI8A8jh4HrKO+s2Aw33M0s44FyfvFw3cIKnZozaIAZ64+qaJE /J536uss4QZcP0WQwORtKHP4KKArShUjD/+0/4D0K45bqs9GHPIw81zSj0nJgsC6xfkS jRZoaSiIABaGzmA4G7eoBa31H66uFiS/Vhle69TrpbtgwJWrk+37KVzbbPkQUI4N81X/ QR5VFSwY4WF9wuXXnITRyi1bcxZQaFJBGlZ0HzKj8Ij00+sATXSa4JzIDXL9R0Q01KZU DNMVK6BOI8Xjevi2KSEYHxVJVmRMP+LP8RbdS/XZJJaqz4fsh5tJYMhUA1AmdvH9tzVt DBmQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=cnVlwnR2KkDHOAjDMHHoCVgnYgSL3fHLX/BJV9Vxx+w=; b=Yw+IaVrklUVXzxPzawghB6jc6O/TNKfqhhMWBFnyj2L+a9z93aQmP2MtO94c7wbidF qxW/Yl+8z3IpdSK3tqNCNZG0gWJf0k9ics67wpIZLs83AvSokXgrdCBXztULafB4YDii AxJqTzBrJim5DP3FvI4E+9J8DUkB1aGTeZVJebeoidwYGccCqH7rbkuAdrDdHttzepLr 5MBt5uhVmxrp5+APNs6joLgL0rqeguyOMiNz+BTsLI6TbsEyqyj2NzTtqqqy81AcQJKu IA+j7SaUIUfiNH3LAbNxcNMO8dUvwWRv9p6FMttEEBNTz1YWhw/etDhow9WvXWxPHYJi zXPA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=vdCwa4WH; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [23.128.96.19]) by mx.google.com with ESMTPS id a14-20020a170902ecce00b00153b2d16504si14753036plh.268.2022.04.05.15.03.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Apr 2022 15:03:36 -0700 (PDT) Received-SPF: softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) client-ip=23.128.96.19; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=vdCwa4WH; spf=softfail (google.com: domain of transitioning linux-kernel-owner@vger.kernel.org does not designate 23.128.96.19 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 6606F483B9; Tue, 5 Apr 2022 14:46:22 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242904AbiDEOVL (ORCPT + 99 others); Tue, 5 Apr 2022 10:21:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40698 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240078AbiDEJeB (ORCPT ); Tue, 5 Apr 2022 05:34:01 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2E2527B32; Tue, 5 Apr 2022 02:23:28 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6BD9C61645; Tue, 5 Apr 2022 09:23:28 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7D990C385A0; Tue, 5 Apr 2022 09:23:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1649150607; bh=GSyj3xxP9PHs0hr0AIMx9kLbS7m90QYmAvEN2o1MDIM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=vdCwa4WHVuOMBeYFve15Gp7ScmGD5RVSgppnAcHv9lHa2HJei0hINYBQIu6Go6DjX cxLMLjYQf1VsnWSHXjJJfH3kHJZYNaMHopVuLU+ZF6ivcmmOX03mbHC6DaOcMfmPfA ssosXMzWN9HRlhAQQ1XpOVKlBtV60YyMdgeu28JM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mikulas Patocka , Mike Snitzer Subject: [PATCH 5.15 114/913] dm: interlock pending dm_io and dm_wait_for_bios_completion Date: Tue, 5 Apr 2022 09:19:36 +0200 Message-Id: <20220405070343.243951982@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220405070339.801210740@linuxfoundation.org> References: <20220405070339.801210740@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Mike Snitzer commit 9f6dc633761006f974701d4c88da71ab68670749 upstream. Commit d208b89401e0 ("dm: fix mempool NULL pointer race when completing IO") didn't go far enough. When bio_end_io_acct ends the count of in-flight I/Os may reach zero and the DM device may be suspended. There is a possibility that the suspend races with dm_stats_account_io. Fix this by adding percpu "pending_io" counters to track outstanding dm_io. Move kicking of suspend queue to dm_io_dec_pending(). Also, rename md_in_flight_bios() to dm_in_flight_bios() and update it to iterate all pending_io counters. Fixes: d208b89401e0 ("dm: fix mempool NULL pointer race when completing IO") Cc: stable@vger.kernel.org Co-developed-by: Mikulas Patocka Signed-off-by: Mikulas Patocka Signed-off-by: Mike Snitzer Signed-off-by: Greg Kroah-Hartman --- drivers/md/dm-core.h | 2 ++ drivers/md/dm.c | 35 +++++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 12 deletions(-) --- a/drivers/md/dm-core.h +++ b/drivers/md/dm-core.h @@ -65,6 +65,8 @@ struct mapped_device { struct gendisk *disk; struct dax_device *dax_dev; + unsigned long __percpu *pending_io; + /* * A list of ios that arrived while we were suspended. */ --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -507,10 +507,6 @@ static void end_io_acct(struct mapped_de dm_stats_account_io(&md->stats, bio_data_dir(bio), bio->bi_iter.bi_sector, bio_sectors(bio), true, duration, stats_aux); - - /* nudge anyone waiting on suspend queue */ - if (unlikely(wq_has_sleeper(&md->wait))) - wake_up(&md->wait); } static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio) @@ -531,6 +527,7 @@ static struct dm_io *alloc_io(struct map io->magic = DM_IO_MAGIC; io->status = 0; atomic_set(&io->io_count, 1); + this_cpu_inc(*md->pending_io); io->orig_bio = bio; io->md = md; spin_lock_init(&io->endio_lock); @@ -828,6 +825,12 @@ void dm_io_dec_pending(struct dm_io *io, stats_aux = io->stats_aux; free_io(md, io); end_io_acct(md, bio, start_time, &stats_aux); + smp_wmb(); + this_cpu_dec(*md->pending_io); + + /* nudge anyone waiting on suspend queue */ + if (unlikely(wq_has_sleeper(&md->wait))) + wake_up(&md->wait); if (io_error == BLK_STS_DM_REQUEUE) return; @@ -1697,6 +1700,11 @@ static void cleanup_mapped_device(struct blk_cleanup_disk(md->disk); } + if (md->pending_io) { + free_percpu(md->pending_io); + md->pending_io = NULL; + } + cleanup_srcu_struct(&md->io_barrier); mutex_destroy(&md->suspend_lock); @@ -1794,6 +1802,10 @@ static struct mapped_device *alloc_dev(i if (!md->wq) goto bad; + md->pending_io = alloc_percpu(unsigned long); + if (!md->pending_io) + goto bad; + dm_stats_init(&md->stats); /* Populate the mapping, nobody knows we exist yet */ @@ -2209,16 +2221,13 @@ void dm_put(struct mapped_device *md) } EXPORT_SYMBOL_GPL(dm_put); -static bool md_in_flight_bios(struct mapped_device *md) +static bool dm_in_flight_bios(struct mapped_device *md) { int cpu; - struct block_device *part = dm_disk(md)->part0; - long sum = 0; + unsigned long sum = 0; - for_each_possible_cpu(cpu) { - sum += part_stat_local_read_cpu(part, in_flight[0], cpu); - sum += part_stat_local_read_cpu(part, in_flight[1], cpu); - } + for_each_possible_cpu(cpu) + sum += *per_cpu_ptr(md->pending_io, cpu); return sum != 0; } @@ -2231,7 +2240,7 @@ static int dm_wait_for_bios_completion(s while (true) { prepare_to_wait(&md->wait, &wait, task_state); - if (!md_in_flight_bios(md)) + if (!dm_in_flight_bios(md)) break; if (signal_pending_state(task_state, current)) { @@ -2243,6 +2252,8 @@ static int dm_wait_for_bios_completion(s } finish_wait(&md->wait, &wait); + smp_rmb(); + return r; }