Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp2180435ybl; Thu, 19 Dec 2019 09:16:19 -0800 (PST) X-Google-Smtp-Source: APXvYqw6nP5LzDwpIj7RQiYVe5by3VS9VaySGTPZnDfHDRRyQgYNYnYIVZUVEe0lPHcEgfuEBnfe X-Received: by 2002:aca:1b08:: with SMTP id b8mr2572608oib.106.1576775779148; Thu, 19 Dec 2019 09:16:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1576775779; cv=none; d=google.com; s=arc-20160816; b=pSO3+pzdd+t8QPLZPtxhfkp3WYPdVjYvptFMEh3p6rKdIXKQy0EHiX3k64nK0Di5H6 pSAO8gv2nFe4hIHaqBxYj9ZSduy/B1YYaE7xh3Xp+2MxknDE746i5M/TK4ZgUl6QSGG+ qvr+XhrX8Bujio9whfpD1QGTHfYZuZTGTgXedvpn5QG8wN9D5+t9EmD1phhG0tjwmVpZ 1VgbhLs3mQLqMZHlkVucqBGmMvurOFPdqOWRIYCp7JbE5Pdx8qGq9kYkFwNxbMCvFlBp L9/3/GmKF/Q8jlcVmQ/eNP5d1cX5FzOCh858GjL/hUp9ZUexHAgMhJSDOYqPQNjTtg71 3Ojw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:reply-to:message-id :subject:cc:to:from:date:dkim-signature; bh=BbglfyxJOIwteIxVRJYjxqGzI/scqaQ4nLf/yECKD2o=; b=d/x/SvLysHMekgyVhHcal1/SX97JNyheB5cmQEHS7Z3gLPLBWXMgbtqieW4HcUTvhU +VeMlfXoB1i/U6dZkfXgL9WEPIhq1AsuW9QXlcBaay/anZ4Aw38fUO1a44ED9mG+JOw+ S85XfkbowAl45Sho73fhu1TsOjkEK1LpXw0y3CP0sLxKb5EVV7OpL3Qz5Ud3pfiR5l1r kDIuN+5WCix/8Vhg8bIh1/vfOfGZi5OG8oWTreKFy244srDsTA0RKZ/KvysaHdvFAmCP vOUE963geR0o+36EFOVvOKgFPpT5PQ+hAIOBFobUugLpWdwloXwD0LHnXcyHgEJ3RxkQ AX6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=hbXyrMl4; 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=pass (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 s68si3460464oih.275.2019.12.19.09.16.06; Thu, 19 Dec 2019 09:16:19 -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; dkim=pass header.i=@kernel.org header.s=default header.b=hbXyrMl4; 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=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726928AbfLSROE (ORCPT + 99 others); Thu, 19 Dec 2019 12:14:04 -0500 Received: from mail.kernel.org ([198.145.29.99]:35788 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726760AbfLSROE (ORCPT ); Thu, 19 Dec 2019 12:14:04 -0500 Received: from paulmck-ThinkPad-P72.home (50-39-105-78.bvtn.or.frontiernet.net [50.39.105.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 8DA032053B; Thu, 19 Dec 2019 17:14:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1576775642; bh=uAMMjNIlagJKp+x3jQrVT66BTGLAiz2Mgu5j/5XkSHM=; h=Date:From:To:Cc:Subject:Reply-To:References:In-Reply-To:From; b=hbXyrMl4mejHGkmb/S1AztF+nWkpnnsjo+19Se6c0cMPkpz/xRmYIFV3hMhzqLYzQ 7xzNyjm5G5yTwsH6IxgZ7/VdjDEkvWJndfxksjYfeJNUFb7W4CTQyUzVMehBVF0L57 Yqpbd563U8t8jKwsXU19WlDT538qxhOD1CaE3H9A= Received: by paulmck-ThinkPad-P72.home (Postfix, from userid 1000) id 58BF9352274B; Thu, 19 Dec 2019 09:14:02 -0800 (PST) Date: Thu, 19 Dec 2019 09:14:02 -0800 From: "Paul E. McKenney" To: "Joel Fernandes (Google)" Cc: linux-kernel@vger.kernel.org, bristot@redhat.com, frextrite@gmail.com, madhuparnabhowmik04@gmail.com, urezki@gmail.com, Davidlohr Bueso , Josh Triplett , Lai Jiangshan , Mathieu Desnoyers , rcu@vger.kernel.org, Steven Rostedt Subject: Re: [PATCH v2 rcu-dev] rcuperf: Measure memory footprint during kfree_rcu() test Message-ID: <20191219171402.GB2889@paulmck-ThinkPad-P72> Reply-To: paulmck@kernel.org References: <20191219162242.128282-1-joel@joelfernandes.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20191219162242.128282-1-joel@joelfernandes.org> User-Agent: Mutt/1.9.4 (2018-02-28) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Dec 19, 2019 at 11:22:42AM -0500, Joel Fernandes (Google) wrote: > During changes to kfree_rcu() code, we often check how much is free > memory. Instead of doing so manually, add a measurement in the test > itself. We measure 4 times during the test for available memory and > compare with the beginning. > > A sample run shows something like: > > Total time taken by all kfree'ers: 6369738407 ns, loops: 10000, batches: 764, memory footprint: 216MB > > Signed-off-by: Joel Fernandes (Google) Does the following make sense for the commit log? ------------------------------------------------------------------------ During changes to kfree_rcu() code, we often check the amount of free memory. As an alternative to checking this manually, this commit adds a measurement in the test itself. It measures four times during the test for available memory, digitally filters these measurements to produce a running average with a weight of 0.5, and compares this digitally filtered value with the amount of available memory at the beginning of the test. Something like the following is printed at the end of the run: Total time taken by all kfree'ers: 6369738407 ns, loops: 10000, batches: 764, memory footprint: 216MB ------------------------------------------------------------------------ And some questions below. I have queued this for testing and further review with the commit log above in the meantime. Thanx, Paul > --- > v1->v2 : Minor corrections > > Cc: bristot@redhat.com > Cc: frextrite@gmail.com > Cc: madhuparnabhowmik04@gmail.com > Cc: urezki@gmail.com > > kernel/rcu/rcuperf.c | 14 ++++++++++++-- > 1 file changed, 12 insertions(+), 2 deletions(-) > > diff --git a/kernel/rcu/rcuperf.c b/kernel/rcu/rcuperf.c > index da94b89cd531..91f0650914cc 100644 > --- a/kernel/rcu/rcuperf.c > +++ b/kernel/rcu/rcuperf.c > @@ -12,6 +12,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -611,6 +612,7 @@ kfree_perf_thread(void *arg) > long me = (long)arg; > struct kfree_obj *alloc_ptr; > u64 start_time, end_time; > + long mem_begin, mem_during = 0; > > VERBOSE_PERFOUT_STRING("kfree_perf_thread task started"); > set_cpus_allowed_ptr(current, cpumask_of(me % nr_cpu_ids)); > @@ -626,6 +628,12 @@ kfree_perf_thread(void *arg) > } > > do { > + if (!mem_during) { > + mem_during = mem_begin = si_mem_available(); So we sample at the beginning of the test before we have either allocated or freed. Or did I miss a beginning-of-test allocation somehow? > + } else if (loop % (kfree_loops / 4) == 0) { > + mem_during = (mem_during + si_mem_available()) / 2; This is the digital-filter step. The truncating nature of integer division could actually get us four samples counting the first one if kfree_loops evenly divides by four, or five otherwise, correct? In the latter case, we would have a measurement near the end of the test, but not exactly at the end of the test, right? And I have to ask, having studied control systems back in the day... Why digitally filter by 0.5 as opposed to any other choice? For example, you could weight recent history more heavily: mem_during = (mem_during + 3 * si_mem_available()) / 4; Or vice versa: mem_during = (3 * mem_during + si_mem_available()) / 4; So why the specific choice of 0.5? Oh, and integer overflow is a problem on 32-bit platforms with more than 2GB of memory, for example x86 or ARM physical-address-extension (PAE) systems. I therefore changed the declarations to "long long" (and adjusted the format accordingly), but please let me know if I am missing some other effect that prevents overflow. This does not address the possible problem of 64-bit systems that really have 64 bits worth of physical memory, but I am happy to leave that one for the time being, to be fixed if and when. ;-) Adjusted patch shown below. Please let me know if I have messed anything up, and if there is nothing obviously wrong, please give it a good testing. > + } > + > for (i = 0; i < kfree_alloc_num; i++) { > alloc_ptr = kmalloc(sizeof(struct kfree_obj), GFP_KERNEL); > if (!alloc_ptr) > @@ -645,9 +653,11 @@ kfree_perf_thread(void *arg) > else > b_rcu_gp_test_finished = cur_ops->get_gp_seq(); > > - pr_alert("Total time taken by all kfree'ers: %llu ns, loops: %d, batches: %ld\n", > + pr_alert("Total time taken by all kfree'ers: %llu ns, loops: %d, batches: %ld, memory footprint: %ldMB\n", > (unsigned long long)(end_time - start_time), kfree_loops, > - rcuperf_seq_diff(b_rcu_gp_test_finished, b_rcu_gp_test_started)); > + rcuperf_seq_diff(b_rcu_gp_test_finished, b_rcu_gp_test_started), > + (mem_begin - mem_during) >> (20 - PAGE_SHIFT)); > + > if (shutdown) { > smp_mb(); /* Assign before wake. */ > wake_up(&shutdown_wq); > -- > 2.24.1.735.g03f4e72817-goog ------------------------------------------------------------------------ commit 8bf389d441538030d07a9a0f9e38ec0843f7a83e Author: Joel Fernandes (Google) Date: Thu Dec 19 11:22:42 2019 -0500 rcuperf: Measure memory footprint during kfree_rcu() test During changes to kfree_rcu() code, we often check the amount of free memory. As an alternative to checking this manually, this commit adds a measurement in the test itself. It measures four times during the test for available memory, digitally filters these measurements to produce a running average with a weight of 0.5, and compares this digitally filtered value with the amount of available memory at the beginning of the test. Something like the following is printed at the end of the run: Total time taken by all kfree'ers: 6369738407 ns, loops: 10000, batches: 764, memory footprint: 216MB Signed-off-by: Joel Fernandes (Google) Signed-off-by: Paul E. McKenney diff --git a/kernel/rcu/rcuperf.c b/kernel/rcu/rcuperf.c index da94b89..a4a8d09 100644 --- a/kernel/rcu/rcuperf.c +++ b/kernel/rcu/rcuperf.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -611,6 +612,7 @@ kfree_perf_thread(void *arg) long me = (long)arg; struct kfree_obj *alloc_ptr; u64 start_time, end_time; + long long mem_begin, mem_during = 0; VERBOSE_PERFOUT_STRING("kfree_perf_thread task started"); set_cpus_allowed_ptr(current, cpumask_of(me % nr_cpu_ids)); @@ -626,6 +628,12 @@ kfree_perf_thread(void *arg) } do { + if (!mem_during) { + mem_during = mem_begin = si_mem_available(); + } else if (loop % (kfree_loops / 4) == 0) { + mem_during = (mem_during + si_mem_available()) / 2; + } + for (i = 0; i < kfree_alloc_num; i++) { alloc_ptr = kmalloc(sizeof(struct kfree_obj), GFP_KERNEL); if (!alloc_ptr) @@ -645,9 +653,11 @@ kfree_perf_thread(void *arg) else b_rcu_gp_test_finished = cur_ops->get_gp_seq(); - pr_alert("Total time taken by all kfree'ers: %llu ns, loops: %d, batches: %ld\n", + pr_alert("Total time taken by all kfree'ers: %llu ns, loops: %d, batches: %ld, memory footprint: %lldMB\n", (unsigned long long)(end_time - start_time), kfree_loops, - rcuperf_seq_diff(b_rcu_gp_test_finished, b_rcu_gp_test_started)); + rcuperf_seq_diff(b_rcu_gp_test_finished, b_rcu_gp_test_started), + (mem_begin - mem_during) >> (20 - PAGE_SHIFT)); + if (shutdown) { smp_mb(); /* Assign before wake. */ wake_up(&shutdown_wq);