From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 79D01C2D0CD for ; Mon, 19 May 2025 16:44:30 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 39C0E6B0092; Mon, 19 May 2025 12:44:25 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 2852B6B00D6; Mon, 19 May 2025 12:44:25 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 0FF8E6B00BE; Mon, 19 May 2025 12:44:25 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id D8DEF6B00D8 for ; Mon, 19 May 2025 12:44:24 -0400 (EDT) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 0BDDD120AD4 for ; Mon, 19 May 2025 16:44:27 +0000 (UTC) X-FDA: 83460230574.26.BC5149B Received: from sea.source.kernel.org (sea.source.kernel.org [172.234.252.31]) by imf01.hostedemail.com (Postfix) with ESMTP id 456A44000C for ; Mon, 19 May 2025 16:44:25 +0000 (UTC) Authentication-Results: imf01.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=oVe2cC2L; spf=pass (imf01.hostedemail.com: domain of sj@kernel.org designates 172.234.252.31 as permitted sender) smtp.mailfrom=sj@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1747673065; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=miYaiVhTvKKYH/dJ3JSb+tAdLgydhahm3LZEudenD6w=; b=OFC1nIqCWVsB8HgmhBOk9b+/Ecpe21fAamPYivQ1Ot91z0n1+G08bsEeN1UeTa4PkDU964 iwTW4B2hCGlFoWciY222YYbYG7UKC9cWdIbkYdfA03Rf1ElFEkE002dmz5INd4AmVDFnHk cVkrPx32r1ZvGipbCbaa8OzBrimAbHM= ARC-Authentication-Results: i=1; imf01.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=oVe2cC2L; spf=pass (imf01.hostedemail.com: domain of sj@kernel.org designates 172.234.252.31 as permitted sender) smtp.mailfrom=sj@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1747673065; a=rsa-sha256; cv=none; b=fqxUNS7Pq/jeZybXYUKEN3vl8wD0OWw+TGX/m9CLggeGItIj6jn9hbRIR9+d1ZPCSPYH4V 8FBexc4sOxv2lmmfkY3IGGNR4ezrAvKfFpcouXu5fBTFskY34X6T2fJ5EVVHkktXpfN/L6 FXkljMZ04rwqtw+Nzuy81OryzgXI0Fk= Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sea.source.kernel.org (Postfix) with ESMTP id F36F94AAAC; Mon, 19 May 2025 16:44:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A2A74C4CEF0; Mon, 19 May 2025 16:44:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1747673063; bh=/8/4pFjPPVhMHFQr9b7mNlWI254qxXmUWO34UkwncD0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oVe2cC2LWrFButcYacjM61U3B0tTyqTFHXvQXBW9j7iWzRkPUb2mn+annjBmoQzxH kAbDowbPqUb5KzwvuonOxVMl0NX/vbim+YekttfSP4u7lw3dod7RaZCjwS1Lrtn29b H4ojoYD1FA11sIDss8VMhsr76El3O98DAJo84Apc4biyP1Fwldctw6pQNMfAr5eyPC keAyT3fR0/egdROn5n0hjeH0dv0LiWZNu048H8tgD65W2ilCqHG5M7g4NxBxZJDi+J +E2GozUxhJwpnXxUVIScww6jCBeOBsJGXI+XwDPfEDhQZwoXuH/iv+2YiTXyWVXNQy nQTelKv1FRUOw== From: SeongJae Park To: Cc: SeongJae Park , Andrew Morton , damon@lists.linux.dev, kernel-team@meta.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [RFC PATCH 3/3] mm/damon/stat: calculate and expose idle time percentiles Date: Mon, 19 May 2025 09:44:15 -0700 Message-Id: <20250519164415.43935-4-sj@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250519164415.43935-1-sj@kernel.org> References: <20250519164415.43935-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Stat-Signature: 9mcjgaemstreiqeo86o95hufxub51ngc X-Rspam-User: X-Rspamd-Server: rspam03 X-Rspamd-Queue-Id: 456A44000C X-HE-Tag: 1747673065-372281 X-HE-Meta: U2FsdGVkX19/FLAvjy0Nwrm99SJ8Ixvnl8KxxfB1lfYqy++yLcVf9mGYGCP0YUQOtScaejNB3v42B+BC43g9NwVDwr8YnNqThByA5RZ43QNjO0scrh5fWBNcYoaosnZj8uWDaQFNGll0NQzeYToPWcN5d6gT7USbnkQPoijjDNoHTkAcNIKZkuwP78/an4fmcSZyEIBg+PoTTM+e/fe+ElTBvk+ybBejfIkJ/DhMCLcPIvp09DxRI4pQZUyB7MoXBAomrHFSzent960tM8Xn9wpiZ4QsvtNtoDV1xHcNN/Ru2QnxAqeqyKLb/ng/yjLgQE8ZuKre9H6FePN53cH4cCh/PxwPOKhy9Iyx3ATVuztrEGpAwGkPL2+HJ45cciba8P2YFvBA+YCHFELR5sDxjano3RBCPyqHcyhSd1Gs8fD9ayEacggl1HILYCfXAf+mve4TIXWPwLyfgbDcWmjdyRlvOZQKSS1AukpSTmz4Ajr2ch7igUZq+7SLLqSEL3o6kv1HrNnt6cfYmT9rKDmclEBB4bTl+l8HNCl/XzHIzWclS7a6T5BLc0NaQvtNg2Zitk3pIz2KvFb0zDQQ+IvlIpTYDHW7ZI09laEGNJVAvLz9YifJGaDA1Af/BxGLLnkryLSXe9Ts+Mqnbhi9OXL9ZQ46bXK9qA1i6729+tRfyQ7Qt+43repa+92ZyqSSF6JPfh72P0Q6a1PAt0AVqnMIc7pNdvvv+UdRClpSLhX0Tp8UFNTw4i7gMQ3Cn2rAGMBBPi43IEw9UEWOhbEv1NVgE5VTz2zACPZIz0uRjmrK0HWFtED6kdmN8Ta8G8izSh53m6HjrlpTWuB1RvNCbTpT2bBHwzLBBu/ing8719+l28rSZlr8VBuhUK1Q7lAOEV8bux37pvtYPJf2qgsc/7lP1cqKN/wwK59XtzSnH2hJjawmfN20QeUPkN0dULscHGtXYKNy2TGR5YcEZFiGiwL 1ciK+fzz DcDGpVRkw8GADZQ7VuLgps5pMwV6Sj0Yfop5kjEcZJvf1eyI+LoMlB70uZDAzqf9+oebsyOGwERvX2Q9cMgVt4cpcm2ZE3Gl/DJMNzKj6Xl6DQ4n/d3p7n//a9VxDttLlp/VDsOiWV6vNdgZbhOJZiAnIsOdWp+GK6GYr/T0Itun0nd3ArZpFjrbliMxljyEIKJMihJ7rWvXqCVFmyqzEuhEoO946PLhTzXlqlhiMTAXyQIqWIJZwkSnlVAQkNiokW6X2I4K9kDJ9irA= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Knowing how much memory are how cold can be useful for understanding coldness and utilization efficiency of memory. The raw form of DAMON's monitoring results has the information. Convert the raw results into the per-byte idle time distributions and expose it as percentiles metric to users, as a read-only DAMON_STAT parameter. In detail, the metrics are calcualted as following. First, DAMON's per-region access frequency and age information is converted into per-byte idle time. If access frequency of a region is higher than zero, every byte of the region has zero idle time. If access frequency of a region is zero, every byte of the region has idle time as the age of the region. Then the logic sorts the per-byte idle times and provides the value at 0/100, 1/100, ..., 99/100 and 100/100 location of the sorted array. The metric can be easily aggregated and compared on large scale production systems. For example, if an average of 75-th percentile idle time of machines that collected on similar time is two minutes, it means the system's 25 percent memory is not accessed at all for two minutes or more in average. If a workload considers two minutes as unit work time, we can conclude its working set size is only 75 percent of the memory. If the system utilizes proactive reclamation and it supports coldness-based thresholds like DAMON_RECLAIM, te idle time percentiles can be used to find more safe or aggressive coldness threshold for aimed memory saving. Signed-off-by: SeongJae Park --- mm/damon/stat.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/mm/damon/stat.c b/mm/damon/stat.c index f9ae44db265b..7ef13ea22221 100644 --- a/mm/damon/stat.c +++ b/mm/damon/stat.c @@ -33,6 +33,11 @@ module_param(estimated_memory_bandwidth, ulong, 0400); MODULE_PARM_DESC(estimated_memory_bandwidth, "Estimated memory bandwidth usage in bytes per second"); +static unsigned long memory_idle_ms_percentiles[101] __read_mostly = {0,}; +module_param_array(memory_idle_ms_percentiles, ulong, NULL, 0400); +MODULE_PARM_DESC(memory_idle_ms_percentiles, + "Memory idle time percentiles in milliseconds"); + static struct damon_ctx *damon_stat_context; static void damon_stat_set_estimated_memory_bandwidth(struct damon_ctx *c) @@ -50,6 +55,72 @@ static void damon_stat_set_estimated_memory_bandwidth(struct damon_ctx *c) MSEC_PER_SEC / c->attrs.aggr_interval; } +static unsigned int damon_stat_idletime(const struct damon_region *r) +{ + if (r->nr_accesses) + return 0; + return r->age + 1; +} + +static int damon_stat_cmp_regions(const void *a, const void *b) +{ + const struct damon_region *ra = *(const struct damon_region **)a; + const struct damon_region *rb = *(const struct damon_region **)b; + + return damon_stat_idletime(ra) - damon_stat_idletime(rb); +} + +static int damon_stat_sort_regions(struct damon_ctx *c, + struct damon_region ***sorted_ptr, int *nr_regions_ptr, + unsigned long *total_sz_ptr) +{ + struct damon_target *t; + struct damon_region *r; + struct damon_region **region_pointers; + unsigned int nr_regions = 0; + unsigned long total_sz = 0; + + damon_for_each_target(t, c) { + /* there is only one target */ + region_pointers = kmalloc_array(damon_nr_regions(t), + sizeof(*region_pointers), GFP_KERNEL); + if (!region_pointers) + return -ENOMEM; + damon_for_each_region(r, t) { + region_pointers[nr_regions++] = r; + total_sz += r->ar.end - r->ar.start; + } + } + sort(region_pointers, nr_regions, sizeof(*region_pointers), + damon_stat_cmp_regions, NULL); + *sorted_ptr = region_pointers; + *nr_regions_ptr = nr_regions; + *total_sz_ptr = total_sz; + return 0; +} + +static void damon_stat_set_idletime_percentiles(struct damon_ctx *c) +{ + struct damon_region **sorted_regions, *region; + int nr_regions; + unsigned long total_sz, accounted_bytes = 0; + int err, i, next_percentile = 0; + + err = damon_stat_sort_regions(c, &sorted_regions, &nr_regions, + &total_sz); + if (err) + return; + for (i = 0; i < nr_regions; i++) { + region = sorted_regions[i]; + accounted_bytes += region->ar.end - region->ar.start; + while (next_percentile <= accounted_bytes * 100 / total_sz) + memory_idle_ms_percentiles[next_percentile++] = + damon_stat_idletime(region) * + c->attrs.aggr_interval / USEC_PER_MSEC; + } + kfree(sorted_regions); +} + static int damon_stat_after_aggregation(struct damon_ctx *c) { static unsigned long last_refresh_jiffies; @@ -61,6 +132,7 @@ static int damon_stat_after_aggregation(struct damon_ctx *c) last_refresh_jiffies = jiffies; damon_stat_set_estimated_memory_bandwidth(c); + damon_stat_set_idletime_percentiles(c); return 0; } -- 2.39.5