Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp9721762imu; Wed, 5 Dec 2018 09:12:16 -0800 (PST) X-Google-Smtp-Source: AFSGD/VTlu8d04mqJNIyInAT59muvKlLokceLpvt+XTeGxO/aoNlp3XY+H+uXvbG9LfxxPzvtpZc X-Received: by 2002:a62:442:: with SMTP id 63mr24702953pfe.156.1544029936400; Wed, 05 Dec 2018 09:12:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544029936; cv=none; d=google.com; s=arc-20160816; b=f89MAgc2ghEUDgf48m/X77Rjp63lSm52m1p3/WOxVdD4NTQwCbMdub9DzQTxs2dXg/ mrfPyRDAPFye5x247BrcMa52nD978g1UjO6w5A5Uf/30UlrTDGDkcXb9N2/HgHxJeF3T 7COoWCyodIlJ7DQM4Gl1Gq3+yEFehXc6aR51w32eD+UJseza46jL1BPll1FYgeixaePQ 9TjdhOh6HTbMlPfhml1Zt86s7XyMbnfCA0iOaZEGn7cZbtqZqD1MIaOsz39M0iG0H8FL GIl0Q7GAYlLblCC8utVcQyE9GJqeBgz3s+40QmZE1n6ntlc7nr+zdRjOm4cL8wZ1QS3a kkwQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=fDCGHmkmdcQMNToNCcLmdM57oBgf+GDSG1Fr69xhCfY=; b=mtH5Hvrev6y+hG9tmmXGK3LpHVlOa+tv7u3EGdNLhpLMHPxZ7LHz9/PTw7Kro1qZz9 bNojCVJLnpbUJcnsysNzR9/ei8PfCQ88yHvg80uI+RtTcApFdoFOrtPgb0IO8v6rf+fn IgHt54cLLCy6fCeU0gzRGiL9suBm5uFHckc4W8nLC1H7/2o3iNIiVY5f99OUX6q5ze5G YSq8QnICdT1c/KS4DIarVI1M5LNd+tsn32i3oFktwWApzLT5vBl/A2z26DP+7C5AcclI kOuwHM+LirKFblpqyOJL1XFhjLATfG8D/QXOELr7YLprPMy8AkDHthaN41f9lwGYvEs4 oogw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i69si19049504pgc.538.2018.12.05.09.12.00; Wed, 05 Dec 2018 09:12:16 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728439AbeLERLC (ORCPT + 99 others); Wed, 5 Dec 2018 12:11:02 -0500 Received: from mail-qt1-f196.google.com ([209.85.160.196]:39463 "EHLO mail-qt1-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728234AbeLERLB (ORCPT ); Wed, 5 Dec 2018 12:11:01 -0500 Received: by mail-qt1-f196.google.com with SMTP id n21so23087352qtl.6; Wed, 05 Dec 2018 09:11:00 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=fDCGHmkmdcQMNToNCcLmdM57oBgf+GDSG1Fr69xhCfY=; b=deF0uXl1OxzdrsHNeDXY748FR2z6EW6loLk4NOd86dEvQ4Ah/X0/ukTGG0V+mrtf6m BKzFSYWb99qEWsD8C5X4zWa6foK2LoDkeFTABzJctuHz3V03xQOtRz9N5P80UxISdjbn dmo31XCFsntnk0haZE46VKwLJSHRIOKxIJKUgIYH4b5WTI0hBAHNLqxUK+ldR7rOcreH BD757vntb7tnLnzXSN/YmNdmQebIfYVhziyEA2GrfX3oFEYFf1wvc7jTmP6x3J6vt2B9 4QK0MqsTWXrdZpbG3myM9sNFSyTqcP0jyZNKB0nYpqmMd6OHff43HbU1FB1JsHIVmwxq L/NQ== X-Gm-Message-State: AA+aEWZhNBgyJbRc9aTaUXSNvoUYgr4lmncojaATJCdl8zbwAvs1ww9w WC6kMXEYjbsTxlZV7ndFHqw= X-Received: by 2002:aed:3622:: with SMTP id e31mr24189909qtb.5.1544029859860; Wed, 05 Dec 2018 09:10:59 -0800 (PST) Received: from dennisz-mbp.thefacebook.com ([199.201.65.135]) by smtp.gmail.com with ESMTPSA id q15sm12098751qkl.81.2018.12.05.09.10.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 05 Dec 2018 09:10:59 -0800 (PST) From: Dennis Zhou To: Jens Axboe , Tejun Heo , Johannes Weiner , Josef Bacik Cc: kernel-team@fb.com, linux-block@vger.kernel.org, cgroups@vger.kernel.org, linux-kernel@vger.kernel.org, Dennis Zhou Subject: [PATCH 13/14] blkcg: change blkg reference counting to use percpu_ref Date: Wed, 5 Dec 2018 12:10:38 -0500 Message-Id: <20181205171039.73066-14-dennis@kernel.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20181205171039.73066-1-dennis@kernel.org> References: <20181205171039.73066-1-dennis@kernel.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Every bio is now associated with a blkg putting blkg_get, blkg_try_get, and blkg_put on the hot path. Switch over the refcnt in blkg to use percpu_ref. Signed-off-by: Dennis Zhou Acked-by: Tejun Heo Reviewed-by: Josef Bacik --- block/blk-cgroup.c | 41 ++++++++++++++++++++++++++++++++++++-- include/linux/blk-cgroup.h | 15 +++++--------- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 120f2e2835fb..2ca7611fe274 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -81,6 +81,37 @@ static void blkg_free(struct blkcg_gq *blkg) kfree(blkg); } +static void __blkg_release(struct rcu_head *rcu) +{ + struct blkcg_gq *blkg = container_of(rcu, struct blkcg_gq, rcu_head); + + percpu_ref_exit(&blkg->refcnt); + + /* release the blkcg and parent blkg refs this blkg has been holding */ + css_put(&blkg->blkcg->css); + if (blkg->parent) + blkg_put(blkg->parent); + + wb_congested_put(blkg->wb_congested); + + blkg_free(blkg); +} + +/* + * A group is RCU protected, but having an rcu lock does not mean that one + * can access all the fields of blkg and assume these are valid. For + * example, don't try to follow throtl_data and request queue links. + * + * Having a reference to blkg under an rcu allows accesses to only values + * local to groups like group stats and group rate limits. + */ +static void blkg_release(struct percpu_ref *ref) +{ + struct blkcg_gq *blkg = container_of(ref, struct blkcg_gq, refcnt); + + call_rcu(&blkg->rcu_head, __blkg_release); +} + /** * blkg_alloc - allocate a blkg * @blkcg: block cgroup the new blkg is associated with @@ -107,7 +138,6 @@ static struct blkcg_gq *blkg_alloc(struct blkcg *blkcg, struct request_queue *q, blkg->q = q; INIT_LIST_HEAD(&blkg->q_node); blkg->blkcg = blkcg; - atomic_set(&blkg->refcnt, 1); for (i = 0; i < BLKCG_MAX_POLS; i++) { struct blkcg_policy *pol = blkcg_policy[i]; @@ -207,6 +237,11 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg, blkg_get(blkg->parent); } + ret = percpu_ref_init(&blkg->refcnt, blkg_release, 0, + GFP_NOWAIT | __GFP_NOWARN); + if (ret) + goto err_cancel_ref; + /* invoke per-policy init */ for (i = 0; i < BLKCG_MAX_POLS; i++) { struct blkcg_policy *pol = blkcg_policy[i]; @@ -239,6 +274,8 @@ static struct blkcg_gq *blkg_create(struct blkcg *blkcg, blkg_put(blkg); return ERR_PTR(ret); +err_cancel_ref: + percpu_ref_exit(&blkg->refcnt); err_put_congested: wb_congested_put(wb_congested); err_put_css: @@ -367,7 +404,7 @@ static void blkg_destroy(struct blkcg_gq *blkg) * Put the reference taken at the time of creation so that when all * queues are gone, group can be destroyed. */ - blkg_put(blkg); + percpu_ref_kill(&blkg->refcnt); } /** diff --git a/include/linux/blk-cgroup.h b/include/linux/blk-cgroup.h index 284819a4d122..d19ef15a673d 100644 --- a/include/linux/blk-cgroup.h +++ b/include/linux/blk-cgroup.h @@ -124,7 +124,7 @@ struct blkcg_gq { struct blkcg_gq *parent; /* reference count */ - atomic_t refcnt; + struct percpu_ref refcnt; /* is this blkg online? protected by both blkcg and q locks */ bool online; @@ -487,8 +487,7 @@ static inline int blkg_path(struct blkcg_gq *blkg, char *buf, int buflen) */ static inline void blkg_get(struct blkcg_gq *blkg) { - WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0); - atomic_inc(&blkg->refcnt); + percpu_ref_get(&blkg->refcnt); } /** @@ -500,7 +499,7 @@ static inline void blkg_get(struct blkcg_gq *blkg) */ static inline struct blkcg_gq *blkg_try_get(struct blkcg_gq *blkg) { - if (atomic_inc_not_zero(&blkg->refcnt)) + if (percpu_ref_tryget(&blkg->refcnt)) return blkg; return NULL; } @@ -514,23 +513,19 @@ static inline struct blkcg_gq *blkg_try_get(struct blkcg_gq *blkg) */ static inline struct blkcg_gq *blkg_try_get_closest(struct blkcg_gq *blkg) { - while (!atomic_inc_not_zero(&blkg->refcnt)) + while (!percpu_ref_tryget(&blkg->refcnt)) blkg = blkg->parent; return blkg; } -void __blkg_release_rcu(struct rcu_head *rcu); - /** * blkg_put - put a blkg reference * @blkg: blkg to put */ static inline void blkg_put(struct blkcg_gq *blkg) { - WARN_ON_ONCE(atomic_read(&blkg->refcnt) <= 0); - if (atomic_dec_and_test(&blkg->refcnt)) - call_rcu(&blkg->rcu_head, __blkg_release_rcu); + percpu_ref_put(&blkg->refcnt); } /** -- 2.17.1