Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp546099pxb; Tue, 3 Nov 2020 06:28:26 -0800 (PST) X-Google-Smtp-Source: ABdhPJzQlOLO3vdtXiYpvHSEsGtdwvMvYPZy8odFGXv4DlGBX5yEad8Z+DxXvEfO4YOyqPqz04qF X-Received: by 2002:a17:906:a119:: with SMTP id t25mr21362334ejy.67.1604413706371; Tue, 03 Nov 2020 06:28:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604413706; cv=none; d=google.com; s=arc-20160816; b=jJ53L7PZZUSPe/+2qHjMYL6XIZilH9NRY0VdofnWNAZsShZvu9pUor2OPxgoo09St8 WHWK1etCZ18Zb4EOs0DiEqliuHuyEgooAEHsSdjbfJBdTaROTW+/Qk1crkpqycCd7e51 bN4TiNGsTajBHdcISOUIWKSzEtKz2XoPCFuyRBcR1jraKb7FxTAngZPjFRWLtDVfj1zx WOHIDqoEhOdkG4ZC9lXe6zu567rlyPeT9iju9WVlwMZLUXQrOlCaYS1fHtZwhPAAdf0o Tnb/24IlkYx/6u8yseEgLDhAkqzvSsYO8ncN0ZWamjTYT/h1+LfA7dmVlSoQRKPRkJLe nQGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=mucybD6StJqSnm1Khhz72fhNCKKWVCVi3XxrlWOTUvs=; b=EEw9btQwLF9zyposCh2Z+r37s7C6qKked+PGtnPvQFcJE2jo1HkmJ7Slq7uIa052G/ 6wx3wxMGgwzi+jCpHed39FJur2q1Q1Rqkx1EN4+qQNFfMCOBFanQ01y8xRGGcaa647pF 7XjKAKlKqORZ2K44Ra6RBq0lzkbfWbAyIGzRH0f6B3bg+7xigg+wnHg0Nr9/iLBdRx7z jYRBldMabA3NQKKN6ncydhqupTyu0OHAjHDDNBxjfLgk2r6BUZlTPw0+6pdC67T29ny7 BQYxPB3MMHQB8t2fVsczbBbbfun1CMczXMfzeHHDmhWrfYOcXgNyEDSs+8HoTq/H1SBs hYvA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@joelfernandes.org header.s=google header.b=djDApmUO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id d10si4892942ejh.20.2020.11.03.06.28.03; Tue, 03 Nov 2020 06:28:26 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@joelfernandes.org header.s=google header.b=djDApmUO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729511AbgKCO0b (ORCPT + 99 others); Tue, 3 Nov 2020 09:26:31 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46750 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729734AbgKCO0P (ORCPT ); Tue, 3 Nov 2020 09:26:15 -0500 Received: from mail-qt1-x842.google.com (mail-qt1-x842.google.com [IPv6:2607:f8b0:4864:20::842]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E6B0CC0617A6 for ; Tue, 3 Nov 2020 06:26:13 -0800 (PST) Received: by mail-qt1-x842.google.com with SMTP id m14so11640045qtc.12 for ; Tue, 03 Nov 2020 06:26:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=joelfernandes.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mucybD6StJqSnm1Khhz72fhNCKKWVCVi3XxrlWOTUvs=; b=djDApmUOn/yi7DnDehLnzF00V/FRT/ck75VbewamDPk64OWZJmn2fNnCnU2hMqfd0e lk/htUIVurXRnLSVOOT72L++zkE3vmscSR73f7eh9G0qwPeZ+cveDyUPf88kJIr5XDqu 8ZzmSJUqU54ma7kZnVxfKJYbQ95Q2xDO7Ekfc= 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:mime-version:content-transfer-encoding; bh=mucybD6StJqSnm1Khhz72fhNCKKWVCVi3XxrlWOTUvs=; b=KlDqgMtTkdGWnaRPu2vFe9/UhyucSx6IPJ698K/u8ZGrCQyrZCk+GKGYFLnoy0zTVb 0/6uOQrEQhPu8cUfUnCrXb0I5kkNEZ94zhiTAtuTg8eI4xKynwgr/cMHObBsyzPNJ7d/ +nEMYNQD+mt8TyehuHsYy8LHO9oKOxebWdbOVWhIX1RTsjep5OWh4Z1s5vvcffkRgEqq LkH2a/6o8fYH8RGRud4gQPhhCR74+nFi1QlWw5QP3jHPEtqebD6d2poH3ylzS0gzrwFc qxROyr0V6Q8HjPxX0gAH+4rkk5/yUvMRN8ekXxtF9JnicOR0FQztcj1wdwG9Y1a4ynKo oreA== X-Gm-Message-State: AOAM5302R9GzeG7R1Y1gICpwSJnldJ8G/u5wNM+Q1M9Fxht80qTatg6d pfp7TmtqDpGT1bW/eCZVBZrPjBCwUIQYOw== X-Received: by 2002:ac8:3797:: with SMTP id d23mr6243630qtc.205.1604413572847; Tue, 03 Nov 2020 06:26:12 -0800 (PST) Received: from joelaf.cam.corp.google.com ([2620:15c:6:411:cad3:ffff:feb3:bd59]) by smtp.gmail.com with ESMTPSA id l30sm10564967qta.73.2020.11.03.06.26.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Nov 2020 06:26:12 -0800 (PST) From: "Joel Fernandes (Google)" To: linux-kernel@vger.kernel.org Cc: "Joel Fernandes (Google)" , Frederic Weisbecker , Neeraj Upadhyay , Josh Triplett , Lai Jiangshan , Marco Elver , Mathieu Desnoyers , "Paul E. McKenney" , rcu@vger.kernel.org, Steven Rostedt , "Uladzislau Rezki (Sony)" , fweisbec@gmail.com, neeraj.iitr10@gmail.com Subject: [PATCH v9 4/7] rcu/trace: Add tracing for how segcb list changes Date: Tue, 3 Nov 2020 09:26:00 -0500 Message-Id: <20201103142603.1302207-5-joel@joelfernandes.org> X-Mailer: git-send-email 2.29.1.341.ge80a0c044ae-goog In-Reply-To: <20201103142603.1302207-1-joel@joelfernandes.org> References: <20201103142603.1302207-1-joel@joelfernandes.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Track how the segcb list changes before/after acceleration, during queuing and during dequeuing. This has proved useful to discover an optimization to avoid unwanted GP requests when there are no callbacks accelerated. The overhead is minimal as each segment's length is now stored in the respective segment. Reviewed-by: Frederic Weisbecker Reviewed-by: Neeraj Upadhyay Signed-off-by: Joel Fernandes (Google) --- include/trace/events/rcu.h | 25 +++++++++++++++++++++++++ kernel/rcu/rcu_segcblist.c | 34 ++++++++++++++++++++++++++++++++++ kernel/rcu/rcu_segcblist.h | 5 +++++ kernel/rcu/tree.c | 9 +++++++++ 4 files changed, 73 insertions(+) diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h index 155b5cb43cfd..5f8f2ee1a936 100644 --- a/include/trace/events/rcu.h +++ b/include/trace/events/rcu.h @@ -505,6 +505,31 @@ TRACE_EVENT_RCU(rcu_callback, __entry->qlen) ); +TRACE_EVENT_RCU(rcu_segcb_stats, + + TP_PROTO(const char *ctx, int *cb_count, unsigned long *gp_seq), + + TP_ARGS(ctx, cb_count, gp_seq), + + TP_STRUCT__entry( + __field(const char *, ctx) + __array(int, cb_count, RCU_CBLIST_NSEGS) + __array(unsigned long, gp_seq, RCU_CBLIST_NSEGS) + ), + + TP_fast_assign( + __entry->ctx = ctx; + memcpy(__entry->cb_count, cb_count, RCU_CBLIST_NSEGS * sizeof(int)); + memcpy(__entry->gp_seq, gp_seq, RCU_CBLIST_NSEGS * sizeof(unsigned long)); + ), + + TP_printk("%s cb_count: (DONE=%d, WAIT=%d, NEXT_READY=%d, NEXT=%d) " + "gp_seq: (DONE=%lu, WAIT=%lu, NEXT_READY=%lu, NEXT=%lu)", __entry->ctx, + __entry->cb_count[0], __entry->cb_count[1], __entry->cb_count[2], __entry->cb_count[3], + __entry->gp_seq[0], __entry->gp_seq[1], __entry->gp_seq[2], __entry->gp_seq[3]) + +); + /* * Tracepoint for the registration of a single RCU callback of the special * kvfree() form. The first argument is the RCU type, the second argument diff --git a/kernel/rcu/rcu_segcblist.c b/kernel/rcu/rcu_segcblist.c index 357c19bbcb00..2a03949d0b82 100644 --- a/kernel/rcu/rcu_segcblist.c +++ b/kernel/rcu/rcu_segcblist.c @@ -14,6 +14,7 @@ #include #include "rcu_segcblist.h" +#include "rcu.h" /* Initialize simple callback list. */ void rcu_cblist_init(struct rcu_cblist *rclp) @@ -328,6 +329,39 @@ void rcu_segcblist_extract_done_cbs(struct rcu_segcblist *rsclp, rcu_segcblist_set_seglen(rsclp, RCU_DONE_TAIL, 0); } +/* + * Return how many CBs each segment along with their gp_seq values. + * + * This function is O(N) where N is the number of segments. Only used from + * tracing code which is usually disabled in production. + */ +#ifdef CONFIG_RCU_TRACE +static void rcu_segcblist_countseq(struct rcu_segcblist *rsclp, + int cbcount[RCU_CBLIST_NSEGS], + unsigned long gpseq[RCU_CBLIST_NSEGS]) +{ + int i; + + for (i = 0; i < RCU_CBLIST_NSEGS; i++) { + cbcount[i] = rcu_segcblist_get_seglen(rsclp, i); + gpseq[i] = rsclp->gp_seq[i]; + } +} + +void __trace_rcu_segcb_stats(struct rcu_segcblist *rsclp, const char *context) +{ + int cbs[RCU_CBLIST_NSEGS]; + unsigned long gps[RCU_CBLIST_NSEGS]; + + if (!trace_rcu_segcb_stats_enabled()) + return; + + rcu_segcblist_countseq(rsclp, cbs, gps); + + trace_rcu_segcb_stats(context, cbs, gps); +} +#endif + /* * Extract only those callbacks still pending (not yet ready to be * invoked) from the specified rcu_segcblist structure and place them in diff --git a/kernel/rcu/rcu_segcblist.h b/kernel/rcu/rcu_segcblist.h index cd35c9faaf51..7750734fa116 100644 --- a/kernel/rcu/rcu_segcblist.h +++ b/kernel/rcu/rcu_segcblist.h @@ -103,3 +103,8 @@ void rcu_segcblist_advance(struct rcu_segcblist *rsclp, unsigned long seq); bool rcu_segcblist_accelerate(struct rcu_segcblist *rsclp, unsigned long seq); void rcu_segcblist_merge(struct rcu_segcblist *dst_rsclp, struct rcu_segcblist *src_rsclp); +#ifdef CONFIG_RCU_TRACE +void __trace_rcu_segcb_stats(struct rcu_segcblist *rsclp, const char *context); +#else +#define __trace_rcu_segcb_stats(...) +#endif diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 24c00020ab83..f6c6653b3ec2 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -1497,6 +1497,8 @@ static bool rcu_accelerate_cbs(struct rcu_node *rnp, struct rcu_data *rdp) if (!rcu_segcblist_pend_cbs(&rdp->cblist)) return false; + __trace_rcu_segcb_stats(&rdp->cblist, TPS("SegCbPreAcc")); + /* * Callbacks are often registered with incomplete grace-period * information. Something about the fact that getting exact @@ -1517,6 +1519,8 @@ static bool rcu_accelerate_cbs(struct rcu_node *rnp, struct rcu_data *rdp) else trace_rcu_grace_period(rcu_state.name, gp_seq_req, TPS("AccReadyCB")); + __trace_rcu_segcb_stats(&rdp->cblist, TPS("SegCbPostAcc")); + return ret; } @@ -2466,11 +2470,14 @@ static void rcu_do_batch(struct rcu_data *rdp) rcu_segcblist_extract_done_cbs(&rdp->cblist, &rcl); if (offloaded) rdp->qlen_last_fqs_check = rcu_segcblist_n_cbs(&rdp->cblist); + + __trace_rcu_segcb_stats(&rdp->cblist, TPS("SegCbDequeued")); rcu_nocb_unlock_irqrestore(rdp, flags); /* Invoke callbacks. */ tick_dep_set_task(current, TICK_DEP_BIT_RCU); rhp = rcu_cblist_dequeue(&rcl); + for (; rhp; rhp = rcu_cblist_dequeue(&rcl)) { rcu_callback_t f; @@ -2983,6 +2990,8 @@ __call_rcu(struct rcu_head *head, rcu_callback_t func) trace_rcu_callback(rcu_state.name, head, rcu_segcblist_n_cbs(&rdp->cblist)); + __trace_rcu_segcb_stats(&rdp->cblist, TPS("SegCBQueued")); + /* Go handle any RCU core processing required. */ if (unlikely(rcu_segcblist_is_offloaded(&rdp->cblist))) { __call_rcu_nocb_wake(rdp, was_alldone, flags); /* unlocks */ -- 2.29.1.341.ge80a0c044ae-goog