From nobody Sat Oct 4 22:39:30 2025 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) (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 2A2772BE7CF for ; Wed, 13 Aug 2025 03:52:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755057165; cv=none; b=crFQxvtcW5Qc6QxtvqGluKjqDYcz5Nop+ZwJuhUnWRzXlIxyKf+4Zp03DKxM5VypFbMw0+RaNW2CtdrJIks3R4yZ1fHqbLjxwa0wvbLJYSIWCRPId8Qw3shopk+SlbVTc2/cnKOSy1u8593t5QWyqTKX/wssdlBCzrr9jR7TcK4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755057165; c=relaxed/simple; bh=K8zueaRJo3gNUjC+lIEOH6g3TS9WguEf58BxphKiDew=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CZqpqh800qTtVnGaypPvF8dy9xYMXumyyP9tNcLIFYQEKmINMfWkP/tR7SZdRP8OdOR66zOextlJQ3rrjKXy8GnedrpIyoNOCYtxsFpoMb0WX2EVYOb+tI8s2CluEXMdNhAK+27jS5xVWgqeJ3UlvkKR++rbw67o+mkVyKY99t0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.188 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.163.48]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4c1vZ21RvTztTBG; Wed, 13 Aug 2025 11:51:38 +0800 (CST) Received: from dggpemf200018.china.huawei.com (unknown [7.185.36.31]) by mail.maildlp.com (Postfix) with ESMTPS id 70073180064; Wed, 13 Aug 2025 11:52:38 +0800 (CST) Received: from huawei.com (10.175.113.32) by dggpemf200018.china.huawei.com (7.185.36.31) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Wed, 13 Aug 2025 11:52:37 +0800 From: Quanmin Yan To: CC: , , , , , , Subject: [RFC PATCH -next 12/16] mm/damon: add damon_ctx->min_region and damon_target->min_region Date: Wed, 13 Aug 2025 13:07:02 +0800 Message-ID: <20250813050706.1564229-13-yanquanmin1@huawei.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250813050706.1564229-1-yanquanmin1@huawei.com> References: <20250813050706.1564229-1-yanquanmin1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To dggpemf200018.china.huawei.com (7.185.36.31) Content-Type: text/plain; charset="utf-8" Adopting addr_unit would make DAMON_MINREGION 'addr_unit * 4096' bytes and cause data alignment issues[1]. Add damon_ctx->min_region to change DAMON_MIN_REGION from a global macro value to per-context variable, let target inherit the min_region from its associated ctx to avoid excessive passing of ctx. [1] https://lore.kernel.org/all/527714dd-0e33-43ab-bbbd-d89670ba79e7@huawei= .com Signed-off-by: Quanmin Yan --- include/linux/damon.h | 7 ++++++- mm/damon/core.c | 41 +++++++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/include/linux/damon.h b/include/linux/damon.h index 1b7b4cf1a3c5..aa045dcb5b5d 100644 --- a/include/linux/damon.h +++ b/include/linux/damon.h @@ -88,6 +88,7 @@ struct damon_region { /** * struct damon_target - Represents a monitoring target. * @pid: The PID of the virtual address space to monitor. + * @min_region: Minimum Region Size. * @nr_regions: Number of monitoring target regions of this target. * @regions_list: Head of the monitoring target regions of this target. * @list: List head for siblings. @@ -95,10 +96,12 @@ struct damon_region { * Each monitoring context could have multiple targets. For example, a co= ntext * for virtual memory address spaces could have multiple target processes.= The * @pid should be set for appropriate &struct damon_operations including t= he - * virtual address spaces monitoring operations. + * virtual address spaces monitoring operations. The @min_region Keeps con= sistent + * with the associated monitoring context. */ struct damon_target { struct pid *pid; + unsigned long min_region; unsigned int nr_regions; struct list_head regions_list; struct list_head list; @@ -747,6 +750,7 @@ struct damon_attrs { * * @ops: Set of monitoring operations for given use cases. * @addr_unit: Scale factor for core to ops address conversion. + * @min_region: Minimum Region Size. * @adaptive_targets: Head of monitoring targets (&damon_target) list. * @schemes: Head of schemes (&damos) list. */ @@ -789,6 +793,7 @@ struct damon_ctx { =20 struct damon_operations ops; unsigned long addr_unit; + unsigned long min_region; =20 struct list_head adaptive_targets; struct list_head schemes; diff --git a/mm/damon/core.c b/mm/damon/core.c index 803c30f64b94..b162aa1156fc 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -245,16 +245,16 @@ int damon_set_regions(struct damon_target *t, struct = damon_addr_range *ranges, /* no region intersects with this range */ newr =3D damon_new_region( ALIGN_DOWN(range->start, - DAMON_MIN_REGION), - ALIGN(range->end, DAMON_MIN_REGION)); + t->min_region), + ALIGN(range->end, t->min_region)); if (!newr) return -ENOMEM; damon_insert_region(newr, damon_prev_region(r), r, t); } else { /* resize intersecting regions to fit in this range */ first->ar.start =3D ALIGN_DOWN(range->start, - DAMON_MIN_REGION); - last->ar.end =3D ALIGN(range->end, DAMON_MIN_REGION); + t->min_region); + last->ar.end =3D ALIGN(range->end, t->min_region); =20 /* fill possible holes in the range */ err =3D damon_fill_regions_holes(first, last, t); @@ -472,6 +472,7 @@ struct damon_target *damon_new_target(void) =20 t->pid =3D NULL; t->nr_regions =3D 0; + t->min_region =3D DAMON_MIN_REGION; INIT_LIST_HEAD(&t->regions_list); INIT_LIST_HEAD(&t->list); =20 @@ -480,6 +481,7 @@ struct damon_target *damon_new_target(void) =20 void damon_add_target(struct damon_ctx *ctx, struct damon_target *t) { + t->min_region =3D ctx->min_region; list_add_tail(&t->list, &ctx->adaptive_targets); } =20 @@ -545,6 +547,7 @@ struct damon_ctx *damon_new_ctx(void) ctx->attrs.max_nr_regions =3D 1000; =20 ctx->addr_unit =3D 1; + ctx->min_region =3D DAMON_MIN_REGION; =20 INIT_LIST_HEAD(&ctx->adaptive_targets); INIT_LIST_HEAD(&ctx->schemes); @@ -1181,6 +1184,14 @@ static int damon_commit_targets( return 0; } =20 +static void damon_sync_target_min_region(struct damon_ctx *ctx) +{ + struct damon_target *t; + + damon_for_each_target(t, ctx) + t->min_region =3D ctx->min_region; +} + /** * damon_commit_ctx() - Commit parameters of a DAMON context to another. * @dst: The commit destination DAMON context. @@ -1216,6 +1227,8 @@ int damon_commit_ctx(struct damon_ctx *dst, struct da= mon_ctx *src) return err; dst->ops =3D src->ops; dst->addr_unit =3D src->addr_unit ? : 1; + dst->min_region =3D max(DAMON_MIN_REGION / dst->addr_unit, 1); + damon_sync_target_min_region(dst); =20 return 0; } @@ -1248,8 +1261,8 @@ static unsigned long damon_region_sz_limit(struct dam= on_ctx *ctx) =20 if (ctx->attrs.min_nr_regions) sz /=3D ctx->attrs.min_nr_regions; - if (sz < DAMON_MIN_REGION) - sz =3D DAMON_MIN_REGION; + if (sz < ctx->min_region) + sz =3D ctx->min_region; =20 return sz; } @@ -1632,11 +1645,11 @@ static bool damos_skip_charged_region(struct damon_= target *t, if (quota->charge_addr_from && r->ar.start < quota->charge_addr_from) { sz_to_skip =3D ALIGN_DOWN(quota->charge_addr_from - - r->ar.start, DAMON_MIN_REGION); + r->ar.start, t->min_region); if (!sz_to_skip) { - if (damon_sz_region(r) <=3D DAMON_MIN_REGION) + if (damon_sz_region(r) <=3D t->min_region) return true; - sz_to_skip =3D DAMON_MIN_REGION; + sz_to_skip =3D t->min_region; } damon_split_region_at(t, r, sz_to_skip); r =3D damon_next_region(r); @@ -1678,8 +1691,8 @@ static bool damos_filter_match(struct damon_ctx *ctx,= struct damon_target *t, matched =3D target_idx =3D=3D filter->target_idx; break; case DAMOS_FILTER_TYPE_ADDR: - start =3D ALIGN_DOWN(filter->addr_range.start, DAMON_MIN_REGION); - end =3D ALIGN_DOWN(filter->addr_range.end, DAMON_MIN_REGION); + start =3D ALIGN_DOWN(filter->addr_range.start, t->min_region); + end =3D ALIGN_DOWN(filter->addr_range.end, t->min_region); =20 /* inside the range */ if (start <=3D r->ar.start && r->ar.end <=3D end) { @@ -1850,7 +1863,7 @@ static void damos_apply_scheme(struct damon_ctx *c, s= truct damon_target *t, if (c->ops.apply_scheme) { if (quota->esz && quota->charged_sz + sz > quota->esz) { sz =3D ALIGN_DOWN(quota->esz - quota->charged_sz, - DAMON_MIN_REGION); + c->min_region); if (!sz) goto update_stat; damon_split_region_at(t, r, sz); @@ -2302,13 +2315,13 @@ static void damon_split_regions_of(struct damon_tar= get *t, int nr_subs) sz_region =3D damon_sz_region(r); =20 for (i =3D 0; i < nr_subs - 1 && - sz_region > 2 * DAMON_MIN_REGION; i++) { + sz_region > 2 * t->min_region; i++) { /* * Randomly select size of left sub-region to be at * least 10 percent and at most 90% of original region */ sz_sub =3D ALIGN_DOWN(damon_rand(1, 10) * - sz_region / 10, DAMON_MIN_REGION); + sz_region / 10, t->min_region); /* Do not allow blank region */ if (sz_sub =3D=3D 0 || sz_sub >=3D sz_region) continue; --=20 2.34.1