Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp2591295pxa; Mon, 24 Aug 2020 19:53:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxTyGRmbHAgtGUOkixGK/4Pnkfdasm9s62BAEeGst6Fc3u2jAhzJEDC0DBA5GIh0X2xJ65j X-Received: by 2002:a05:6402:36f:: with SMTP id s15mr210072edw.325.1598324002079; Mon, 24 Aug 2020 19:53:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1598324002; cv=none; d=google.com; s=arc-20160816; b=jh0PD4CL61FTzHOe2j1MSom+U7GTz+pVO4o/Q60IcReB4Ctmiz3CDH8ReCy3JT6gNY TMtNY0x1t4a32XdssFozT6LVanVYqpWKYkjw9+8TmoVDQA5ET+GkAFMZ8U8+icHdTNH6 xq3D0J+jC4Qj+M17KGHeaMED7q1hj3cDeEcJpAka4rMpKdxSbEhYYxs0LUSNEJFeErkP bY9GCZUwo39pDhuQUEUNmrNm8ngk83C67ocHmyfYMHkye1zsYnoUgg2GyAeQBQ48g3in mT2qzvl3l4uGNvb7V0Yw9tOVVM92OHs4kV5tlmZDzb+O0qsd+UYzpdAdfdPGyIjttA6q z8xA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Rr2wu86hvyBvF0qDYpQKgu2V3m2RjeVp5RhnLSFtTac=; b=B8lhvtCmk4UuhgjBvzF8P/68NjwozYFYX4hDpvk9y/SjSmnmhwuRZK2sFj2kQNwN8n FsDleKWDFsGLgc1RC0dkDsyP0trTa8aL67qUSFdW+21LHVjNfCFb9MZueZaOwnYfteM/ 1D1N6JQFUIKMfPf1ch8v5Yt0YRaytsQ+VbT5UZyaudjR+R3jK36VORJevkwfXyk0L2JA oswbL9qGnnGlFu2x+OGIFpMXZdL9hmaprAMZxkFGr5t8Ntzf90280H8yqpDdUN2VWkuz S/tKAeXTOYcPfo4PVKWoj+Wt/4jvn4eoTh1o5b/8zrCRuLeinpmJK53+3l4fThG1usdD yuWw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@joelfernandes.org header.s=google header.b=fsoRajiz; 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 w13si6470360eja.81.2020.08.24.19.52.58; Mon, 24 Aug 2020 19:53:22 -0700 (PDT) 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=fsoRajiz; 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 S1728183AbgHYCtE (ORCPT + 99 others); Mon, 24 Aug 2020 22:49:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728245AbgHYCsz (ORCPT ); Mon, 24 Aug 2020 22:48:55 -0400 Received: from mail-qk1-x744.google.com (mail-qk1-x744.google.com [IPv6:2607:f8b0:4864:20::744]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CE791C061797 for ; Mon, 24 Aug 2020 19:48:54 -0700 (PDT) Received: by mail-qk1-x744.google.com with SMTP id n129so9734462qkd.6 for ; Mon, 24 Aug 2020 19:48:54 -0700 (PDT) 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=Rr2wu86hvyBvF0qDYpQKgu2V3m2RjeVp5RhnLSFtTac=; b=fsoRajizjPljsgm6M/MbWqMqC696sWJI9F7blcRie8ChI/LkHG2OMuVlQ2IN63I8RN YQVsiH7wHQ5OkWiA12juc9HSqryWRcczlxnkJmasVTcQArh+RUUhO+ioiH37mhRgObbh lpjr1AJPjZXAn8qhT5zbB5G4pVeQxFNcd2rAU= 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=Rr2wu86hvyBvF0qDYpQKgu2V3m2RjeVp5RhnLSFtTac=; b=hVt5Eeb189i5N8IpwU+oq8I/fNUUZFtby6GHeeemqTI0eXtuqmf7X8FgR/1RAPRTe5 Xk+WRGgbCUaL2d19+sp1dX00v7D5fVWXz2jm2/gy7LJmpSn5YrTlr7q70IwhX0ZLKybw FWYy82SDeQmgl12DFqbZz7hMd5sUnBjw2rlbGk1XViZzXUKptTfN3M8YY0ZBs34A5qfi Rp1p5ifBEp5XB99RqXNndqC7J20xpM6IbXBZO4cZRzDyufFcYOmhmF50gjVHKwMc6GbW Nb76ID6lUNccFrWPb9jH5u1vjUO9OXonT/E4N0CQq1jBYyju9oiYdIl2gMsaOfLU4veX Cpdg== X-Gm-Message-State: AOAM530b/JO2FQIN0du0F+QgXxJUTN8IiEVZ8yHJlhH+Jx8kNkG3rqPZ R3e1P+9R4XrYCPTmu/jAWjRgnlFZAhMPWw== X-Received: by 2002:a37:b88:: with SMTP id 130mr7652261qkl.222.1598323733772; Mon, 24 Aug 2020 19:48:53 -0700 (PDT) Received: from joelaf.cam.corp.google.com ([2620:15c:6:12:cad3:ffff:feb3:bd59]) by smtp.gmail.com with ESMTPSA id n14sm2159188qtk.50.2020.08.24.19.48.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 Aug 2020 19:48:53 -0700 (PDT) From: "Joel Fernandes (Google)" To: linux-kernel@vger.kernel.org Cc: "Joel Fernandes (Google)" , boqun.feng@gmail.com, dave@stgolabs.net, Ingo Molnar , Josh Triplett , Lai Jiangshan , Madhuparna Bhowmik , Mathieu Desnoyers , neeraj.iitr10@gmail.com, "Paul E. McKenney" , rcu@vger.kernel.org, Steven Rostedt , "Uladzislau Rezki (Sony)" , vineethrp@gmail.com Subject: [PATCH v4 -rcu 4/4] rcu/trace: Add tracing for how segcb list changes Date: Mon, 24 Aug 2020 22:48:42 -0400 Message-Id: <20200825024842.3408659-5-joel@joelfernandes.org> X-Mailer: git-send-email 2.28.0.297.g1956fa8f8d-goog In-Reply-To: <20200825024842.3408659-1-joel@joelfernandes.org> References: <20200825024842.3408659-1-joel@joelfernandes.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org 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. Signed-off-by: Joel Fernandes (Google) --- include/trace/events/rcu.h | 25 +++++++++++++++++++++++++ kernel/rcu/rcu_segcblist.c | 27 +++++++++++++++++++++++++++ kernel/rcu/rcu_segcblist.h | 7 +++++++ kernel/rcu/tree.c | 23 +++++++++++++++++++++++ 4 files changed, 82 insertions(+) diff --git a/include/trace/events/rcu.h b/include/trace/events/rcu.h index 155b5cb43cfd..7b84df3c95df 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, + + 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, 4) + __array(unsigned long, gp_seq, 4) + ), + + TP_fast_assign( + __entry->ctx = ctx; + memcpy(__entry->cb_count, cb_count, 4 * sizeof(int)); + memcpy(__entry->gp_seq, gp_seq, 4 * 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 73a103464ea4..6419dbbaecde 100644 --- a/kernel/rcu/rcu_segcblist.c +++ b/kernel/rcu/rcu_segcblist.c @@ -378,6 +378,33 @@ 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 callbacks. Only used from + * tracing code which is usually disabled in production. + */ +#ifdef CONFIG_RCU_TRACE +void rcu_segcblist_countseq(struct rcu_segcblist *rsclp, + int cbcount[RCU_CBLIST_NSEGS], + unsigned long gpseq[RCU_CBLIST_NSEGS]) +{ + struct rcu_head **cur_tail; + int i; + + for (i = 0; i < RCU_CBLIST_NSEGS; i++) + cbcount[i] = 0; + + cur_tail = &(rsclp->head); + + for (i = 0; i < RCU_CBLIST_NSEGS; i++) { + cbcount[i] = rcu_segcblist_get_seglen(rsclp, i); + gpseq[i] = rsclp->gp_seq[i]; + cur_tail = rsclp->tails[i]; + } +} +#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 b90725f81d77..5f7cdfed0ba4 100644 --- a/kernel/rcu/rcu_segcblist.h +++ b/kernel/rcu/rcu_segcblist.h @@ -105,3 +105,10 @@ 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 rcu_segcblist_countseq(struct rcu_segcblist *rsclp, + int cbcount[RCU_CBLIST_NSEGS], + unsigned long gpseq[RCU_CBLIST_NSEGS]); +#else +#define rcu_segcblist_countseq(...) +#endif diff --git a/kernel/rcu/tree.c b/kernel/rcu/tree.c index 51348144a4ea..16ad99a9ebba 100644 --- a/kernel/rcu/tree.c +++ b/kernel/rcu/tree.c @@ -1476,6 +1476,8 @@ static bool rcu_accelerate_cbs(struct rcu_node *rnp, struct rcu_data *rdp) { unsigned long gp_seq_req; bool ret = false; + int cbs[RCU_CBLIST_NSEGS]; + unsigned long gps[RCU_CBLIST_NSEGS]; rcu_lockdep_assert_cblist_protected(rdp); raw_lockdep_assert_held_rcu_node(rnp); @@ -1484,6 +1486,10 @@ static bool rcu_accelerate_cbs(struct rcu_node *rnp, struct rcu_data *rdp) if (!rcu_segcblist_pend_cbs(&rdp->cblist)) return false; + /* Count CBs for tracing. */ + rcu_segcblist_countseq(&rdp->cblist, cbs, gps); + trace_rcu_segcb("SegCbPreAcc", cbs, gps); + /* * Callbacks are often registered with incomplete grace-period * information. Something about the fact that getting exact @@ -1504,6 +1510,10 @@ 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")); + /* Count CBs for tracing. */ + rcu_segcblist_countseq(&rdp->cblist, cbs, gps); + trace_rcu_segcb("SegCbPostAcc", cbs, gps); + return ret; } @@ -2421,6 +2431,8 @@ static void rcu_do_batch(struct rcu_data *rdp) struct rcu_cblist rcl = RCU_CBLIST_INITIALIZER(rcl); long bl, count = 0; long pending, tlimit = 0; + int cbs[RCU_CBLIST_NSEGS]; + unsigned long gps[RCU_CBLIST_NSEGS]; /* If no callbacks are ready, just return. */ if (!rcu_segcblist_ready_cbs(&rdp->cblist)) { @@ -2461,6 +2473,11 @@ static void rcu_do_batch(struct rcu_data *rdp) /* Invoke callbacks. */ tick_dep_set_task(current, TICK_DEP_BIT_RCU); rhp = rcu_cblist_dequeue(&rcl); + + /* Count CBs for tracing. */ + rcu_segcblist_countseq(&rdp->cblist, cbs, gps); + trace_rcu_segcb("SegCbDequeued", cbs, gps); + for (; rhp; rhp = rcu_cblist_dequeue(&rcl)) { rcu_callback_t f; @@ -2929,6 +2946,8 @@ __call_rcu(struct rcu_head *head, rcu_callback_t func) unsigned long flags; struct rcu_data *rdp; bool was_alldone; + int cbs[RCU_CBLIST_NSEGS]; + unsigned long gps[RCU_CBLIST_NSEGS]; /* Misaligned rcu_head! */ WARN_ON_ONCE((unsigned long)head & (sizeof(void *) - 1)); @@ -2974,6 +2993,10 @@ __call_rcu(struct rcu_head *head, rcu_callback_t func) trace_rcu_callback(rcu_state.name, head, rcu_segcblist_n_cbs(&rdp->cblist)); + /* Count CBs for tracing. */ + rcu_segcblist_countseq(&rdp->cblist, cbs, gps); + trace_rcu_segcb("SegCBQueued", cbs, gps); + /* Go handle any RCU core processing required. */ if (IS_ENABLED(CONFIG_RCU_NOCB_CPU) && unlikely(rcu_segcblist_is_offloaded(&rdp->cblist))) { -- 2.28.0.297.g1956fa8f8d-goog