From patchwork Tue Aug 7 22:51:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 10559315 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B820313AC for ; Tue, 7 Aug 2018 22:51:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A70AB2A81F for ; Tue, 7 Aug 2018 22:51:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A59492A82A; Tue, 7 Aug 2018 22:51:44 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5F1652A820 for ; Tue, 7 Aug 2018 22:51:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726986AbeHHBIS (ORCPT ); Tue, 7 Aug 2018 21:08:18 -0400 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:58488 "EHLO esa5.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726895AbeHHBIS (ORCPT ); Tue, 7 Aug 2018 21:08:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1533682302; x=1565218302; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=pmZ00wa/pZP3BzJ4VsCpF4uV70NEkLO3ejyvegB6dn4=; b=IvrkmxIzFuRJeiAW/bDwSMg99guf6O9kNzsjidf0fM3odTL6wtUrdjlH q/PSKuFxESfY18fbnkaPJVDkb/BYf5nhjMfDIdqCEnJExfUhNKTVJHLcH RRXLtVfw8YBuwXZUlD6/YD6dcU3jUXlSPlwI9y0XCwyOKrApxZ+WDmx+A GFk7yA3UaBJTVJ7y8zoUWZqFKPbyePSs6jnWm0rCv66XWNm4Kp+8RTSC+ N8FKeTeJnFzqutCeBAiJS2PlnwfwAD/UCUn+BYsRMHYu6bj6Xk6DXsuti p1gedXbY0ZUeao03uRJ2xuve1J7l//+ijDH2AkbXCbsR+QRHpJF0wNZqu w==; X-IronPort-AV: E=Sophos;i="5.51,456,1526313600"; d="scan'208";a="87859745" Received: from h199-255-45-15.hgst.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 08 Aug 2018 06:51:35 +0800 Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep02.wdc.com with ESMTP; 07 Aug 2018 15:39:13 -0700 Received: from thinkpad-bart.sdcorp.global.sandisk.com ([10.111.67.248]) by uls-op-cesaip01.wdc.com with ESMTP; 07 Aug 2018 15:51:35 -0700 From: Bart Van Assche To: Jens Axboe Cc: linux-block@vger.kernel.org, Christoph Hellwig , Bart Van Assche , Tejun Heo , Ming Lei , Jianchao Wang , Hannes Reinecke , Johannes Thumshirn , Alan Stern Subject: [PATCH v5 4/9] percpu-refcount: Introduce percpu_ref_is_in_use() Date: Tue, 7 Aug 2018 15:51:28 -0700 Message-Id: <20180807225133.27221-5-bart.vanassche@wdc.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180807225133.27221-1-bart.vanassche@wdc.com> References: <20180807225133.27221-1-bart.vanassche@wdc.com> Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Introduce a function that allows to determine whether a per-cpu refcount is in use. This function will be used in a later patch to determine whether or not any block layer requests are being executed. Signed-off-by: Bart Van Assche Cc: Tejun Heo Cc: Christoph Hellwig Cc: Ming Lei Cc: Jianchao Wang Cc: Hannes Reinecke Cc: Johannes Thumshirn Cc: Alan Stern --- include/linux/percpu-refcount.h | 2 ++ lib/percpu-refcount.c | 40 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/include/linux/percpu-refcount.h b/include/linux/percpu-refcount.h index 009cdf3d65b6..dd247756d634 100644 --- a/include/linux/percpu-refcount.h +++ b/include/linux/percpu-refcount.h @@ -331,4 +331,6 @@ static inline bool percpu_ref_is_zero(struct percpu_ref *ref) return !atomic_long_read(&ref->count); } +bool percpu_ref_is_in_use(struct percpu_ref *ref); + #endif diff --git a/lib/percpu-refcount.c b/lib/percpu-refcount.c index 9f96fa7bc000..1dcb47e2c561 100644 --- a/lib/percpu-refcount.c +++ b/lib/percpu-refcount.c @@ -369,3 +369,43 @@ void percpu_ref_reinit(struct percpu_ref *ref) spin_unlock_irqrestore(&percpu_ref_switch_lock, flags); } EXPORT_SYMBOL_GPL(percpu_ref_reinit); + +/** + * percpu_ref_is_in_use - verify whether or not a percpu refcount is in use + * @ref: percpu_ref to test + * + * For a percpu refcount that is in percpu-mode, verify whether the reference + * count is above one. For a percpu refcount that is in atomic mode, verify + * whether the reference count is above zero. This function allows to verify + * whether any references are held on a percpu refcount that is switched + * between atomic and percpu mode with percpu_ref_reinit() / + * percpu_ref_kill(). + * + * This function is safe to call as long as @ref is between init and exit. It + * is the responsibility of the caller to handle percpu_ref_get() and + * percpu_ref_put() calls that occur concurrently with this function. + */ +bool percpu_ref_is_in_use(struct percpu_ref *ref) +{ + unsigned long __percpu *percpu_count; + unsigned long sum = 0; + int cpu; + unsigned long flags; + + /* Obtain percpu_ref_switch_lock to serialize against mode switches. */ + spin_lock_irqsave(&percpu_ref_switch_lock, flags); + rcu_read_lock_sched(); + if (__ref_is_percpu(ref, &percpu_count)) { + for_each_possible_cpu(cpu) + sum += *per_cpu_ptr(percpu_count, cpu); + } + rcu_read_unlock_sched(); + sum += atomic_long_read(&ref->count); + sum &= ~PERCPU_COUNT_BIAS; + sum += (ref->percpu_count_ptr & __PERCPU_REF_DEAD); + spin_unlock_irqrestore(&percpu_ref_switch_lock, flags); + + WARN_ON_ONCE(sum == 0); + return sum > 1; +} +EXPORT_SYMBOL_GPL(percpu_ref_is_in_use);