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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ECA3AC433EF for ; Fri, 8 Apr 2022 00:39:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233013AbiDHAlt (ORCPT ); Thu, 7 Apr 2022 20:41:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58964 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232174AbiDHAls (ORCPT ); Thu, 7 Apr 2022 20:41:48 -0400 Received: from mail-pg1-f178.google.com (mail-pg1-f178.google.com [209.85.215.178]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13002200 for ; Thu, 7 Apr 2022 17:39:47 -0700 (PDT) Received: by mail-pg1-f178.google.com with SMTP id 125so6374464pgc.11 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=fI5tUm7ynALpjJ8wDQj5vFRDAYLzHnU5gAS4asSzYXKeN+XyPXfKmi0RYelE/q26jB EkU4Y/N0mLVwh80d7bDmgjTPdfkCB6q55thNrgVNZYe/ubEKN9eBDHUZMwNGQgvhx5eu 0UG2Dy4QaAqaFvqlBjKnppf2blRCdWXSdMZY8MLQPQzEKTLpdzg5EKZ/N8L+Y9oncsp4 rqogK0z8jTcHm6dwUhecbFJ5wHUvhizjH0Di0Ru/hg4/RtTSYBIYiE9IUtobsAbiq1NW 5gXORgUybpWIntDpO3ArreFtf/aylajof6TO1Zla5t0WTgNSOkxTKU1XYhCk4z7iAUNA teCw== X-Gm-Message-State: AOAM5314Kfd+gpY0j07BgpnAtjaE3BxfP4rtVD+O0H34/hMQ/vouDQgB qJKKMt45d8OE28gffKsC9Ys= 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> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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) >