Received: by 2002:a05:6a10:2726:0:0:0:0 with SMTP id ib38csp681542pxb; Tue, 5 Apr 2022 18:33:56 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyQzuZar7KJm8MxkGvCMhEPc1EMzdc5dprqwWeuSkYk150ldV7KkkrOThZtk7BxWusCbwZ+ X-Received: by 2002:a17:90a:a78d:b0:1bc:d11c:ad40 with SMTP id f13-20020a17090aa78d00b001bcd11cad40mr7157266pjq.246.1649208836790; Tue, 05 Apr 2022 18:33:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1649208836; cv=none; d=google.com; s=arc-20160816; b=CPXWWBeIbAu/tIO0tKITYvzSN7L0EpCrTAwhfgTSAh8gAYGFTCRwb8wMmTmZNlbCfI l/0HqH9QEZWNPA9ujPzcXnd5eFE1NQahJqBmOOtB8NGcGdqz4WBGMC9G8/e1Xvfsd7BH 1sUJg3Z47qHq8Vsytwi26OOtAZVVIY6kgxYpOeaNg7jHIMD6WjZVmqVonH/BJV3q7+Q5 YXi1yaUYjq/3ap5kf7ey/MXkMXbdljAQCt7H5VB2Z22Ym6FzM/XH0Uh65RbdNOL9J3Z1 qPnOOCHJ0JZfrZBeMrln4KxEGOhnk9007bcM/E9WsIV1ue31YTI58mQvDwTkWRjlGExI ToFw== 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=cT9h3+hHHYNB3KSBFdIDUiRAa4PagDNq52XhskmD3Vg=; b=rgRXmR/jF//AbDleY6xNZBJHpuMbiKE+2O0NE85iaHjDGrJtN5JFHbSmCt7YDtV5HL U/XreTdRALprHyLk+/OYjhGToXKV0aqNsbT79YyEzTyrrJ6lblhFlHYmKq73eiCwtKeA WhA+hAhD+gB0xneDp63MVwiJp1pVuwEWvwYKS/KOQLcWDr5+9yspzpjmqsnFHCycsIBZ 429hGh2J+RPOLxg6Pqq2iZ0MF3JHrsIUTQM3igLcbD/ODDhWaBFE3jRlR0FiNtINB7nG FI+tIpdh33jRF7CJQzpJxVhQa/ied5LIwmpcdnmacOEXtoPqtwMliCezGaBUcNch6Quk J+MA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Qk5YAqJp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 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 out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id nm2-20020a17090b19c200b001ca6bd88c6asi3498257pjb.63.2022.04.05.18.33.42; Tue, 05 Apr 2022 18:33:56 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Qk5YAqJp; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233153AbiDEH44 (ORCPT + 99 others); Tue, 5 Apr 2022 03:56:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47088 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233271AbiDEHrl (ORCPT ); Tue, 5 Apr 2022 03:47:41 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E698BB7C4; Tue, 5 Apr 2022 00:43:47 -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 D1735616BF; Tue, 5 Apr 2022 07:43:46 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D9725C340EE; Tue, 5 Apr 2022 07:43:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1649144626; bh=PwoYvdv/B8jGc1fJpLaxWKJ5aWs33AsXDs0Dcffi23s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Qk5YAqJpDu78BULHfc7PtXUqhZITz+cU1uKCwrTsJzswhio/nPrj6Lzfh9GvwjxjO 4ygTaKIGRXPn3uthXDaQcQG9n+hEW8LKL0kpdO5R2NO9AJKe6mQ3i/LQDsuhKqRxku rC9xTSuXfQSQ9UUI+90FDZPHO6UT569usRCcIn78= 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.17 0113/1126] dm: interlock pending dm_io and dm_wait_for_bios_completion Date: Tue, 5 Apr 2022 09:14:20 +0200 Message-Id: <20220405070410.887516282@linuxfoundation.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220405070407.513532867@linuxfoundation.org> References: <20220405070407.513532867@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=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham 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; @@ -1622,6 +1625,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); @@ -1723,6 +1731,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 */ @@ -2130,16 +2142,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; } @@ -2152,7 +2161,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)) { @@ -2164,6 +2173,8 @@ static int dm_wait_for_bios_completion(s } finish_wait(&md->wait, &wait); + smp_rmb(); + return r; }