Received: by 2002:a5d:9c59:0:0:0:0:0 with SMTP id 25csp2212276iof; Tue, 7 Jun 2022 23:21:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzoeY0xT9UcXegp/LzxUET1i8B2ItClr/r7xF2f1N01GawHzXxMIwvHCspBzxhttrJ3eP0C X-Received: by 2002:a05:6a00:ac3:b0:51b:9803:dc01 with SMTP id c3-20020a056a000ac300b0051b9803dc01mr33214193pfl.8.1654669312575; Tue, 07 Jun 2022 23:21:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1654669312; cv=none; d=google.com; s=arc-20160816; b=ddEFApo5xkhU0TiwqfJYoF4EbGmTl8glGZD4+lY9aQOnB01HK0tn6rP4bBCgaG5wvP GBIJyftADsElmbx3iiYxSZwrMp6UonKcPCYBfAXUPeW6KVv2gnZYEv5942asU+5esLss ONJGKnGuFyfRyW8GjroJvpx9+BgQvpvc/m1KL9YtHMuhDDSB9+yu1hkyvN6W25MLoI54 wAH2TUIzCCSGtrUpCsPdgDv90Jb2DL6k05PNd2s7SQQD5JmMNOmsBScl/6LC5Ht9a/kd uOvMhRTTNAoG7MBpyCwV9XK3nzJmooGj0j7vcfKcxmr6fdCziOsG6qnSnGiEqQ0wic0t 4FCg== 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=SnQ3+W/RLvf7GTEiTJJYezqHHzEBdcO/tKGjZ77MsDI=; b=YtUgAAOhMHnXux12Av8Z6axfc7xNJUFdbbw9En4lfU7sQhzhko62Za6Gnn7Qw5SKou CTRs0frIsv7QqJHYWl+H1GSbtqK1ha3VDO3vlpz1PrlqsYgHPtxLIahktJgcZG38F6d+ V0JZcnnoOhroMUZBVZTNdIMP0a6IwZpI17EcWTUO+/J3ZeOON9dIVyhcSpD/4/1BlTx5 REWNenCM2n5Tuo40K8YoBS22xmnY/vbITvxjnqy89yfL1P6S7yViV6+Yaih0irLOJDmP yJfeXFySavBEzYOkvBuR1W3oJd30zAgIoeLD7fZxBppPq9RW3q9o3ETn3vQSoCwNo7v+ VN6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=GzL9Sg1x; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 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. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id q9-20020a170902f78900b00168972d3f30si954826pln.245.2022.06.07.23.21.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Jun 2022 23:21:52 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=GzL9Sg1x; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:18 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 0A4F33CA2E5; Tue, 7 Jun 2022 22:42:31 -0700 (PDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443644AbiFHCDB (ORCPT + 99 others); Tue, 7 Jun 2022 22:03:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1843635AbiFHALQ (ORCPT ); Tue, 7 Jun 2022 20:11:16 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76699277F86; Tue, 7 Jun 2022 12:24:17 -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 ams.source.kernel.org (Postfix) with ESMTPS id 136EBB823CD; Tue, 7 Jun 2022 19:24:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6922DC385A5; Tue, 7 Jun 2022 19:24:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1654629854; bh=mjDVms1mkR0UEE6C7PmyTd3PILZR1jItKQPEJ9Yzcyo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GzL9Sg1xiQtZ2IAGgBtnDVAGHyJdhgz49NyMOp4dfJtZCbSmezcqc0BQ4N4QIEY8Y 8ud5GPbDG7BCOz4+0sDkZf9dnPGQJuxJwWVJSCmPUsUUPtaKj4OZL4jKC/Gng5/M1o TF7P9UIZcbhwrZo1ipsrb/0HIrCGty/Uxv4kOl60= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Coly Li , Jens Axboe Subject: [PATCH 5.18 840/879] bcache: improve multithreaded bch_sectors_dirty_init() Date: Tue, 7 Jun 2022 19:05:58 +0200 Message-Id: <20220607165027.234925594@linuxfoundation.org> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220607165002.659942637@linuxfoundation.org> References: <20220607165002.659942637@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=-3.1 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=unavailable 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: Coly Li commit 4dc34ae1b45fe26e772a44379f936c72623dd407 upstream. Commit b144e45fc576 ("bcache: make bch_sectors_dirty_init() to be multithreaded") makes bch_sectors_dirty_init() to be much faster when counting dirty sectors by iterating all dirty keys in the btree. But it isn't in ideal shape yet, still can be improved. This patch does the following changes to improve current parallel dirty keys iteration on the btree, - Add read lock to root node when multiple threads iterating the btree, to prevent the root node gets split by I/Os from other registered bcache devices. - Remove local variable "char name[32]" and generate kernel thread name string directly when calling kthread_run(). - Allocate "struct bch_dirty_init_state state" directly on stack and avoid the unnecessary dynamic memory allocation for it. - Decrease BCH_DIRTY_INIT_THRD_MAX from 64 to 12 which is enough indeed. - Increase &state->started to count created kernel thread after it succeeds to create. - When wait for all dirty key counting threads to finish, use wait_event() to replace wait_event_interruptible(). With the above changes, the code is more clear, and some potential error conditions are avoided. Fixes: b144e45fc576 ("bcache: make bch_sectors_dirty_init() to be multithreaded") Signed-off-by: Coly Li Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20220524102336.10684-3-colyli@suse.de Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- drivers/md/bcache/writeback.c | 60 ++++++++++++++++-------------------------- drivers/md/bcache/writeback.h | 2 - 2 files changed, 25 insertions(+), 37 deletions(-) --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -948,10 +948,10 @@ void bch_sectors_dirty_init(struct bcach struct btree_iter iter; struct sectors_dirty_init op; struct cache_set *c = d->c; - struct bch_dirty_init_state *state; - char name[32]; + struct bch_dirty_init_state state; /* Just count root keys if no leaf node */ + rw_lock(0, c->root, c->root->level); if (c->root->level == 0) { bch_btree_op_init(&op.op, -1); op.inode = d->id; @@ -961,54 +961,42 @@ void bch_sectors_dirty_init(struct bcach for_each_key_filter(&c->root->keys, k, &iter, bch_ptr_invalid) sectors_dirty_init_fn(&op.op, c->root, k); + rw_unlock(0, c->root); return; } - state = kzalloc(sizeof(struct bch_dirty_init_state), GFP_KERNEL); - if (!state) { - pr_warn("sectors dirty init failed: cannot allocate memory\n"); - return; - } + state.c = c; + state.d = d; + state.total_threads = bch_btre_dirty_init_thread_nr(); + state.key_idx = 0; + spin_lock_init(&state.idx_lock); + atomic_set(&state.started, 0); + atomic_set(&state.enough, 0); + init_waitqueue_head(&state.wait); - state->c = c; - state->d = d; - state->total_threads = bch_btre_dirty_init_thread_nr(); - state->key_idx = 0; - spin_lock_init(&state->idx_lock); - atomic_set(&state->started, 0); - atomic_set(&state->enough, 0); - init_waitqueue_head(&state->wait); - - for (i = 0; i < state->total_threads; i++) { - /* Fetch latest state->enough earlier */ + for (i = 0; i < state.total_threads; i++) { + /* Fetch latest state.enough earlier */ smp_mb__before_atomic(); - if (atomic_read(&state->enough)) + if (atomic_read(&state.enough)) break; - state->infos[i].state = state; - atomic_inc(&state->started); - snprintf(name, sizeof(name), "bch_dirty_init[%d]", i); - - state->infos[i].thread = - kthread_run(bch_dirty_init_thread, - &state->infos[i], - name); - if (IS_ERR(state->infos[i].thread)) { + state.infos[i].state = &state; + state.infos[i].thread = + kthread_run(bch_dirty_init_thread, &state.infos[i], + "bch_dirtcnt[%d]", i); + if (IS_ERR(state.infos[i].thread)) { pr_err("fails to run thread bch_dirty_init[%d]\n", i); for (--i; i >= 0; i--) - kthread_stop(state->infos[i].thread); + kthread_stop(state.infos[i].thread); goto out; } + atomic_inc(&state.started); } - /* - * Must wait for all threads to stop. - */ - wait_event_interruptible(state->wait, - atomic_read(&state->started) == 0); - out: - kfree(state); + /* Must wait for all threads to stop. */ + wait_event(state.wait, atomic_read(&state.started) == 0); + rw_unlock(0, c->root); } void bch_cached_dev_writeback_init(struct cached_dev *dc) --- a/drivers/md/bcache/writeback.h +++ b/drivers/md/bcache/writeback.h @@ -20,7 +20,7 @@ #define BCH_WRITEBACK_FRAGMENT_THRESHOLD_MID 57 #define BCH_WRITEBACK_FRAGMENT_THRESHOLD_HIGH 64 -#define BCH_DIRTY_INIT_THRD_MAX 64 +#define BCH_DIRTY_INIT_THRD_MAX 12 /* * 14 (16384ths) is chosen here as something that each backing device * should be a reasonable fraction of the share, and not to blow up