From nobody Fri Jan 2 18:49:11 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F721CD68E6 for ; Tue, 10 Oct 2023 01:26:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1379289AbjJJB0N (ORCPT ); Mon, 9 Oct 2023 21:26:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59182 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1379251AbjJJB0I (ORCPT ); Mon, 9 Oct 2023 21:26:08 -0400 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 205D291 for ; Mon, 9 Oct 2023 18:26:07 -0700 (PDT) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 50667C433C8; Tue, 10 Oct 2023 01:26:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1696901166; bh=tkpBuPAHcXxVtnYMQEIhabnoxptCyM9g6IJhkHy1SMg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tAWQTp/K52moV1cPuIjdEwQJ611H9Xy78nBYCj90TW3I4Ov5uPdLOFPNqJYK3VXAw +Ll4igPCl10aeRmwGmu+DHjgv08wOmOQnBGquWSiyOwjVkyU5kwz6VG35hAUTxFH8K f8KTLiado7LKukenztqwf8o17fVXIAEb73doXRJgHbgOTxzJN4mVRFatJlxSjI7Bxk qR1+S0Y6NMcIOJdjIMZL7PrPU7rS0HH/3Wh/0Le67RiElATC2oJrBpt8heZ6JaVPDS TVZCQHhFbEQqHjYysEhkeyr2R2d810evFOuASv+otwr6W4Jx3TF3+7v9YBY7zHqMjB uV1ETgeQCVyxw== From: SeongJae Park Cc: SeongJae Park , Andrew Morton , damon@lists.linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 1/3] mm/damon/sysfs-schemes: do not update tried regions more than one DAMON snapshot Date: Tue, 10 Oct 2023 01:25:58 +0000 Message-Id: <20231010012600.83140-2-sj@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231010012600.83140-1-sj@kernel.org> References: <20231010012600.83140-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable To: unlisted-recipients:; (no To-header on input) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" DAMON_SYSFS exposes every DAMON-found region that eligible for applying the scheme action for one aggregation interval. However, each DAMON-based operation scheme has its own apply interval. Hence, for a scheme that having its apply interval much smaller than the aggregation interval, DAMON_SYSFS will expose the scheme regions that applied to more than one DAMON monitoring results snapshots. Since the purpose of DAMON tried regions is exposing single snapshot, this makes no much sense. Track progress of each scheme's tried regions update and avoid the case. Signed-off-by: SeongJae Park --- mm/damon/sysfs-schemes.c | 77 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c index a7d70b95c4dd..b07a5c544b34 100644 --- a/mm/damon/sysfs-schemes.c +++ b/mm/damon/sysfs-schemes.c @@ -113,11 +113,47 @@ static const struct kobj_type damon_sysfs_scheme_regi= on_ktype =3D { * scheme regions directory */ =20 +/* + * enum damos_sysfs_regions_upd_status - Represent DAMOS tried regions upd= ate + * status + * @DAMOS_TRIED_REGIONS_UPD_IDLE: Waiting for next request. + * @DAMOS_TRIED_REGIONS_UPD_STARTED: Update started. + * @DAMOS_TRIED_REGIONS_UPD_FINISHED: Update finished. + * + * Each DAMON-based operation scheme (&struct damos) has its own apply + * interval, and we need to expose the scheme tried regions based on only + * single snapshot. For this, we keep the tried regions update status for= each + * scheme. The status becomes 'idle' at the beginning. + * + * Once the tried regions update request is received, the request handling + * start function (damon_sysfs_scheme_update_regions_start()) sets the sta= tus + * of all schemes as 'idle' again, and register ->before_damos_apply() and + * ->after_sampling() callbacks. + * + * Then, the first followup ->before_damos_apply() callback + * (damon_sysfs_before_damos_apply()) sets the status 'started'. The first + * ->after_sampling() callback (damon_sysfs_after_sampling()) after the ca= ll + * is called only after the scheme is completely applied + * to the given snapshot. Hence the callback knows the situation by showi= ng + * 'started' status, and sets the status as 'finished'. Then, + * damon_sysfs_before_damos_apply() understands the situation by showing t= he + * 'finished' status and do nothing. + * + * Finally, the tried regions request handling finisher function + * (damon_sysfs_schemes_update_regions_stop()) unregisters the callbacks. + */ +enum damos_sysfs_regions_upd_status { + DAMOS_TRIED_REGIONS_UPD_IDLE, + DAMOS_TRIED_REGIONS_UPD_STARTED, + DAMOS_TRIED_REGIONS_UPD_FINISHED, +}; + struct damon_sysfs_scheme_regions { struct kobject kobj; struct list_head regions_list; int nr_regions; unsigned long total_bytes; + enum damos_sysfs_regions_upd_status upd_status; }; =20 static struct damon_sysfs_scheme_regions * @@ -130,6 +166,7 @@ damon_sysfs_scheme_regions_alloc(void) INIT_LIST_HEAD(®ions->regions_list); regions->nr_regions =3D 0; regions->total_bytes =3D 0; + regions->upd_status =3D DAMOS_TRIED_REGIONS_UPD_IDLE; return regions; } =20 @@ -1777,6 +1814,10 @@ static int damon_sysfs_before_damos_apply(struct dam= on_ctx *ctx, return 0; =20 sysfs_regions =3D sysfs_schemes->schemes_arr[schemes_idx]->tried_regions; + if (sysfs_regions->upd_status =3D=3D DAMOS_TRIED_REGIONS_UPD_FINISHED) + return 0; + if (sysfs_regions->upd_status =3D=3D DAMOS_TRIED_REGIONS_UPD_IDLE) + sysfs_regions->upd_status =3D DAMOS_TRIED_REGIONS_UPD_STARTED; sysfs_regions->total_bytes +=3D r->ar.end - r->ar.start; if (damos_regions_upd_total_bytes_only) return 0; @@ -1793,6 +1834,29 @@ static int damon_sysfs_before_damos_apply(struct dam= on_ctx *ctx, return 0; } =20 +/* + * DAMON callback that called after each accesses sampling. While this + * callback is registered, damon_sysfs_lock should be held to ensure the + * regions directories exist. + */ +static int damon_sysfs_after_sampling(struct damon_ctx *ctx) +{ + struct damon_sysfs_schemes *sysfs_schemes =3D + damon_sysfs_schemes_for_damos_callback; + struct damon_sysfs_scheme_regions *sysfs_regions; + int i; + + for (i =3D 0; i < sysfs_schemes->nr; i++) { + sysfs_regions =3D sysfs_schemes->schemes_arr[i]->tried_regions; + if (sysfs_regions->upd_status =3D=3D + DAMOS_TRIED_REGIONS_UPD_STARTED) + sysfs_regions->upd_status =3D + DAMOS_TRIED_REGIONS_UPD_FINISHED; + } + + return 0; +} + /* Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock */ int damon_sysfs_schemes_clear_regions( struct damon_sysfs_schemes *sysfs_schemes, @@ -1816,6 +1880,16 @@ int damon_sysfs_schemes_clear_regions( return 0; } =20 +static void damos_tried_regions_init_upd_status( + struct damon_sysfs_schemes *sysfs_schemes) +{ + int i; + + for (i =3D 0; i < sysfs_schemes->nr; i++) + sysfs_schemes->schemes_arr[i]->tried_regions->upd_status =3D + DAMOS_TRIED_REGIONS_UPD_IDLE; +} + /* Called from damon_sysfs_cmd_request_callback under damon_sysfs_lock */ int damon_sysfs_schemes_update_regions_start( struct damon_sysfs_schemes *sysfs_schemes, @@ -1823,8 +1897,10 @@ int damon_sysfs_schemes_update_regions_start( { damon_sysfs_schemes_clear_regions(sysfs_schemes, ctx); damon_sysfs_schemes_for_damos_callback =3D sysfs_schemes; + damos_tried_regions_init_upd_status(sysfs_schemes); damos_regions_upd_total_bytes_only =3D total_bytes_only; ctx->callback.before_damos_apply =3D damon_sysfs_before_damos_apply; + ctx->callback.after_sampling =3D damon_sysfs_after_sampling; return 0; } =20 @@ -1837,6 +1913,7 @@ int damon_sysfs_schemes_update_regions_stop(struct da= mon_ctx *ctx) { damon_sysfs_schemes_for_damos_callback =3D NULL; ctx->callback.before_damos_apply =3D NULL; + ctx->callback.after_sampling =3D NULL; damon_sysfs_schemes_region_idx =3D 0; return 0; } --=20 2.34.1