From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1B2613D904C; Tue, 30 Jun 2026 04:08:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782792505; cv=none; b=JA+Vu91XsIjsedNvYLQT0vzE6VX0JJT7Wl5BdTjzY12UsF0/Pgcbu9IwdqaQNvGPCdR10tNLQCBC4Xr6UfxWK7GJ/kRbhoMYAB7kGe9PnF+XkMMMgcAOJDF9k7X/qNf8L0LNcRA6yR5U+yTUDPk4V7c+a7uKb9P+K6voEBCnzkc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782792505; c=relaxed/simple; bh=FPOmjiNJEkjAThxGmx/NhlS7shxz11oYSp27Oy29c3Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jnHlm8WrjeQMEGt8uNPUG7jrs3Ufyx6nbQVtK3izIfzM8p6y/GQoJBmm5f5d5vHIplHqwQXaP2pgzEQwzcpXEiMhMi0oWlLxViyDleA97kVs+cj9T/E8yTaJmKkc1wEqRd1RF/c+204kQFPdJGjIPHW2tDMydjKBY5xgJhLATEU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=daSBI9Hr; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="daSBI9Hr" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B164F1F00A3A; Tue, 30 Jun 2026 04:08:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1782792503; bh=d/qJVmkjnHPk0hozesPjKLZL3BJIw61bUZ5bJBqe7d4=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=daSBI9HrmyqkDwzZBeMKIn0SiydZ//+l5bANvKsMwAahTNNQThsCKwWIRZr56UAfh 0ffWQr++O/IQOCoI/P6umplCSR5xRBN50OaHpJOxOf59okKUCr7klz2IiVoiFuxIPw 1z+n6Uw4oP9GS7tVjWn0YhmjJCxZMkYkeJrGBzZhD0+XOEfo6/sod9p3wLDmwLPCZ3 9h4xPECmR0I9GisBhI5NGJWFq3ZlBdNU5sCyOOQ4Q2Umx5AVIsGkthEcfP8moHMJPm JO+eXwEF6R8ZkcTpkBwoQjK7r07u5OgFgVwbFCeYtfCAGIrwOPhOLRfq5cs4yfPMAD 28COhHE4yat4w== From: SJ Park To: Andrew Morton Cc: SJ Park , damon@lists.linux.dev, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [PATCH 01/18] mm/damon/core: introduce damon_nr_accesses_mvsum() Date: Mon, 29 Jun 2026 21:07:54 -0700 Message-ID: <20260630040812.149729-2-sj@kernel.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260630040812.149729-1-sj@kernel.org> References: <20260630040812.149729-1-sj@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Introduce a new DAMON core function, damon_nr_accesses_mvsum(). It returns a pseudo moving sum value of a given region's nr_accesses for the last aggregation interval. The internal logic is the same to nr_accesses_bp. The difference is that nr_accesses_bp is updated for each sampling interval, while the new function needs to be executed only when requested. Hence the function's return value is the same as the value of nr_accesses_bp. Signed-off-by: SJ Park --- include/linux/damon.h | 2 ++ mm/damon/core.c | 62 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/include/linux/damon.h b/include/linux/damon.h index cfbbf8ba28f63..87c1ff479da82 100644 --- a/include/linux/damon.h +++ b/include/linux/damon.h @@ -1011,6 +1011,8 @@ struct damon_probe *damon_new_probe(void); void damon_add_probe(struct damon_ctx *ctx, struct damon_probe *probe); struct damon_region *damon_new_region(unsigned long start, unsigned long end); +unsigned int damon_nr_accesses_mvsum(struct damon_region *r, + struct damon_ctx *ctx); int damon_set_regions(struct damon_target *t, struct damon_addr_range *ranges, unsigned int nr_ranges, unsigned long min_region_sz); diff --git a/mm/damon/core.c b/mm/damon/core.c index 972a19fcee3ec..c588f943080f9 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -208,6 +208,68 @@ static struct damon_probe *damon_nth_probe(int n, struct damon_ctx *ctx) return NULL; } +/* + * damon_mvsum() - Returns pseudo moving sum value for a time window. + * @current_nr: The value of the current aggregation window. + * @last_nr: The value of the last aggregation window. + * @left_window_bp: Left time of the current aggregation window. + * + * This function calculates a pseudo moving sum value of a counter that is + * aggregated for each time window. @current_nr is the value of the counter + * that aggregated so far (maybe not yet complete), from the beginning of the + * current aggregation time window. @last_nr is the value of the counter that + * has completely aggregated in the last aggregation time window. + * @left_window_bp represents how much time is left for the current aggregation + * time window in bp (1/10,000). For example, the aggregation time window is + * for every 10 seconds and 7 seconds has passed since the beginning of the + * current window, this parameter will be 3000 ((10 - 7) / 10 * 10000). + * + * The logic assumes the aggregation in the last phase was made in a single + * speed. Based on the assumption, the value from the last window that needs + * to be added to the current value is calculated as a portion of the last + * value based on the remaining time window. + */ +static unsigned long damon_mvsum(unsigned long current_nr, + unsigned long last_nr, unsigned long left_window_bp) +{ + return current_nr + mult_frac(last_nr, left_window_bp, 10000); +} + +/** + * damon_nr_accesses_mvsum() - Returns moving sum access frequency score. + * @r: Region to get the access frequency of. + * @ctx: DAMON context of @r. + * + * This function returns for how many sampling iterations in the last + * aggregation interval (&damon_attrs->aggr_interval) the region was found to + * be accessed. Hence the value can be interpreted as the relative access + * frequency score of the region (@r). The value is calculated as a pseudo + * moving sum, and hence it is not an exact value but just a best-effort + * reasonable estimation. + * + * Return: the pseudo moving sum access frequency score. + */ +unsigned int damon_nr_accesses_mvsum(struct damon_region *r, + struct damon_ctx *ctx) +{ + unsigned long sample_interval, aggr_interval; + unsigned long window_len, left_window, left_window_bp; + + sample_interval = ctx->attrs.sample_interval ? : 1; + aggr_interval = ctx->attrs.aggr_interval ? : 1; + window_len = aggr_interval / sample_interval; + if (time_after_eq(ctx->passed_sample_intervals, + ctx->next_aggregation_sis)) + left_window = 0; + else + left_window = ctx->next_aggregation_sis - + ctx->passed_sample_intervals; + left_window_bp = mult_frac(left_window, 10000, window_len); + + return damon_mvsum(r->nr_accesses, r->last_nr_accesses, + left_window_bp); +} + #ifdef CONFIG_DAMON_DEBUG_SANITY static void damon_verify_new_region(unsigned long start, unsigned long end) { -- 2.47.3