Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp114224rwb; Mon, 28 Nov 2022 17:50:48 -0800 (PST) X-Google-Smtp-Source: AA0mqf6HyCY2mKJN2nRnEafpLQe9N4v2kmOsyYias6loH3BFlq9IfQ8SPTYZJgqpfk0bu/8DWQ5W X-Received: by 2002:a17:906:30c1:b0:7b7:eaa9:c1cb with SMTP id b1-20020a17090630c100b007b7eaa9c1cbmr31419137ejb.745.1669686648100; Mon, 28 Nov 2022 17:50:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1669686648; cv=none; d=google.com; s=arc-20160816; b=FWjpiXeLSIb01RpA7GVeZFNHX+7v7zE84mnz87VxXF0FIRtgtHE82EyAnZZobpzLNt eKaKSGPeiHLX6JF39llKepc9OPAB7GNnuTmG0I/mlfwxziyyhN4CFTwav10MtB1CGk1G /DRZvQZtU/+eqNZ9dCm6KnxtwXfc+WM3kOJJSzly6TShCB/kCMNzA9xzyu88kE2gpB4G NseuSIYs0Zy4nG7bw6Ask56ISATEX9Bm6FyWw4G6hZmd9uB/+WyEYlVJF8Zn2VfXolT4 NmUbOmXO6fgD8tEg4h3laC7sp51pv0GwdaN5x0wQYMXMnOYPqOvZ2XANOBmUGeRt9H3B tqFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:reply-to:message-id:subject:cc:to:from:date :dkim-signature; bh=BqTLOpC+5X9Er8Qe0yyHxunshdkbRQJuOaRT03UxhfY=; b=JTrm2RLfJcOTKE01eBqm8OTMKQ32OK7Pkc/azilU8QN0hRZYA1eLqdaJW3sItOYCFF JiFB19dKM4zUK87AhCxoYLPKStCESD7N6eGICGkUpy0bOovuz4ZLvPR4V0DT+wf0D7RR 6sSvk4KTdKjKeRSslioQlSDTMZjpyDnb+TjWgh9zAhMyLHlQ5My8ulVHU+uIV2+RdeHR yXq4h0GEvRtyixhz2ud64UJ2pqLPGK/yCmmneI5xMkpNpVb0acWarpO9c22/n+cJZ65o PBmsi++Uq7hgGbRiAfg57y6zD2GNMrhfkEES0no4BXMdIdvHk5sL/Gnpqjov8R15iMZa YTbw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=lunUszSq; 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=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z13-20020a056402274d00b00469a09a7ccfsi12882031edd.11.2022.11.28.17.50.26; Mon, 28 Nov 2022 17:50:48 -0800 (PST) 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=@kernel.org header.s=k20201202 header.b=lunUszSq; 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=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234672AbiK2BDQ (ORCPT + 83 others); Mon, 28 Nov 2022 20:03:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39684 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234681AbiK2BDO (ORCPT ); Mon, 28 Nov 2022 20:03:14 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A433C27CD5; Mon, 28 Nov 2022 17:03:13 -0800 (PST) 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 41C0561195; Tue, 29 Nov 2022 01:03:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9F741C433B5; Tue, 29 Nov 2022 01:03:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1669683792; bh=PPaCKThtXBv4RuxYsoVEKUj7Mw6K2389pRooeVtWdsc=; h=Date:From:To:Cc:Subject:Reply-To:References:In-Reply-To:From; b=lunUszSqnNwu7uaSOvLmx2XPdnMiyw4hyRcfdmIM/QVZpQg2Ht7DHDVPgyStrEMvo k8jRYpt4L3TDflGbbCu6R778zzBYwBDmH/fgJOAxEBbvJyoLd60KQ/0/QYQWIvjtXN o09TtLiHONmflp3oCYI4kIDYTcEAczOHLP/LmHMBFK2TJByVFhmGJJJck4UZ0KE7eX XeaYjk54mQS7+SVXG+c4U/3G7vo8aTZ+hVp1JxQY5lzsM9jIzTKUjadC15AMIAFQeA xXwwJv0DpmdKD2HGsNyd+zaqiPd/tusOKRQLOQrSL0Ghs0MTDK/1+u3qhZGZ7eeFrI ld+/FwkiM/YyQ== Received: by paulmck-ThinkPad-P17-Gen-1.home (Postfix, from userid 1000) id 4828D5C0EBE; Mon, 28 Nov 2022 17:03:12 -0800 (PST) Date: Mon, 28 Nov 2022 17:03:12 -0800 From: "Paul E. McKenney" To: Zqiang Cc: frederic@kernel.org, quic_neeraju@quicinc.com, joel@joelfernandes.org, rcu@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH v2] rcu-tasks: Make rude RCU-Tasks work well with CPU hotplug Message-ID: <20221129010312.GS4001@paulmck-ThinkPad-P17-Gen-1> Reply-To: paulmck@kernel.org References: <20221128143428.1703744-1-qiang1.zhang@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20221128143428.1703744-1-qiang1.zhang@intel.com> 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 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 On Mon, Nov 28, 2022 at 10:34:28PM +0800, Zqiang wrote: > Currently, invoke rcu_tasks_rude_wait_gp() to wait one rude > RCU-tasks grace period, if __num_online_cpus == 1, will return > directly, indicates the end of the rude RCU-task grace period. > suppose the system has two cpus, consider the following scenario: > > CPU0 CPU1 (going offline) > migration/1 task: > cpu_stopper_thread > -> take_cpu_down > -> _cpu_disable > (dec __num_online_cpus) > ->cpuhp_invoke_callback > preempt_disable > access old_data0 > task1 > del old_data0 ..... > synchronize_rcu_tasks_rude() > task1 schedule out > .... > task2 schedule in > rcu_tasks_rude_wait_gp() > ->__num_online_cpus == 1 > ->return > .... > task1 schedule in > ->free old_data0 > preempt_enable > > when CPU1 dec __num_online_cpus and __num_online_cpus is equal one, > the CPU1 has not finished offline, stop_machine task(migration/1) > still running on CPU1, maybe still accessing 'old_data0', but the > 'old_data0' has freed on CPU0. > > This commit add cpus_read_lock/unlock() protection before accessing > __num_online_cpus variables, to ensure that the CPU in the offline > process has been completed offline. > > Signed-off-by: Zqiang First, good eyes and good catch!!! The purpose of that check for num_online_cpus() is not performance on single-CPU systems, but rather correct operation during early boot. So a simpler way to make that work is to check for RCU_SCHEDULER_RUNNING, for example, as follows: if (rcu_scheduler_active != RCU_SCHEDULER_RUNNING && num_online_cpus() <= 1) return; // Early boot fastpath for only one CPU. This works because rcu_scheduler_active is set to RCU_SCHEDULER_RUNNING long before it is possible to offline CPUs. Yes, schedule_on_each_cpu() does do cpus_read_lock(), again, good eyes, and it also unnecessarily does the schedule_work_on() the current CPU, but the code calling synchronize_rcu_tasks_rude() is on high-overhead code paths, so this overhead is down in the noise. Until further notice, anyway. So simplicity is much more important than performance in this code. So just adding the check for RCU_SCHEDULER_RUNNING should fix this, unless I am missing something (always possible!). Thanx, Paul > --- > kernel/rcu/tasks.h | 20 ++++++++++++++++++-- > 1 file changed, 18 insertions(+), 2 deletions(-) > > diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h > index 4a991311be9b..08e72c6462d8 100644 > --- a/kernel/rcu/tasks.h > +++ b/kernel/rcu/tasks.h > @@ -1033,14 +1033,30 @@ static void rcu_tasks_be_rude(struct work_struct *work) > { > } > > +static DEFINE_PER_CPU(struct work_struct, rude_work); > + > // Wait for one rude RCU-tasks grace period. > static void rcu_tasks_rude_wait_gp(struct rcu_tasks *rtp) > { > + int cpu; > + struct work_struct *work; > + > + cpus_read_lock(); > if (num_online_cpus() <= 1) > - return; // Fastpath for only one CPU. > + goto end;// Fastpath for only one CPU. > > rtp->n_ipis += cpumask_weight(cpu_online_mask); > - schedule_on_each_cpu(rcu_tasks_be_rude); > + for_each_online_cpu(cpu) { > + work = per_cpu_ptr(&rude_work, cpu); > + INIT_WORK(work, rcu_tasks_be_rude); > + schedule_work_on(cpu, work); > + } > + > + for_each_online_cpu(cpu) > + flush_work(per_cpu_ptr(&rude_work, cpu)); > + > +end: > + cpus_read_unlock(); > } > > void call_rcu_tasks_rude(struct rcu_head *rhp, rcu_callback_t func); > -- > 2.25.1 >