From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 6EE43280309; Sun, 5 Apr 2026 15:12:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775401957; cv=none; b=lEyiqzHAWAO3hSKg/Wzm9Ki3VNFFsVBUml+gmW+yZI+R6AGMrhfpD13k37970c7D9p8sVB1zyiyOVvOiBbTCmXf2U4Pk77wlbwvP3djC9pJzt2x6OwNESlnjxeXLPAY9ah0+CQMm9aAWIk60tJ1vRyByYLdi6YQHOmb7RkjUyFE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775401957; c=relaxed/simple; bh=9Nwo+bW0ZeePwq2iK6IWWxk1khfaf4AjvqsrcmsSnWo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gBvPSln+ydvfDT0cT0Ylp/tJtLQ82mu4PpYyY6C0nOQBG7cockczUItyo1+20Qy/3LV8QJPlQUJxujCAX/VcXWJ86j6ELNXrT7+l7U6P9DmVfCfex5GjY4FCT5honUsyh2g3v91XhtHnEQXmwG2vCeQ7hrRklXAc8pQyxWowFTc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=AnFboUzK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="AnFboUzK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 222D9C2BCB0; Sun, 5 Apr 2026 15:12:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1775401957; bh=9Nwo+bW0ZeePwq2iK6IWWxk1khfaf4AjvqsrcmsSnWo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AnFboUzKa6Jy5pP3gMeQgWFk9sXZwGRiVVQKmGf1UbLYkAsibRq/XKPUwbVsVDGo3 tilB5M5yv8RjXOg0ksSydC+WQcdxLsYBGC5RQOfTUnAXJBvUyfDUj7xA7uyWgpkfzw mALAk1fj8YPEb8ADsh2mFbtTC/jXzv2LrdeCj7+uJkZcyWRwLlQ6HC7TFvgBn18vpf rd/bMnHHOOJzuIEzwGK16Xtmnw3UOp5tZqApuN6NEuG5Mlo8qNjqPY/thNajYUBWWs gE1cQlczKN7Vr1HXT+T1MYfmCISNQxj2bIPuOKQSTb7URMaCMwowV4JEXA4tFIyyZW J8AUjkHj/odmg== From: SeongJae Park To: Cc: SeongJae Park , Andrew Morton , damon@lists.linux.dev, linux-kernel@vger.kernel.org, linux-mm@kvack.org Subject: [RFC PATCH v2 1/9] mm/damon/core: introduce failed region quota charge ratio Date: Sun, 5 Apr 2026 08:12:19 -0700 Message-ID: <20260405151232.102690-2-sj@kernel.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260405151232.102690-1-sj@kernel.org> References: <20260405151232.102690-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 DAMOS quota is charged to all DAMOS action application attempted memory, regardless of how much of the memory the action was successful and failed. This makes understanding quota behavior without DAMOS stat but only with end level metrics (e.g., increased amount of free memory for DAMOS_PAGEOUT action) difficult. Also, charging action-failed memory same as action-successful memory is somewhat unfair, as successful action application will induce more overhead in most cases. Introduce DAMON core API for setting the charge ratio for such action-failed memory. It allows API callers to specify the ratio in a flexible way, by setting the numerator and the denominator. Signed-off-by: SeongJae Park --- include/linux/damon.h | 9 +++++++++ mm/damon/core.c | 21 ++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/linux/damon.h b/include/linux/damon.h index 4b69f4553267d..9ab7331775b9e 100644 --- a/include/linux/damon.h +++ b/include/linux/damon.h @@ -233,6 +233,8 @@ enum damos_quota_goal_tuner { * @goals: Head of quota tuning goals (&damos_quota_goal) list. * @goal_tuner: Goal-based @esz tuning algorithm to use. * @esz: Effective size quota in bytes. + * @fail_charge_num: Failed regions charge rate numerator. + * @fail_charge_denom: Failed regions charge rate denominator. * * @weight_sz: Weight of the region's size for prioritization. * @weight_nr_accesses: Weight of the region's nr_accesses for prioritization. @@ -262,6 +264,10 @@ enum damos_quota_goal_tuner { * * The resulting effective size quota in bytes is set to @esz. * + * For DAMOS action applying failed amount of regions, charging those same to + * those that the action has successfully applied may be unfair. For the + * reason, 'the size * @fail_charge_num / @fail_charge_denom' is charged. + * * For selecting regions within the quota, DAMON prioritizes current scheme's * target memory regions using the &struct damon_operations->get_scheme_score. * You could customize the prioritization logic by setting &weight_sz, @@ -276,6 +282,9 @@ struct damos_quota { enum damos_quota_goal_tuner goal_tuner; unsigned long esz; + unsigned int fail_charge_num; + unsigned int fail_charge_denom; + unsigned int weight_sz; unsigned int weight_nr_accesses; unsigned int weight_age; diff --git a/mm/damon/core.c b/mm/damon/core.c index fe5a4a8d5b294..fdeab474b7456 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -918,6 +918,8 @@ static int damos_commit_quota(struct damos_quota *dst, struct damos_quota *src) if (err) return err; dst->goal_tuner = src->goal_tuner; + dst->fail_charge_num = src->fail_charge_num; + dst->fail_charge_denom = src->fail_charge_denom; dst->weight_sz = src->weight_sz; dst->weight_nr_accesses = src->weight_nr_accesses; dst->weight_age = src->weight_age; @@ -2042,6 +2044,23 @@ static void damos_walk_cancel(struct damon_ctx *ctx) mutex_unlock(&ctx->walk_control_lock); } +static void damos_charge_quota(struct damos_quota *quota, + unsigned long sz_region, unsigned long sz_applied) +{ + /* + * sz_applied could be bigger than sz_region, depending on ops + * implementation of the action, e.g., damos_pa_pageout(). Charge only + * the region size in the case. + */ + if (!quota->fail_charge_denom || sz_applied > sz_region) + quota->charged_sz += sz_region; + else + quota->charged_sz += sz_applied + mult_frac( + (sz_region - sz_applied), + quota->fail_charge_num, + quota->fail_charge_denom); +} + static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t, struct damon_region *r, struct damos *s) { @@ -2098,7 +2117,7 @@ static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t, ktime_get_coarse_ts64(&end); quota->total_charged_ns += timespec64_to_ns(&end) - timespec64_to_ns(&begin); - quota->charged_sz += sz; + damos_charge_quota(quota, sz, sz_applied); if (damos_quota_is_set(quota) && quota->charged_sz >= quota->esz) { quota->charge_target_from = t; -- 2.47.3