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 2B8A2C5AD49 for ; Mon, 26 May 2025 21:09:52 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 0905E6B0089; Mon, 26 May 2025 17:09:48 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id E6F196B008A; Mon, 26 May 2025 17:09:47 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D5DD56B008C; Mon, 26 May 2025 17:09:47 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id B5F6B6B0089 for ; Mon, 26 May 2025 17:09:47 -0400 (EDT) Received: from smtpin16.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id 4F1541D44FB for ; Mon, 26 May 2025 21:09:47 +0000 (UTC) X-FDA: 83486300814.16.69DF259 Received: from sea.source.kernel.org (sea.source.kernel.org [172.234.252.31]) by imf15.hostedemail.com (Postfix) with ESMTP id 8E2F6A0007 for ; Mon, 26 May 2025 21:09:45 +0000 (UTC) Authentication-Results: imf15.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=elTcgBEM; dmarc=pass (policy=quarantine) header.from=kernel.org; spf=pass (imf15.hostedemail.com: domain of sj@kernel.org designates 172.234.252.31 as permitted sender) smtp.mailfrom=sj@kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1748293785; 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=3T3NNJCvqAWr50DcflaJH1kOnRPqJG9OmJxO2htoHkQ=; b=ZWw+MeiFEGnozLG5ztQ3YzyLQajzVm3JYEJsFEMp0kSOeHpgxWtFj+haecaMSZY/gTMStt i6GwU24crHxkP6eQgSu5yMlyJdTqQQUpdFEol06zwcFS9DXnCQJMraQEp2aH26y4mbInQT /gmDvJQo2cXQ6ycc+ZoUkMt56nVm6zY= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1748293785; a=rsa-sha256; cv=none; b=KhMdMAuUxs65+deTkbHv6aZhnEy1BMt3hTBFJODS2KtNQs6Gk427tF0sOI7iG4Nu0ghLiv 91zx1BkV0fHPtXmOGZThLoUNEbXWSOLOebQ4RZdRZRu09cMPQqv6bJ5KLcVOaHfnquQcvE 7WriOl+UnLbRN5jWjuNHixUCrXtMdAE= ARC-Authentication-Results: i=1; imf15.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=elTcgBEM; dmarc=pass (policy=quarantine) header.from=kernel.org; spf=pass (imf15.hostedemail.com: domain of sj@kernel.org designates 172.234.252.31 as permitted sender) smtp.mailfrom=sj@kernel.org Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sea.source.kernel.org (Postfix) with ESMTP id 91B2B4A4AE; Mon, 26 May 2025 21:09:44 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4699CC4CEE7; Mon, 26 May 2025 21:09:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1748293784; bh=99xhNIYjrRRHYJ4jwFEOfM7WQzxpqK4uF5YCwTKBiUU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=elTcgBEM0yQs3NazQgBkA22UjHhWMla8mf0W/YUXruLw5IfIMCPMBEkfcC4pbGNUu 8x6uZkzZsCFu20h1k21YhN9GDrbWSGWvVj9TJFpjWBeevTMJfRuh4WQJ5Iu3Grc+ao jwi/8tV2Q28N28vuxhlQCGG6gagRE1PHgflmb6+lncdSRn4ZUU5JDQXQ23fwiWySbq oU86JkB1np33KdTdKRM9IvF12RrV3I9TohfeQqgBSpXbh5ovbRKSGf3hYElcQovMYY LTMnIr1gXBhnp3tWWOXCBM2OcqaorTy4rlX1WOVeL42d2uNrHrnDYHUlGWk34qGO9A mOtEZp7F/BjaA== From: SeongJae Park To: Andrew Morton Cc: SeongJae Park , damon@lists.linux.dev, kernel-team@meta.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH 3/4] mm/damon/stat: calculate and expose idle time percentiles Date: Mon, 26 May 2025 14:09:35 -0700 Message-Id: <20250526210936.2744-4-sj@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250526210936.2744-1-sj@kernel.org> References: <20250526210936.2744-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: 8E2F6A0007 X-Stat-Signature: 53m3wqmcfyfa6conhzjsiufj8kmq6dtz X-Rspam-User: X-HE-Tag: 1748293785-579298 X-HE-Meta: U2FsdGVkX19mTWbxWcRvFZaucNI15Nqsk/8SYwQPgUlaJj3YDbwpD50Ru/ej2CI9tWZ6uU4ZB4Sk4waDXxyPVH5PqEfCLoHmuw2TuZvPpnrixf6X6Z/9Gosk7Ob72hq5gLBzKQ/R6EkqGbgCYq1FKHINYOnS7USmyKxbabJtOPCckQG6aVMm+mGpRr/10H06kROszp3Y2nEabOffrPfS5FEV3WE18XNVVvyr55qrFgrYJpyfdIisuzGWiG9XtlCtuYKRofuitXfvkp05L0iebILOjVsqjv+I09PGNUKenXWhble8oeBmJoGutR3PBW54jjpZb72PL//4y7HOjmsL4Skv3lbZBQ0cpJa5GQ6r5ihFTaE1QT3rthZPuni8V0eOEsjYbj6nWMrh+6TiXWSOo4MufCx6B8AWB9D8Hs3Cxm9EbJF1bEqwkzuTZHhuZKhiAf40Qrr3zEfwbCU67OQvCybA5FRJZeImTnDhRjaXLLoID5Uay/0b664TEMKGo0pBXyXoyGeGf4rvxG6Wtr5IzZr4HUAMqnMpf34GdV0l9IYGBTiE2XREaWem6CYX0EAHw0fprgAzMwdGEenbEuGxdejFXv69OikKL4Rq4lD+0Ygnn1RbUDss6aGSSfeRQIcCGA8kdz9YcyPntc0y340HFglDfDf/D9oczlhLAACvm8FqaPl4K+98Om7EajtpWq3QFS46Y8nwtUIo9Hsp8MFhp8wZgVSJyK8G630XnnYD1ri88qr4dISGpsSZPT5OpcwXl+toWqlE0rRghvo8OyFPrPXDiZYL5w3r18l8yfHMwZ7c0FQMBJ1YttEPCExZ1gKFcHVs6dVw1BbPSWrKr9HuY35hmSJIGmYM+GbJV+P7AVJqOo49f/uvh+BwMw9hjjqcTegyaEQa1qZQHcdIedtUcY0n8XE6gN733vGYAm1ZmfSTqMVOEn/ETIZ/MccD/SMesCeSi58jUpEiyQY3zi3 yB6XuQBu Cb/BvEIqgzlSgLax4bqin8emT+cbYWEkYDezkTQl3eFErRUYTzF+DWci0W8Vi+uRawRLDMmelSuJooJM2JocU8mWFTwMOzl1It3rxSClofjNjyIfDSiVPeTQl7k2pfUaCgJCEAnN5WhAPjJAJrprDHx6jRv6vPUdpdCBDelNMi2vHndCOr8xsiNBsczz9rA0ZzeUGcHpupDH+brEhINV+8aUOsxXw8IJs/UP7jvyqsXyNtEsenj9civQrcEu/6PsjSXfpQ0E0DBuf1B8= 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 is 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 calculated as follows. 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 the 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 on 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, the idle time percentiles can be used to find a 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