From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C21AC433F5 for ; Fri, 8 Apr 2022 00:39:49 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 606A96B0071; Thu, 7 Apr 2022 20:39:48 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 5B5E36B0073; Thu, 7 Apr 2022 20:39:48 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 47DCB6B0074; Thu, 7 Apr 2022 20:39:48 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (relay.hostedemail.com [64.99.140.27]) by kanga.kvack.org (Postfix) with ESMTP id 39E766B0071 for ; Thu, 7 Apr 2022 20:39:48 -0400 (EDT) Received: from smtpin08.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay11.hostedemail.com (Postfix) with ESMTP id 08DE880416 for ; Fri, 8 Apr 2022 00:39:48 +0000 (UTC) X-FDA: 79331854056.08.6E502F9 Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) by imf02.hostedemail.com (Postfix) with ESMTP id 85C2580007 for ; Fri, 8 Apr 2022 00:39:47 +0000 (UTC) Received: by mail-pg1-f179.google.com with SMTP id s137so3673774pgs.5 for ; Thu, 07 Apr 2022 17:39:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=0Xk1+fs4EReZHznvydunkPsq1TyAFPHWXf8m9Tth19E=; b=v1lCl6bbfpn3HzcEm/VqUqvyxWmHSiEGC+EkZddURMBs5Arex8zJejEwTHp4+JbrSM SFVGhuLOijzYED5nI0KDuoCBEknqLiAAhDGQF6c2qzl+IaQokfoVOyroEKKDfDNuscQY XQPmdjKhsqphLdrbZdfhmM/VyxmtkObnp/GEpCSkdAt7pK+KTex6+UIJnAyYNKnGeFnN HCY03WvFSec8WNR2MK6Gy/+2LmCbAYu0q4APmv9FHbNXCju3WgE8UumhgRYA2Eb0Y435 8G+7oTf9Paz30CIKNWaiOushKFqJ19bh7yld3nnf/256XSEEy9EkDXAumEs26M0o+WnL nJ1A== X-Gm-Message-State: AOAM530r9vYL2yrSgM4tFUpN3SkowUbU/alhwxCrQyJSxQOVkxT51vvG 7COCGo9DzlwUgio4UgZyaNwspuI99xhSRtlL X-Google-Smtp-Source: ABdhPJztJZ7L+/5PHv3zgM7cX3sQyQR4/FykBiwQshDvB8dL1MiwJOzEg2s1fSMTGpxDxXJwpGGhvg== X-Received: by 2002:a05:6a00:3018:b0:4fa:d533:45e5 with SMTP id ay24-20020a056a00301800b004fad53345e5mr16703828pfb.13.1649378386475; Thu, 07 Apr 2022 17:39:46 -0700 (PDT) Received: from fedora (136-24-99-118.cab.webpass.net. [136.24.99.118]) by smtp.gmail.com with ESMTPSA id k11-20020a056a00168b00b004f7e1555538sm23597254pfc.190.2022.04.07.17.39.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Apr 2022 17:39:46 -0700 (PDT) Date: Thu, 7 Apr 2022 17:39:43 -0700 From: Dennis Zhou To: Andrew Morton Cc: Qi Zheng , tj@kernel.org, cl@linux.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org, zhouchengming@bytedance.com, songmuchun@bytedance.com, Ming Lei Subject: Re: [PATCH] percpu_ref: call wake_up_all() after percpu_ref_put() completes Message-ID: References: <20220407103335.36885-1-zhengqi.arch@bytedance.com> <20220407155752.769632b737f79b038cf83742@linux-foundation.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20220407155752.769632b737f79b038cf83742@linux-foundation.org> X-Stat-Signature: 1d5fzhd16f1odfraqmwtig8oppzccjzj Authentication-Results: imf02.hostedemail.com; dkim=none; spf=pass (imf02.hostedemail.com: domain of dennisszhou@gmail.com designates 209.85.215.179 as permitted sender) smtp.mailfrom=dennisszhou@gmail.com; dmarc=fail reason="SPF not aligned (relaxed), No valid DKIM" header.from=kernel.org (policy=none) X-Rspam-User: X-Rspamd-Server: rspam08 X-Rspamd-Queue-Id: 85C2580007 X-HE-Tag: 1649378387-926905 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Hello, On Thu, Apr 07, 2022 at 03:57:52PM -0700, Andrew Morton wrote: > (cc Ming Lei) > > On Thu, 7 Apr 2022 18:33:35 +0800 Qi Zheng wrote: > > > In the percpu_ref_call_confirm_rcu(), we call the wake_up_all() > > before calling percpu_ref_put(), which will cause the value of > > percpu_ref to be unstable when percpu_ref_switch_to_atomic_sync() > > returns. > > > > CPU0 CPU1 > > > > percpu_ref_switch_to_atomic_sync(&ref) > > --> percpu_ref_switch_to_atomic(&ref) > > --> percpu_ref_get(ref); /* put after confirmation */ > > call_rcu(&ref->data->rcu, percpu_ref_switch_to_atomic_rcu); > > > > percpu_ref_switch_to_atomic_rcu > > --> percpu_ref_call_confirm_rcu > > --> data->confirm_switch = NULL; > > wake_up_all(&percpu_ref_switch_waitq); > > > > /* here waiting to wake up */ > > wait_event(percpu_ref_switch_waitq, !ref->data->confirm_switch); > > (A)percpu_ref_put(ref); > > /* The value of &ref is unstable! */ > > percpu_ref_is_zero(&ref) > > (B)percpu_ref_put(ref); > > > > As shown above, assuming that the counts on each cpu add up to 0 before > > calling percpu_ref_switch_to_atomic_sync(), we expect that after switching > > to atomic mode, percpu_ref_is_zero() can return true. But actually it will > > return different values in the two cases of A and B, which is not what > > we expected. > > > > Maybe the original purpose of percpu_ref_switch_to_atomic_sync() is > > just to ensure that the conversion to atomic mode is completed, but it > > should not return with an extra reference count. > > > > Calling wake_up_all() after percpu_ref_put() ensures that the value of > > percpu_ref is stable after percpu_ref_switch_to_atomic_sync() returns. > > So just do it. > > Thanks. I'll grab this, but shall await input from others before doing > anything else with it. > Seems right to me. The percpu_ref protects the __percpu_ref_exit(), not the waiters. Acked-by: Dennis Zhou Thanks, Dennis > > Signed-off-by: Qi Zheng > > +++ b/lib/percpu-refcount.c > > @@ -154,13 +154,14 @@ static void percpu_ref_call_confirm_rcu(struct rcu_head *rcu) > > > > data->confirm_switch(ref); > > data->confirm_switch = NULL; > > - wake_up_all(&percpu_ref_switch_waitq); > > > > if (!data->allow_reinit) > > __percpu_ref_exit(ref); > > > > /* drop ref from percpu_ref_switch_to_atomic() */ > > percpu_ref_put(ref); > > + > > + wake_up_all(&percpu_ref_switch_waitq); > > } > > > > static void percpu_ref_switch_to_atomic_rcu(struct rcu_head *rcu) >