From nobody Wed Apr 8 07:59:16 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 1189DFA373E for ; Wed, 26 Oct 2022 23:00:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233965AbiJZXAD (ORCPT ); Wed, 26 Oct 2022 19:00:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40936 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233946AbiJZW76 (ORCPT ); Wed, 26 Oct 2022 18:59:58 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3AEA26558 for ; Wed, 26 Oct 2022 15:59:52 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 39CA8B82473 for ; Wed, 26 Oct 2022 22:59:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7A973C433B5; Wed, 26 Oct 2022 22:59:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825189; bh=PcpzlnNHZWtuE8/7HVnA2SeaMVIQ6XHWVj8vUJ1ZrF4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lRniJU/9ikWpyMRR5kfjgU/6Iqe32PXn0o8jXqKhZolqSUOL6HEenaGW3obcwZEyZ ufRoarBtPKYdazvBBO4J4gqrFYNmg1QOcFolHNHL1vfvd5J/VnXK97cZPvcjJuH9tq 2VQBajLilWdf5g8PTKhxX7S8lRiOGISlVxGh1mrqP/5i/kJEHSfr633CYOYblvKrgu VVFj2q/MDA8hq8R7Ka2PJelPuGw/AwgYXp5YUZ7w5vthBWlPuouiB9i9qYzIrXBGmE NrB2LowcimyC2ELjFifkgsNJbkQgkismBiW85BYvRgRbFWX8ZXxy4om7MQw9nrtNL6 kjwOlB50TEX1Q== From: SeongJae Park To: Andrew Morton Cc: damon@lists.linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, SeongJae Park Subject: [PATCH v2 01/12] mm/damon/core: split out DAMOS-charged region skip logic into a new function Date: Wed, 26 Oct 2022 22:59:32 +0000 Message-Id: <20221026225943.100429-2-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The DAMOS action applying function, 'damon_do_apply_schemes()', is quite long and not so simple. Split out the already quota-charged region skip code, which is not a small amount of simple code, into a new function with some comments for better readability. Signed-off-by: SeongJae Park Signed-off-by: Andrew Morton --- mm/damon/core.c | 96 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index 36d098d06c55..06b50ede9cc6 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -694,6 +694,67 @@ static bool damos_valid_target(struct damon_ctx *c, st= ruct damon_target *t, return c->ops.get_scheme_score(c, t, r, s) >=3D s->quota.min_score; } =20 +/* + * damos_skip_charged_region() - Check if the given region or starting par= t of + * it is already charged for the DAMOS quota. + * @t: The target of the region. + * @rp: The pointer to the region. + * @s: The scheme to be applied. + * + * If a quota of a scheme has exceeded in a quota charge window, the schem= e's + * action would applied to only a part of the target access pattern fulfil= ling + * regions. To avoid applying the scheme action to only already applied + * regions, DAMON skips applying the scheme action to the regions that cha= rged + * in the previous charge window. + * + * This function checks if a given region should be skipped or not for the + * reason. If only the starting part of the region has previously charged, + * this function splits the region into two so that the second one covers = the + * area that not charged in the previous charge widnow and saves the second + * region in *rp and returns false, so that the caller can apply DAMON act= ion + * to the second one. + * + * Return: true if the region should be entirely skipped, false otherwise. + */ +static bool damos_skip_charged_region(struct damon_target *t, + struct damon_region **rp, struct damos *s) +{ + struct damon_region *r =3D *rp; + struct damos_quota *quota =3D &s->quota; + unsigned long sz_to_skip; + + /* Skip previously charged regions */ + if (quota->charge_target_from) { + if (t !=3D quota->charge_target_from) + return true; + if (r =3D=3D damon_last_region(t)) { + quota->charge_target_from =3D NULL; + quota->charge_addr_from =3D 0; + return true; + } + if (quota->charge_addr_from && + r->ar.end <=3D quota->charge_addr_from) + return true; + + 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); + if (!sz_to_skip) { + if (damon_sz_region(r) <=3D DAMON_MIN_REGION) + return true; + sz_to_skip =3D DAMON_MIN_REGION; + } + damon_split_region_at(t, r, sz_to_skip); + r =3D damon_next_region(r); + *rp =3D r; + } + quota->charge_target_from =3D NULL; + quota->charge_addr_from =3D 0; + } + return false; +} + static void damon_do_apply_schemes(struct damon_ctx *c, struct damon_target *t, struct damon_region *r) @@ -702,7 +763,7 @@ static void damon_do_apply_schemes(struct damon_ctx *c, =20 damon_for_each_scheme(s, c) { struct damos_quota *quota =3D &s->quota; - unsigned long sz =3D damon_sz_region(r); + unsigned long sz; struct timespec64 begin, end; unsigned long sz_applied =3D 0; =20 @@ -713,41 +774,14 @@ static void damon_do_apply_schemes(struct damon_ctx *= c, if (quota->esz && quota->charged_sz >=3D quota->esz) continue; =20 - /* Skip previously charged regions */ - if (quota->charge_target_from) { - if (t !=3D quota->charge_target_from) - continue; - if (r =3D=3D damon_last_region(t)) { - quota->charge_target_from =3D NULL; - quota->charge_addr_from =3D 0; - continue; - } - if (quota->charge_addr_from && - r->ar.end <=3D quota->charge_addr_from) - continue; - - if (quota->charge_addr_from && r->ar.start < - quota->charge_addr_from) { - sz =3D ALIGN_DOWN(quota->charge_addr_from - - r->ar.start, DAMON_MIN_REGION); - if (!sz) { - if (damon_sz_region(r) <=3D - DAMON_MIN_REGION) - continue; - sz =3D DAMON_MIN_REGION; - } - damon_split_region_at(t, r, sz); - r =3D damon_next_region(r); - sz =3D damon_sz_region(r); - } - quota->charge_target_from =3D NULL; - quota->charge_addr_from =3D 0; - } + if (damos_skip_charged_region(t, &r, s)) + continue; =20 if (!damos_valid_target(c, t, r, s)) continue; =20 /* Apply the scheme */ + sz =3D damon_sz_region(r); if (c->ops.apply_scheme) { if (quota->esz && quota->charged_sz + sz > quota->esz) { --=20 2.25.1 From nobody Wed Apr 8 07:59:16 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 08D2FC433FE for ; Wed, 26 Oct 2022 23:00:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234077AbiJZXAP (ORCPT ); Wed, 26 Oct 2022 19:00:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40986 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234000AbiJZXAA (ORCPT ); Wed, 26 Oct 2022 19:00:00 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5BF2527B30 for ; Wed, 26 Oct 2022 15:59:53 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id CFEEEB82474 for ; Wed, 26 Oct 2022 22:59:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1DDA4C433D6; Wed, 26 Oct 2022 22:59:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825190; bh=pZN9MaiWJ2neRPvf8pSCjOgtf8CaxIjSAQay3UAMfX0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EeZ3udcwpEj8X7lrZ3fVW2I92ny3inV0tw5PEoCmE5DrBrNbiBmIolLrLnjW9nIbV sQK22IKfw/I3kDl331yD9KwqRdXJzsNJjgmaivdqSLkne1o05tPQx6hsSXmyIP0LQ4 /4tGEqQEtT5aNXsa+UT3HoQYnfhHsPHdIXVrcU6TfPkGPWuvhUs/hfx2UJJvQEn6sa fM6BM8F3AgBUkyJPDywH+SAp4HW7O1n6n53wSR5b1fZx2X1kD0lmr04SR/XjTnDfeA CVQWU/VDl0fZpwhmZMkxnNtEyX1a6E1T5iPAQpFfIhJ+d+kIUW1e0f1T8MnoEJWcZl vM+SKyeijktWw== From: SeongJae Park To: Andrew Morton Cc: damon@lists.linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, SeongJae Park Subject: [PATCH v2 02/12] mm/damon/core: split damos application logic into a new function Date: Wed, 26 Oct 2022 22:59:33 +0000 Message-Id: <20221026225943.100429-3-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The DAMOS action applying function, 'damon_do_apply_schemes()', is still long and not easy to read. Split out the code for applying a single action to a single region into a new function for better readability. Signed-off-by: SeongJae Park Signed-off-by: Andrew Morton --- mm/damon/core.c | 73 ++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index 06b50ede9cc6..c1a912bc46ae 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -755,6 +755,44 @@ static bool damos_skip_charged_region(struct damon_tar= get *t, return false; } =20 +static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t, + struct damon_region *r, struct damos *s) +{ + struct damos_quota *quota =3D &s->quota; + unsigned long sz =3D damon_sz_region(r); + struct timespec64 begin, end; + unsigned long sz_applied =3D 0; + + 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); + if (!sz) + goto update_stat; + damon_split_region_at(t, r, sz); + } + ktime_get_coarse_ts64(&begin); + sz_applied =3D c->ops.apply_scheme(c, t, r, s); + ktime_get_coarse_ts64(&end); + quota->total_charged_ns +=3D timespec64_to_ns(&end) - + timespec64_to_ns(&begin); + quota->charged_sz +=3D sz; + if (quota->esz && quota->charged_sz >=3D quota->esz) { + quota->charge_target_from =3D t; + quota->charge_addr_from =3D r->ar.end + 1; + } + } + if (s->action !=3D DAMOS_STAT) + r->age =3D 0; + +update_stat: + s->stat.nr_tried++; + s->stat.sz_tried +=3D sz; + if (sz_applied) + s->stat.nr_applied++; + s->stat.sz_applied +=3D sz_applied; +} + static void damon_do_apply_schemes(struct damon_ctx *c, struct damon_target *t, struct damon_region *r) @@ -763,9 +801,6 @@ static void damon_do_apply_schemes(struct damon_ctx *c, =20 damon_for_each_scheme(s, c) { struct damos_quota *quota =3D &s->quota; - unsigned long sz; - struct timespec64 begin, end; - unsigned long sz_applied =3D 0; =20 if (!s->wmarks.activated) continue; @@ -780,37 +815,7 @@ static void damon_do_apply_schemes(struct damon_ctx *c, if (!damos_valid_target(c, t, r, s)) continue; =20 - /* Apply the scheme */ - sz =3D damon_sz_region(r); - 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); - if (!sz) - goto update_stat; - damon_split_region_at(t, r, sz); - } - ktime_get_coarse_ts64(&begin); - sz_applied =3D c->ops.apply_scheme(c, t, r, s); - ktime_get_coarse_ts64(&end); - quota->total_charged_ns +=3D timespec64_to_ns(&end) - - timespec64_to_ns(&begin); - quota->charged_sz +=3D sz; - if (quota->esz && quota->charged_sz >=3D quota->esz) { - quota->charge_target_from =3D t; - quota->charge_addr_from =3D r->ar.end + 1; - } - } - if (s->action !=3D DAMOS_STAT) - r->age =3D 0; - -update_stat: - s->stat.nr_tried++; - s->stat.sz_tried +=3D sz; - if (sz_applied) - s->stat.nr_applied++; - s->stat.sz_applied +=3D sz_applied; + damos_apply_scheme(c, t, r, s); } } =20 --=20 2.25.1 From nobody Wed Apr 8 07:59:16 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 CC9D3FA373D for ; Wed, 26 Oct 2022 23:00:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233318AbiJZXAJ (ORCPT ); Wed, 26 Oct 2022 19:00:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40956 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233491AbiJZW77 (ORCPT ); Wed, 26 Oct 2022 18:59:59 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3C5C26569 for ; Wed, 26 Oct 2022 15:59:52 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id AC4E2620DC for ; Wed, 26 Oct 2022 22:59:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B58E6C43142; Wed, 26 Oct 2022 22:59:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825191; bh=JpR/JpSFcvX/01k1C+QGg0rBNnZER7RU6+E6N5NVTO8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r6Eyv8ffq85heYOnigGBCrI+z0CZ4/IyyIB+YPDQDNJr+24gdpnLwQ302W4TFpqyE 5PQSq5YVSY+94t/kcpD7m9+o9jvI/FY4BYFd0+W9bHrzsmGY6GI8uVrq3mV9rcjRmN hvtwew5+HkJ8S2WsXBTfP9t2ch6LmFZtXk+MMmVxUGPLhHE2XSGGUP1y+Wl/1C0mhA CD1fMCaw9yw3bWwDBGNYTqGQ6za5fGkEaUIrJrrazMtESzldt4aujvwPTKMP2i7JEw 3hx82Iuk66RtdFldolTjr0JN5VVAl0a+BGfrNSkmoMLSrijYWfDanoNknERIUi3044 JlEfEkO6oAyjg== From: SeongJae Park To: Andrew Morton Cc: damon@lists.linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, SeongJae Park Subject: [PATCH v2 03/12] mm/damon/core: split out scheme stat update logic into a new function Date: Wed, 26 Oct 2022 22:59:34 +0000 Message-Id: <20221026225943.100429-4-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The function for applying a given DAMON scheme action to a given DAMON region, 'damos_apply_scheme()' is not quite short. Make it better to read by splitting out the stat update logic into a new function. Signed-off-by: SeongJae Park Signed-off-by: Andrew Morton --- mm/damon/core.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index c1a912bc46ae..3a810c6e26bc 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -755,6 +755,16 @@ static bool damos_skip_charged_region(struct damon_tar= get *t, return false; } =20 +static void damos_update_stat(struct damos *s, + unsigned long sz_tried, unsigned long sz_applied) +{ + s->stat.nr_tried++; + s->stat.sz_tried +=3D sz_tried; + if (sz_applied) + s->stat.nr_applied++; + s->stat.sz_applied +=3D sz_applied; +} + static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t, struct damon_region *r, struct damos *s) { @@ -786,11 +796,7 @@ static void damos_apply_scheme(struct damon_ctx *c, st= ruct damon_target *t, r->age =3D 0; =20 update_stat: - s->stat.nr_tried++; - s->stat.sz_tried +=3D sz; - if (sz_applied) - s->stat.nr_applied++; - s->stat.sz_applied +=3D sz_applied; + damos_update_stat(s, sz, sz_applied); } =20 static void damon_do_apply_schemes(struct damon_ctx *c, --=20 2.25.1 From nobody Wed Apr 8 07:59:16 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 29EFFFA3743 for ; Wed, 26 Oct 2022 23:00:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234006AbiJZXAG (ORCPT ); Wed, 26 Oct 2022 19:00:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233956AbiJZW76 (ORCPT ); Wed, 26 Oct 2022 18:59:58 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A3A2826495 for ; Wed, 26 Oct 2022 15:59:52 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id DCCD462079 for ; Wed, 26 Oct 2022 22:59:51 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4C6D9C433C1; Wed, 26 Oct 2022 22:59:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825191; bh=ijAibGNK7BkbPJuFkIhnu5wZ2+BYvBnNeRFcJtsugII=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DjzuvnukrhrEXV0TQ6k4DIipy66pmX1qwr2/IQjeWOaeQa6+czARR6Ptlcl/Dt2If zxTdpJLrTS3qmyK70kX5Pu1y0K4TWkQQnZIdhopotH+HN0z/aebztqY+OyRGAyASsz 24Ui1EecU/z0NJTt4nPQDJaiujlCHqBTKV2MukbdDG279a9OIRNuqh4T3ITZvC7OFG jikPYJtcnv9+Bdfbx0W3WYCe8c0A5XPrL68AMdS/l/feFJi9Q7eWJyoPNBzONWi43L WVFGdNZlifefEWOrka/adY/lsb/6ySEt70LVVxjpJKNg2XSzP5LOEcahDcXSFz9RQr XdLN8zi1Pqf3A== From: SeongJae Park To: Andrew Morton Cc: damon@lists.linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, SeongJae Park Subject: [PATCH v2 04/12] mm/damon/core: split out scheme quota adjustment logic into a new function Date: Wed, 26 Oct 2022 22:59:35 +0000 Message-Id: <20221026225943.100429-5-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" DAMOS quota adjustment logic in 'kdamond_apply_schemes()', has some amount of code, and the logic is not so straightforward. Split it out to a new function for better readability. Signed-off-by: SeongJae Park Signed-off-by: Andrew Morton --- mm/damon/core.c | 91 ++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index 3a810c6e26bc..80d5937fe337 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -848,59 +848,64 @@ static void damos_set_effective_quota(struct damos_qu= ota *quota) quota->esz =3D esz; } =20 -static void kdamond_apply_schemes(struct damon_ctx *c) +static void damos_adjust_quota(struct damon_ctx *c, struct damos *s) { + struct damos_quota *quota =3D &s->quota; struct damon_target *t; - struct damon_region *r, *next_r; - struct damos *s; + struct damon_region *r; + unsigned long cumulated_sz; + unsigned int score, max_score =3D 0; =20 - damon_for_each_scheme(s, c) { - struct damos_quota *quota =3D &s->quota; - unsigned long cumulated_sz; - unsigned int score, max_score =3D 0; + if (!quota->ms && !quota->sz) + return; =20 - if (!s->wmarks.activated) - continue; + /* New charge window starts */ + if (time_after_eq(jiffies, quota->charged_from + + msecs_to_jiffies(quota->reset_interval))) { + if (quota->esz && quota->charged_sz >=3D quota->esz) + s->stat.qt_exceeds++; + quota->total_charged_sz +=3D quota->charged_sz; + quota->charged_from =3D jiffies; + quota->charged_sz =3D 0; + damos_set_effective_quota(quota); + } =20 - if (!quota->ms && !quota->sz) - continue; + if (!c->ops.get_scheme_score) + return; =20 - /* New charge window starts */ - if (time_after_eq(jiffies, quota->charged_from + - msecs_to_jiffies( - quota->reset_interval))) { - if (quota->esz && quota->charged_sz >=3D quota->esz) - s->stat.qt_exceeds++; - quota->total_charged_sz +=3D quota->charged_sz; - quota->charged_from =3D jiffies; - quota->charged_sz =3D 0; - damos_set_effective_quota(quota); + /* Fill up the score histogram */ + memset(quota->histogram, 0, sizeof(quota->histogram)); + damon_for_each_target(t, c) { + damon_for_each_region(r, t) { + if (!__damos_valid_target(r, s)) + continue; + score =3D c->ops.get_scheme_score(c, t, r, s); + quota->histogram[score] +=3D damon_sz_region(r); + if (score > max_score) + max_score =3D score; } + } =20 - if (!c->ops.get_scheme_score) - continue; + /* Set the min score limit */ + for (cumulated_sz =3D 0, score =3D max_score; ; score--) { + cumulated_sz +=3D quota->histogram[score]; + if (cumulated_sz >=3D quota->esz || !score) + break; + } + quota->min_score =3D score; +} =20 - /* Fill up the score histogram */ - memset(quota->histogram, 0, sizeof(quota->histogram)); - damon_for_each_target(t, c) { - damon_for_each_region(r, t) { - if (!__damos_valid_target(r, s)) - continue; - score =3D c->ops.get_scheme_score( - c, t, r, s); - quota->histogram[score] +=3D damon_sz_region(r); - if (score > max_score) - max_score =3D score; - } - } +static void kdamond_apply_schemes(struct damon_ctx *c) +{ + struct damon_target *t; + struct damon_region *r, *next_r; + struct damos *s; =20 - /* Set the min score limit */ - for (cumulated_sz =3D 0, score =3D max_score; ; score--) { - cumulated_sz +=3D quota->histogram[score]; - if (cumulated_sz >=3D quota->esz || !score) - break; - } - quota->min_score =3D score; + damon_for_each_scheme(s, c) { + if (!s->wmarks.activated) + continue; + + damos_adjust_quota(c, s); } =20 damon_for_each_target(t, c) { --=20 2.25.1 From nobody Wed Apr 8 07:59:16 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 6DA5BC38A2D for ; Wed, 26 Oct 2022 23:00:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234125AbiJZXAf (ORCPT ); Wed, 26 Oct 2022 19:00:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234005AbiJZXAA (ORCPT ); Wed, 26 Oct 2022 19:00:00 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C1A227CE0 for ; Wed, 26 Oct 2022 15:59:53 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id DAB89620E4 for ; Wed, 26 Oct 2022 22:59:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E3802C433D7; Wed, 26 Oct 2022 22:59:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825192; bh=nH2ArlwknM/y/vBnmfj0ga+qKqYuQNWCJAYIWsSWxEE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sh/w0gDPKBDZTvj3PeoKX95hmST7DK0fwtYMFgGoV74D2d7W70BPXmc5pMvr5UQYX 75wYdCxnWco7u/YfNf1FDOAhTvd/pPYEyDStO6ND3y32bPM7xos/FuOjTVPu4Mq9jw VlgS34XwFctaQ3C1VZOMt4M9/K/iqHjhh49PhbCDOJBlf5Ky0Qvo6Shgse1SNLhQkE NPvv5qeOaWtv96IkHUVp6wO8/mxvZWRKhx0FGNnx/4TjLZEoOVxAKJkjKuFqgEpTRr T1meIpTeo4BixfYNRNbL/nciUQg5bNB8rUc2rjDrp1IcPFxpHNcsBzPCflEloIyx8s hxg/wLJ1Vo2DA== From: SeongJae Park To: Andrew Morton Cc: damon@lists.linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, SeongJae Park Subject: [PATCH v2 05/12] mm/damon/sysfs: use damon_addr_range for regions' start and end values Date: Wed, 26 Oct 2022 22:59:36 +0000 Message-Id: <20221026225943.100429-6-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" DAMON has a struct for each address range but DAMON sysfs interface is using the low type (unsigned long) for storing the start and end addresses of regions. Use the dedicated struct for better type safety. Signed-off-by: SeongJae Park Signed-off-by: Andrew Morton --- mm/damon/sysfs.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c index 9f1219a67e3f..b9183063bfea 100644 --- a/mm/damon/sysfs.c +++ b/mm/damon/sysfs.c @@ -1062,13 +1062,11 @@ static struct kobj_type damon_sysfs_schemes_ktype = =3D { =20 struct damon_sysfs_region { struct kobject kobj; - unsigned long start; - unsigned long end; + struct damon_addr_range ar; }; =20 static struct damon_sysfs_region *damon_sysfs_region_alloc( - unsigned long start, - unsigned long end) + struct damon_addr_range ar) { struct damon_sysfs_region *region =3D kmalloc(sizeof(*region), GFP_KERNEL); @@ -1076,8 +1074,7 @@ static struct damon_sysfs_region *damon_sysfs_region_= alloc( if (!region) return NULL; region->kobj =3D (struct kobject){}; - region->start =3D start; - region->end =3D end; + region->ar =3D ar; return region; } =20 @@ -1087,7 +1084,7 @@ static ssize_t start_show(struct kobject *kobj, struc= t kobj_attribute *attr, struct damon_sysfs_region *region =3D container_of(kobj, struct damon_sysfs_region, kobj); =20 - return sysfs_emit(buf, "%lu\n", region->start); + return sysfs_emit(buf, "%lu\n", region->ar.start); } =20 static ssize_t start_store(struct kobject *kobj, struct kobj_attribute *at= tr, @@ -1095,7 +1092,7 @@ static ssize_t start_store(struct kobject *kobj, stru= ct kobj_attribute *attr, { struct damon_sysfs_region *region =3D container_of(kobj, struct damon_sysfs_region, kobj); - int err =3D kstrtoul(buf, 0, ®ion->start); + int err =3D kstrtoul(buf, 0, ®ion->ar.start); =20 return err ? err : count; } @@ -1106,7 +1103,7 @@ static ssize_t end_show(struct kobject *kobj, struct = kobj_attribute *attr, struct damon_sysfs_region *region =3D container_of(kobj, struct damon_sysfs_region, kobj); =20 - return sysfs_emit(buf, "%lu\n", region->end); + return sysfs_emit(buf, "%lu\n", region->ar.end); } =20 static ssize_t end_store(struct kobject *kobj, struct kobj_attribute *attr, @@ -1114,7 +1111,7 @@ static ssize_t end_store(struct kobject *kobj, struct= kobj_attribute *attr, { struct damon_sysfs_region *region =3D container_of(kobj, struct damon_sysfs_region, kobj); - int err =3D kstrtoul(buf, 0, ®ion->end); + int err =3D kstrtoul(buf, 0, ®ion->ar.end); =20 return err ? err : count; } @@ -1187,7 +1184,7 @@ static int damon_sysfs_regions_add_dirs(struct damon_= sysfs_regions *regions, regions->regions_arr =3D regions_arr; =20 for (i =3D 0; i < nr_regions; i++) { - region =3D damon_sysfs_region_alloc(0, 0); + region =3D damon_sysfs_region_alloc((struct damon_addr_range){}); if (!region) { damon_sysfs_regions_rm_dirs(regions); return -ENOMEM; @@ -2147,11 +2144,11 @@ static int damon_sysfs_set_regions(struct damon_tar= get *t, struct damon_sysfs_region *sys_region =3D sysfs_regions->regions_arr[i]; =20 - if (sys_region->start > sys_region->end) + if (sys_region->ar.start > sys_region->ar.end) goto out; =20 - ranges[i].start =3D sys_region->start; - ranges[i].end =3D sys_region->end; + ranges[i].start =3D sys_region->ar.start; + ranges[i].end =3D sys_region->ar.end; if (i =3D=3D 0) continue; if (ranges[i - 1].end > ranges[i].start) --=20 2.25.1 From nobody Wed Apr 8 07:59:16 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 DB64AC38A2D for ; Wed, 26 Oct 2022 23:00:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234098AbiJZXA2 (ORCPT ); Wed, 26 Oct 2022 19:00:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40990 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234003AbiJZXAA (ORCPT ); Wed, 26 Oct 2022 19:00:00 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5BF7B27CD0 for ; Wed, 26 Oct 2022 15:59:55 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 274DAB80CA9 for ; Wed, 26 Oct 2022 22:59:54 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E743C433D6; Wed, 26 Oct 2022 22:59:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825192; bh=8GL00RPKqf41iTTBqJzSvs8lE7BF3n/Dkon2+BFR2Rk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MePX4QP7b/+bsXbvuYDWVKEzt8T7ttgcmo+ROEtbeepA6gq+RAYM+Hsv0n5MZf6HR fOoJ7LQbDBQ7v3IRo7/ROwd6lLUpT6cU9hRCtPe42QeE9yahzPn39o6qYY4HZAXszM WMjWy38qDWJp5lPr52IEJMiGkOi2vR3U/8zKGDomoHsUxjGV1Xms72lV21B8XHV2FX sCZZY9ZwHNRf3X1FJ+/hjUjSHcvpyLLbkxY6mRBWxWaVNLgPZ83mX+cCZkJCdMKZeA 2LIeGNczowR3Brpwwht3QTd/GBnbqwBhiftq+gGAm2xeLrCnxfnX73vg/VLhWky2Nb jHhgtItkwIP6g== From: SeongJae Park To: Andrew Morton Cc: damon@lists.linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, SeongJae Park Subject: [PATCH v2 06/12] mm/damon/sysfs: remove parameters of damon_sysfs_region_alloc() Date: Wed, 26 Oct 2022 22:59:37 +0000 Message-Id: <20221026225943.100429-7-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 'damon_sysfs_region_alloc()' is always called with zero-filled 'struct damon_addr_range', because the start and end addresses should set by users. Remove unnecessary parameters of the function and simplify the body by using 'kzalloc()'. Signed-off-by: SeongJae Park Signed-off-by: Andrew Morton --- mm/damon/sysfs.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c index b9183063bfea..e8bd7367d15b 100644 --- a/mm/damon/sysfs.c +++ b/mm/damon/sysfs.c @@ -1065,17 +1065,9 @@ struct damon_sysfs_region { struct damon_addr_range ar; }; =20 -static struct damon_sysfs_region *damon_sysfs_region_alloc( - struct damon_addr_range ar) +static struct damon_sysfs_region *damon_sysfs_region_alloc(void) { - struct damon_sysfs_region *region =3D kmalloc(sizeof(*region), - GFP_KERNEL); - - if (!region) - return NULL; - region->kobj =3D (struct kobject){}; - region->ar =3D ar; - return region; + return kzalloc(sizeof(struct damon_sysfs_region), GFP_KERNEL); } =20 static ssize_t start_show(struct kobject *kobj, struct kobj_attribute *att= r, @@ -1184,7 +1176,7 @@ static int damon_sysfs_regions_add_dirs(struct damon_= sysfs_regions *regions, regions->regions_arr =3D regions_arr; =20 for (i =3D 0; i < nr_regions; i++) { - region =3D damon_sysfs_region_alloc((struct damon_addr_range){}); + region =3D damon_sysfs_region_alloc(); if (!region) { damon_sysfs_regions_rm_dirs(regions); return -ENOMEM; --=20 2.25.1 From nobody Wed Apr 8 07:59:16 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 99190C433FE for ; Wed, 26 Oct 2022 23:00:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234132AbiJZXAk (ORCPT ); Wed, 26 Oct 2022 19:00:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40992 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234008AbiJZXAA (ORCPT ); Wed, 26 Oct 2022 19:00:00 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C17227CD6 for ; Wed, 26 Oct 2022 15:59:54 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 092AD620C8 for ; Wed, 26 Oct 2022 22:59:54 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 154F0C4347C; Wed, 26 Oct 2022 22:59:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825193; bh=LA5eSTlkkTuiqSOiZ/+/4cpBqjOUioigu0cyIQgAlG4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mdx99LlUzYMWJi74isWfMCDiXyKcMKzijAHikjv0jWN8tI7zmyTSk1qW93l74h7Lb hsze/eZTlUpzQ62rz+WlvSlBzeG41W0gpPTx1sZznMrvnYEctzRT4zEukhbOkox3C0 pQXbJ+Lcjlkfoo4DgHEmsNEg0RIWmJqmyqJehfjkcZKOySeSyjy6zYBU9p7OR/tAut Co/Mk7lwUXr8bg8A5h3Eca1kBzGeOlkpjSHBazNz9OzYx95ewoCNEBMbxEhnTGfjYz YEY8vXwy8jF9sDchZoVxNkA8Z2lgzPn/OxCyvhVJPWDyEbtXe0Maj+O9ZPWlEwBBRv P+DCd2ogTB6IA== From: SeongJae Park To: Andrew Morton Cc: linux-kernel@vger.kernel.org, damon@lists.linux.dev, linux-mm@kvack.org, SeongJae Park Subject: [PATCH v2 07/12] mm/damon/sysfs: move sysfs_lock to common module Date: Wed, 26 Oct 2022 22:59:38 +0000 Message-Id: <20221026225943.100429-8-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" DAMON sysfs interface is implemented in a single file, sysfs.c, which has about 2,800 lines of code. As the interface is hierarchical and some of the code can be reused by different hierarchies, it would make more sense to split out the implementation into common parts and different parts in multiple files. As the beginning of the work, create files for common code and move the global mutex for directories modifications protection into the new file. Signed-off-by: SeongJae Park Signed-off-by: Andrew Morton --- mm/damon/Makefile | 2 +- mm/damon/sysfs-common.c | 11 +++++++++++ mm/damon/sysfs-common.h | 11 +++++++++++ mm/damon/sysfs.c | 4 +--- 4 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 mm/damon/sysfs-common.c create mode 100644 mm/damon/sysfs-common.h diff --git a/mm/damon/Makefile b/mm/damon/Makefile index 3e6b8ad73858..f8d535a6253b 100644 --- a/mm/damon/Makefile +++ b/mm/damon/Makefile @@ -3,7 +3,7 @@ obj-y :=3D core.o obj-$(CONFIG_DAMON_VADDR) +=3D ops-common.o vaddr.o obj-$(CONFIG_DAMON_PADDR) +=3D ops-common.o paddr.o -obj-$(CONFIG_DAMON_SYSFS) +=3D sysfs.o +obj-$(CONFIG_DAMON_SYSFS) +=3D sysfs-common.o sysfs.o obj-$(CONFIG_DAMON_DBGFS) +=3D dbgfs.o obj-$(CONFIG_DAMON_RECLAIM) +=3D reclaim.o obj-$(CONFIG_DAMON_LRU_SORT) +=3D lru_sort.o diff --git a/mm/damon/sysfs-common.c b/mm/damon/sysfs-common.c new file mode 100644 index 000000000000..9dc743868d5b --- /dev/null +++ b/mm/damon/sysfs-common.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Common Primitives for DAMON Sysfs Interface + * + * Author: SeongJae Park + */ + +#include "sysfs-common.h" + +DEFINE_MUTEX(damon_sysfs_lock); + diff --git a/mm/damon/sysfs-common.h b/mm/damon/sysfs-common.h new file mode 100644 index 000000000000..745a918b94f5 --- /dev/null +++ b/mm/damon/sysfs-common.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Common Primitives for DAMON Sysfs Interface + * + * Author: SeongJae Park + */ + +#include +#include + +extern struct mutex damon_sysfs_lock; diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c index e8bd7367d15b..0f3f06d8dae7 100644 --- a/mm/damon/sysfs.c +++ b/mm/damon/sysfs.c @@ -5,13 +5,11 @@ * Copyright (c) 2022 SeongJae Park */ =20 -#include -#include #include #include #include =20 -static DEFINE_MUTEX(damon_sysfs_lock); +#include "sysfs-common.h" =20 /* * unsigned long range directory --=20 2.25.1 From nobody Wed Apr 8 07:59:16 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 77B9FC433FE for ; Wed, 26 Oct 2022 23:00:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234086AbiJZXAT (ORCPT ); Wed, 26 Oct 2022 19:00:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40998 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234002AbiJZXAA (ORCPT ); Wed, 26 Oct 2022 19:00:00 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C36027CE3 for ; Wed, 26 Oct 2022 15:59:54 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 4057E620E6 for ; Wed, 26 Oct 2022 22:59:54 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id A381DC433B5; Wed, 26 Oct 2022 22:59:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825194; bh=ZOyG8YUU5cVxru2AD6VW1+1EsLz+CD3P+8BEUZMBwok=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dKHhq6CyP1LSndUbyVyNvrVbk8frT73Mgw1L5/bdsRPcMpjhx4cI82ziwh08BsC3t 4d41Bog8sPNgy7/S66oVAqUjOkg8LvZrTaUw8jaUSKE4uHFEmv0EEOb9YpAYWuD+39 sEfcVT9GPtFFcu04s+SuIdDfnC8yA9ApPnXCoGBuCjcDM5JFcoosNwRYCOGMytAfak AiyaYDQjSsqpE0UiWCp4jubQBbOA1dP54ET3yUMnuUfTuLR9T2Sb+IatRchA5nGQcd MJYqULqVWc6jtnBxLOrbSH8jlHg6ToRXRmo2O5IHWKT6QtJne3bVqAzuhOMZzLhiIy /bVgQGarJZT8A== From: SeongJae Park To: Andrew Morton Cc: damon@lists.linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, SeongJae Park Subject: [PATCH v2 08/12] mm/damon/sysfs: move unsigned long range directory to common module Date: Wed, 26 Oct 2022 22:59:39 +0000 Message-Id: <20221026225943.100429-9-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The implementation of unsigned long type range directories can be reused by multiple DAMON sysfs directories including those for DAMON-based Operation Schemes and the range of number of monitoring regions. Move the code into the files for DAMON sysfs common logics. Signed-off-by: SeongJae Park Signed-off-by: Andrew Morton --- mm/damon/sysfs-common.c | 96 ++++++++++++++++++++++++++++++++++++++ mm/damon/sysfs-common.h | 13 ++++++ mm/damon/sysfs.c | 100 ---------------------------------------- 3 files changed, 109 insertions(+), 100 deletions(-) diff --git a/mm/damon/sysfs-common.c b/mm/damon/sysfs-common.c index 9dc743868d5b..52bebf242f74 100644 --- a/mm/damon/sysfs-common.c +++ b/mm/damon/sysfs-common.c @@ -5,7 +5,103 @@ * Author: SeongJae Park */ =20 +#include + #include "sysfs-common.h" =20 DEFINE_MUTEX(damon_sysfs_lock); =20 +/* + * unsigned long range directory + */ + +struct damon_sysfs_ul_range *damon_sysfs_ul_range_alloc( + unsigned long min, + unsigned long max) +{ + struct damon_sysfs_ul_range *range =3D kmalloc(sizeof(*range), + GFP_KERNEL); + + if (!range) + return NULL; + range->kobj =3D (struct kobject){}; + range->min =3D min; + range->max =3D max; + + return range; +} + +static ssize_t min_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct damon_sysfs_ul_range *range =3D container_of(kobj, + struct damon_sysfs_ul_range, kobj); + + return sysfs_emit(buf, "%lu\n", range->min); +} + +static ssize_t min_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct damon_sysfs_ul_range *range =3D container_of(kobj, + struct damon_sysfs_ul_range, kobj); + unsigned long min; + int err; + + err =3D kstrtoul(buf, 0, &min); + if (err) + return err; + + range->min =3D min; + return count; +} + +static ssize_t max_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct damon_sysfs_ul_range *range =3D container_of(kobj, + struct damon_sysfs_ul_range, kobj); + + return sysfs_emit(buf, "%lu\n", range->max); +} + +static ssize_t max_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct damon_sysfs_ul_range *range =3D container_of(kobj, + struct damon_sysfs_ul_range, kobj); + unsigned long max; + int err; + + err =3D kstrtoul(buf, 0, &max); + if (err) + return err; + + range->max =3D max; + return count; +} + +void damon_sysfs_ul_range_release(struct kobject *kobj) +{ + kfree(container_of(kobj, struct damon_sysfs_ul_range, kobj)); +} + +static struct kobj_attribute damon_sysfs_ul_range_min_attr =3D + __ATTR_RW_MODE(min, 0600); + +static struct kobj_attribute damon_sysfs_ul_range_max_attr =3D + __ATTR_RW_MODE(max, 0600); + +static struct attribute *damon_sysfs_ul_range_attrs[] =3D { + &damon_sysfs_ul_range_min_attr.attr, + &damon_sysfs_ul_range_max_attr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(damon_sysfs_ul_range); + +struct kobj_type damon_sysfs_ul_range_ktype =3D { + .release =3D damon_sysfs_ul_range_release, + .sysfs_ops =3D &kobj_sysfs_ops, + .default_groups =3D damon_sysfs_ul_range_groups, +}; + diff --git a/mm/damon/sysfs-common.h b/mm/damon/sysfs-common.h index 745a918b94f5..56e6a99e353b 100644 --- a/mm/damon/sysfs-common.h +++ b/mm/damon/sysfs-common.h @@ -9,3 +9,16 @@ #include =20 extern struct mutex damon_sysfs_lock; + +struct damon_sysfs_ul_range { + struct kobject kobj; + unsigned long min; + unsigned long max; +}; + +struct damon_sysfs_ul_range *damon_sysfs_ul_range_alloc( + unsigned long min, + unsigned long max); +void damon_sysfs_ul_range_release(struct kobject *kobj); + +extern struct kobj_type damon_sysfs_ul_range_ktype; diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c index 0f3f06d8dae7..129743292e17 100644 --- a/mm/damon/sysfs.c +++ b/mm/damon/sysfs.c @@ -11,106 +11,6 @@ =20 #include "sysfs-common.h" =20 -/* - * unsigned long range directory - */ - -struct damon_sysfs_ul_range { - struct kobject kobj; - unsigned long min; - unsigned long max; -}; - -static struct damon_sysfs_ul_range *damon_sysfs_ul_range_alloc( - unsigned long min, - unsigned long max) -{ - struct damon_sysfs_ul_range *range =3D kmalloc(sizeof(*range), - GFP_KERNEL); - - if (!range) - return NULL; - range->kobj =3D (struct kobject){}; - range->min =3D min; - range->max =3D max; - - return range; -} - -static ssize_t min_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) -{ - struct damon_sysfs_ul_range *range =3D container_of(kobj, - struct damon_sysfs_ul_range, kobj); - - return sysfs_emit(buf, "%lu\n", range->min); -} - -static ssize_t min_store(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t count) -{ - struct damon_sysfs_ul_range *range =3D container_of(kobj, - struct damon_sysfs_ul_range, kobj); - unsigned long min; - int err; - - err =3D kstrtoul(buf, 0, &min); - if (err) - return err; - - range->min =3D min; - return count; -} - -static ssize_t max_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) -{ - struct damon_sysfs_ul_range *range =3D container_of(kobj, - struct damon_sysfs_ul_range, kobj); - - return sysfs_emit(buf, "%lu\n", range->max); -} - -static ssize_t max_store(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t count) -{ - struct damon_sysfs_ul_range *range =3D container_of(kobj, - struct damon_sysfs_ul_range, kobj); - unsigned long max; - int err; - - err =3D kstrtoul(buf, 0, &max); - if (err) - return err; - - range->max =3D max; - return count; -} - -static void damon_sysfs_ul_range_release(struct kobject *kobj) -{ - kfree(container_of(kobj, struct damon_sysfs_ul_range, kobj)); -} - -static struct kobj_attribute damon_sysfs_ul_range_min_attr =3D - __ATTR_RW_MODE(min, 0600); - -static struct kobj_attribute damon_sysfs_ul_range_max_attr =3D - __ATTR_RW_MODE(max, 0600); - -static struct attribute *damon_sysfs_ul_range_attrs[] =3D { - &damon_sysfs_ul_range_min_attr.attr, - &damon_sysfs_ul_range_max_attr.attr, - NULL, -}; -ATTRIBUTE_GROUPS(damon_sysfs_ul_range); - -static struct kobj_type damon_sysfs_ul_range_ktype =3D { - .release =3D damon_sysfs_ul_range_release, - .sysfs_ops =3D &kobj_sysfs_ops, - .default_groups =3D damon_sysfs_ul_range_groups, -}; - /* * schemes/stats directory */ --=20 2.25.1 From nobody Wed Apr 8 07:59:16 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 E5D7AFA373D for ; Wed, 26 Oct 2022 23:00:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232679AbiJZXAp (ORCPT ); Wed, 26 Oct 2022 19:00:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234010AbiJZXAA (ORCPT ); Wed, 26 Oct 2022 19:00:00 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C84627FCF for ; Wed, 26 Oct 2022 15:59:57 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id F0CD8B82476 for ; Wed, 26 Oct 2022 22:59:55 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 486D0C43142; Wed, 26 Oct 2022 22:59:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825194; bh=ntGtZw3yOs+uZ3gGOlcjovkmvzOGben11U2Vk6cgNsA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=apA/DBpn9ihjONGTe+7Tm+CF2VK2nXdQwrRSROG0uPjYVHC6AfMycLiYCPgw4tSV2 Bjryu70eLbWJwZ3NnTsY4AVkIq6TUoB9gxxBJDdYo6uGFuIOdvOmyM2ICd2Cwgeqh1 bTgFL7CxZRZOpao4OYSzJN/iSg34iczbkjbdwE9d9E28XH99UhR/tWLjlRWvTEmtqF FMSuaipMVFPhD+vCFcKCokDIHnrMv8uH4EJ1suKOml4QfwTOj3gtr8C5rM00UCydjr ZzzldyJunEtbF2+KVU4QrINjXm4ToX4LMI7rLviAU6jxY6ZWlaCORklG3p0m8AeQtA 2CdoglM3N20DQ== From: SeongJae Park To: Andrew Morton Cc: damon@lists.linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, SeongJae Park Subject: [PATCH v2 09/12] mm/damon/sysfs: split out kdamond-independent schemes stats update logic into a new function Date: Wed, 26 Oct 2022 22:59:40 +0000 Message-Id: <20221026225943.100429-10-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" 'damon_sysfs_schemes_update_stats()' is coupled with both damon_sysfs_kdamond and damon_sysfs_schemes. It's a wide range of types dependency. It makes splitting the logics a little bit distracting. Split the function so that each function is coupled with smaller range of types. Signed-off-by: SeongJae Park Signed-off-by: Andrew Morton --- mm/damon/sysfs.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c index 129743292e17..082c55e68e0e 100644 --- a/mm/damon/sysfs.c +++ b/mm/damon/sysfs.c @@ -2204,6 +2204,25 @@ static void damon_sysfs_before_terminate(struct damo= n_ctx *ctx) mutex_unlock(&ctx->kdamond_lock); } =20 +static void damon_sysfs_schemes_update_stats( + struct damon_sysfs_schemes *sysfs_schemes, + struct damon_ctx *ctx) +{ + struct damos *scheme; + int schemes_idx =3D 0; + + damon_for_each_scheme(scheme, ctx) { + struct damon_sysfs_stats *sysfs_stats; + + sysfs_stats =3D sysfs_schemes->schemes_arr[schemes_idx++]->stats; + sysfs_stats->nr_tried =3D scheme->stat.nr_tried; + sysfs_stats->sz_tried =3D scheme->stat.sz_tried; + sysfs_stats->nr_applied =3D scheme->stat.nr_applied; + sysfs_stats->sz_applied =3D scheme->stat.sz_applied; + sysfs_stats->qt_exceeds =3D scheme->stat.qt_exceeds; + } +} + /* * damon_sysfs_upd_schemes_stats() - Update schemes stats sysfs files. * @kdamond: The kobject wrapper that associated to the kdamond thread. @@ -2216,23 +2235,11 @@ static void damon_sysfs_before_terminate(struct dam= on_ctx *ctx) static int damon_sysfs_upd_schemes_stats(struct damon_sysfs_kdamond *kdamo= nd) { struct damon_ctx *ctx =3D kdamond->damon_ctx; - struct damon_sysfs_schemes *sysfs_schemes; - struct damos *scheme; - int schemes_idx =3D 0; =20 if (!ctx) return -EINVAL; - sysfs_schemes =3D kdamond->contexts->contexts_arr[0]->schemes; - damon_for_each_scheme(scheme, ctx) { - struct damon_sysfs_stats *sysfs_stats; - - sysfs_stats =3D sysfs_schemes->schemes_arr[schemes_idx++]->stats; - sysfs_stats->nr_tried =3D scheme->stat.nr_tried; - sysfs_stats->sz_tried =3D scheme->stat.sz_tried; - sysfs_stats->nr_applied =3D scheme->stat.nr_applied; - sysfs_stats->sz_applied =3D scheme->stat.sz_applied; - sysfs_stats->qt_exceeds =3D scheme->stat.qt_exceeds; - } + damon_sysfs_schemes_update_stats( + kdamond->contexts->contexts_arr[0]->schemes, ctx); return 0; } =20 --=20 2.25.1 From nobody Wed Apr 8 07:59:16 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 AC7B6C38A2D for ; Wed, 26 Oct 2022 23:00:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234056AbiJZXA6 (ORCPT ); Wed, 26 Oct 2022 19:00:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234042AbiJZXAE (ORCPT ); Wed, 26 Oct 2022 19:00:04 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B4472A724 for ; Wed, 26 Oct 2022 15:59:58 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 113F1B82456 for ; Wed, 26 Oct 2022 22:59:57 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D84A2C43470; Wed, 26 Oct 2022 22:59:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825195; bh=hTaaqwhgTBMgV9mr9IUFTP9fSN1B6nfTJ1z7pnWuxxE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aBbYS1N+2I7akzbzsChTsvFXVpF5CrGMIw2woEu2zKxcAg89wwkMYH4mAuKwecRxp 1tfkswmhdsCN+Mc+py2rhtL7n1kHYsdsrqmYAg7LXOn3258DjDb5XdyioDq7V0Zig1 xskFcBI/SDZC/vvXlPd6KyENzxCvTf2/EHqqPxcxSVKKumKcQG47C46HrtCfyjV255 HdqJl91C/XYmb4SOoCdOorUVOdO5/qTO2g4KX/vDeXH3ibRB26HvtZUuIFDYySfJ+p wn5vTUDuuFoS4HcBGlZwgYNdDBYWiq3C+deVs5RGUpxcqxjZDWx5vCYT8AFjAbj1fB niqWGpb2V79nw== From: SeongJae Park To: Andrew Morton Cc: linux-kernel@vger.kernel.org, damon@lists.linux.dev, linux-mm@kvack.org, SeongJae Park Subject: [PATCH v2 10/12] mm/damon/sysfs: split out schemes directory implementation to separate file Date: Wed, 26 Oct 2022 22:59:41 +0000 Message-Id: <20221026225943.100429-11-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" DAMON sysfs interface for 'schemes' directory is implemented using about one thousand lines of code. It has no strong dependency with other parts of its file, so split it out to another file for better code management. Signed-off-by: SeongJae Park --- mm/damon/Makefile | 2 +- mm/damon/sysfs-common.h | 22 + mm/damon/sysfs-schemes.c | 1022 ++++++++++++++++++++++++++++++++++++++ mm/damon/sysfs.c | 1018 ------------------------------------- 4 files changed, 1045 insertions(+), 1019 deletions(-) create mode 100644 mm/damon/sysfs-schemes.c diff --git a/mm/damon/Makefile b/mm/damon/Makefile index f8d535a6253b..1e86f5253d7f 100644 --- a/mm/damon/Makefile +++ b/mm/damon/Makefile @@ -3,7 +3,7 @@ obj-y :=3D core.o obj-$(CONFIG_DAMON_VADDR) +=3D ops-common.o vaddr.o obj-$(CONFIG_DAMON_PADDR) +=3D ops-common.o paddr.o -obj-$(CONFIG_DAMON_SYSFS) +=3D sysfs-common.o sysfs.o +obj-$(CONFIG_DAMON_SYSFS) +=3D sysfs-common.o sysfs-schemes.o sysfs.o obj-$(CONFIG_DAMON_DBGFS) +=3D dbgfs.o obj-$(CONFIG_DAMON_RECLAIM) +=3D reclaim.o obj-$(CONFIG_DAMON_LRU_SORT) +=3D lru_sort.o diff --git a/mm/damon/sysfs-common.h b/mm/damon/sysfs-common.h index 56e6a99e353b..4626b2784404 100644 --- a/mm/damon/sysfs-common.h +++ b/mm/damon/sysfs-common.h @@ -22,3 +22,25 @@ struct damon_sysfs_ul_range *damon_sysfs_ul_range_alloc( void damon_sysfs_ul_range_release(struct kobject *kobj); =20 extern struct kobj_type damon_sysfs_ul_range_ktype; + +/* + * schemes directory + */ + +struct damon_sysfs_schemes { + struct kobject kobj; + struct damon_sysfs_scheme **schemes_arr; + int nr; +}; + +struct damon_sysfs_schemes *damon_sysfs_schemes_alloc(void); +void damon_sysfs_schemes_rm_dirs(struct damon_sysfs_schemes *schemes); + +extern struct kobj_type damon_sysfs_schemes_ktype; + +int damon_sysfs_set_schemes(struct damon_ctx *ctx, + struct damon_sysfs_schemes *sysfs_schemes); + +void damon_sysfs_schemes_update_stats( + struct damon_sysfs_schemes *sysfs_schemes, + struct damon_ctx *ctx); diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c new file mode 100644 index 000000000000..7ea4bcce90cb --- /dev/null +++ b/mm/damon/sysfs-schemes.c @@ -0,0 +1,1022 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DAMON sysfs Interface + * + * Copyright (c) 2022 SeongJae Park + */ + +#include + +#include "sysfs-common.h" + +/* + * schemes/stats directory + */ + +struct damon_sysfs_stats { + struct kobject kobj; + unsigned long nr_tried; + unsigned long sz_tried; + unsigned long nr_applied; + unsigned long sz_applied; + unsigned long qt_exceeds; +}; + +static struct damon_sysfs_stats *damon_sysfs_stats_alloc(void) +{ + return kzalloc(sizeof(struct damon_sysfs_stats), GFP_KERNEL); +} + +static ssize_t nr_tried_show(struct kobject *kobj, struct kobj_attribute *= attr, + char *buf) +{ + struct damon_sysfs_stats *stats =3D container_of(kobj, + struct damon_sysfs_stats, kobj); + + return sysfs_emit(buf, "%lu\n", stats->nr_tried); +} + +static ssize_t sz_tried_show(struct kobject *kobj, struct kobj_attribute *= attr, + char *buf) +{ + struct damon_sysfs_stats *stats =3D container_of(kobj, + struct damon_sysfs_stats, kobj); + + return sysfs_emit(buf, "%lu\n", stats->sz_tried); +} + +static ssize_t nr_applied_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_stats *stats =3D container_of(kobj, + struct damon_sysfs_stats, kobj); + + return sysfs_emit(buf, "%lu\n", stats->nr_applied); +} + +static ssize_t sz_applied_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_stats *stats =3D container_of(kobj, + struct damon_sysfs_stats, kobj); + + return sysfs_emit(buf, "%lu\n", stats->sz_applied); +} + +static ssize_t qt_exceeds_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_stats *stats =3D container_of(kobj, + struct damon_sysfs_stats, kobj); + + return sysfs_emit(buf, "%lu\n", stats->qt_exceeds); +} + +static void damon_sysfs_stats_release(struct kobject *kobj) +{ + kfree(container_of(kobj, struct damon_sysfs_stats, kobj)); +} + +static struct kobj_attribute damon_sysfs_stats_nr_tried_attr =3D + __ATTR_RO_MODE(nr_tried, 0400); + +static struct kobj_attribute damon_sysfs_stats_sz_tried_attr =3D + __ATTR_RO_MODE(sz_tried, 0400); + +static struct kobj_attribute damon_sysfs_stats_nr_applied_attr =3D + __ATTR_RO_MODE(nr_applied, 0400); + +static struct kobj_attribute damon_sysfs_stats_sz_applied_attr =3D + __ATTR_RO_MODE(sz_applied, 0400); + +static struct kobj_attribute damon_sysfs_stats_qt_exceeds_attr =3D + __ATTR_RO_MODE(qt_exceeds, 0400); + +static struct attribute *damon_sysfs_stats_attrs[] =3D { + &damon_sysfs_stats_nr_tried_attr.attr, + &damon_sysfs_stats_sz_tried_attr.attr, + &damon_sysfs_stats_nr_applied_attr.attr, + &damon_sysfs_stats_sz_applied_attr.attr, + &damon_sysfs_stats_qt_exceeds_attr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(damon_sysfs_stats); + +static struct kobj_type damon_sysfs_stats_ktype =3D { + .release =3D damon_sysfs_stats_release, + .sysfs_ops =3D &kobj_sysfs_ops, + .default_groups =3D damon_sysfs_stats_groups, +}; + +/* + * watermarks directory + */ + +struct damon_sysfs_watermarks { + struct kobject kobj; + enum damos_wmark_metric metric; + unsigned long interval_us; + unsigned long high; + unsigned long mid; + unsigned long low; +}; + +static struct damon_sysfs_watermarks *damon_sysfs_watermarks_alloc( + enum damos_wmark_metric metric, unsigned long interval_us, + unsigned long high, unsigned long mid, unsigned long low) +{ + struct damon_sysfs_watermarks *watermarks =3D kmalloc( + sizeof(*watermarks), GFP_KERNEL); + + if (!watermarks) + return NULL; + watermarks->kobj =3D (struct kobject){}; + watermarks->metric =3D metric; + watermarks->interval_us =3D interval_us; + watermarks->high =3D high; + watermarks->mid =3D mid; + watermarks->low =3D low; + return watermarks; +} + +/* Should match with enum damos_wmark_metric */ +static const char * const damon_sysfs_wmark_metric_strs[] =3D { + "none", + "free_mem_rate", +}; + +static ssize_t metric_show(struct kobject *kobj, struct kobj_attribute *at= tr, + char *buf) +{ + struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, + struct damon_sysfs_watermarks, kobj); + + return sysfs_emit(buf, "%s\n", + damon_sysfs_wmark_metric_strs[watermarks->metric]); +} + +static ssize_t metric_store(struct kobject *kobj, struct kobj_attribute *a= ttr, + const char *buf, size_t count) +{ + struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, + struct damon_sysfs_watermarks, kobj); + enum damos_wmark_metric metric; + + for (metric =3D 0; metric < NR_DAMOS_WMARK_METRICS; metric++) { + if (sysfs_streq(buf, damon_sysfs_wmark_metric_strs[metric])) { + watermarks->metric =3D metric; + return count; + } + } + return -EINVAL; +} + +static ssize_t interval_us_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, + struct damon_sysfs_watermarks, kobj); + + return sysfs_emit(buf, "%lu\n", watermarks->interval_us); +} + +static ssize_t interval_us_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, + struct damon_sysfs_watermarks, kobj); + int err =3D kstrtoul(buf, 0, &watermarks->interval_us); + + return err ? err : count; +} + +static ssize_t high_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, + struct damon_sysfs_watermarks, kobj); + + return sysfs_emit(buf, "%lu\n", watermarks->high); +} + +static ssize_t high_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, + struct damon_sysfs_watermarks, kobj); + int err =3D kstrtoul(buf, 0, &watermarks->high); + + return err ? err : count; +} + +static ssize_t mid_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, + struct damon_sysfs_watermarks, kobj); + + return sysfs_emit(buf, "%lu\n", watermarks->mid); +} + +static ssize_t mid_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, + struct damon_sysfs_watermarks, kobj); + int err =3D kstrtoul(buf, 0, &watermarks->mid); + + return err ? err : count; +} + +static ssize_t low_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, + struct damon_sysfs_watermarks, kobj); + + return sysfs_emit(buf, "%lu\n", watermarks->low); +} + +static ssize_t low_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, + struct damon_sysfs_watermarks, kobj); + int err =3D kstrtoul(buf, 0, &watermarks->low); + + return err ? err : count; +} + +static void damon_sysfs_watermarks_release(struct kobject *kobj) +{ + kfree(container_of(kobj, struct damon_sysfs_watermarks, kobj)); +} + +static struct kobj_attribute damon_sysfs_watermarks_metric_attr =3D + __ATTR_RW_MODE(metric, 0600); + +static struct kobj_attribute damon_sysfs_watermarks_interval_us_attr =3D + __ATTR_RW_MODE(interval_us, 0600); + +static struct kobj_attribute damon_sysfs_watermarks_high_attr =3D + __ATTR_RW_MODE(high, 0600); + +static struct kobj_attribute damon_sysfs_watermarks_mid_attr =3D + __ATTR_RW_MODE(mid, 0600); + +static struct kobj_attribute damon_sysfs_watermarks_low_attr =3D + __ATTR_RW_MODE(low, 0600); + +static struct attribute *damon_sysfs_watermarks_attrs[] =3D { + &damon_sysfs_watermarks_metric_attr.attr, + &damon_sysfs_watermarks_interval_us_attr.attr, + &damon_sysfs_watermarks_high_attr.attr, + &damon_sysfs_watermarks_mid_attr.attr, + &damon_sysfs_watermarks_low_attr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(damon_sysfs_watermarks); + +static struct kobj_type damon_sysfs_watermarks_ktype =3D { + .release =3D damon_sysfs_watermarks_release, + .sysfs_ops =3D &kobj_sysfs_ops, + .default_groups =3D damon_sysfs_watermarks_groups, +}; + +/* + * scheme/weights directory + */ + +struct damon_sysfs_weights { + struct kobject kobj; + unsigned int sz; + unsigned int nr_accesses; + unsigned int age; +}; + +static struct damon_sysfs_weights *damon_sysfs_weights_alloc(unsigned int = sz, + unsigned int nr_accesses, unsigned int age) +{ + struct damon_sysfs_weights *weights =3D kmalloc(sizeof(*weights), + GFP_KERNEL); + + if (!weights) + return NULL; + weights->kobj =3D (struct kobject){}; + weights->sz =3D sz; + weights->nr_accesses =3D nr_accesses; + weights->age =3D age; + return weights; +} + +static ssize_t sz_permil_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_weights *weights =3D container_of(kobj, + struct damon_sysfs_weights, kobj); + + return sysfs_emit(buf, "%u\n", weights->sz); +} + +static ssize_t sz_permil_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_weights *weights =3D container_of(kobj, + struct damon_sysfs_weights, kobj); + int err =3D kstrtouint(buf, 0, &weights->sz); + + return err ? err : count; +} + +static ssize_t nr_accesses_permil_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_weights *weights =3D container_of(kobj, + struct damon_sysfs_weights, kobj); + + return sysfs_emit(buf, "%u\n", weights->nr_accesses); +} + +static ssize_t nr_accesses_permil_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_weights *weights =3D container_of(kobj, + struct damon_sysfs_weights, kobj); + int err =3D kstrtouint(buf, 0, &weights->nr_accesses); + + return err ? err : count; +} + +static ssize_t age_permil_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_weights *weights =3D container_of(kobj, + struct damon_sysfs_weights, kobj); + + return sysfs_emit(buf, "%u\n", weights->age); +} + +static ssize_t age_permil_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_weights *weights =3D container_of(kobj, + struct damon_sysfs_weights, kobj); + int err =3D kstrtouint(buf, 0, &weights->age); + + return err ? err : count; +} + +static void damon_sysfs_weights_release(struct kobject *kobj) +{ + kfree(container_of(kobj, struct damon_sysfs_weights, kobj)); +} + +static struct kobj_attribute damon_sysfs_weights_sz_attr =3D + __ATTR_RW_MODE(sz_permil, 0600); + +static struct kobj_attribute damon_sysfs_weights_nr_accesses_attr =3D + __ATTR_RW_MODE(nr_accesses_permil, 0600); + +static struct kobj_attribute damon_sysfs_weights_age_attr =3D + __ATTR_RW_MODE(age_permil, 0600); + +static struct attribute *damon_sysfs_weights_attrs[] =3D { + &damon_sysfs_weights_sz_attr.attr, + &damon_sysfs_weights_nr_accesses_attr.attr, + &damon_sysfs_weights_age_attr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(damon_sysfs_weights); + +static struct kobj_type damon_sysfs_weights_ktype =3D { + .release =3D damon_sysfs_weights_release, + .sysfs_ops =3D &kobj_sysfs_ops, + .default_groups =3D damon_sysfs_weights_groups, +}; + +/* + * quotas directory + */ + +struct damon_sysfs_quotas { + struct kobject kobj; + struct damon_sysfs_weights *weights; + unsigned long ms; + unsigned long sz; + unsigned long reset_interval_ms; +}; + +static struct damon_sysfs_quotas *damon_sysfs_quotas_alloc(void) +{ + return kzalloc(sizeof(struct damon_sysfs_quotas), GFP_KERNEL); +} + +static int damon_sysfs_quotas_add_dirs(struct damon_sysfs_quotas *quotas) +{ + struct damon_sysfs_weights *weights; + int err; + + weights =3D damon_sysfs_weights_alloc(0, 0, 0); + if (!weights) + return -ENOMEM; + + err =3D kobject_init_and_add(&weights->kobj, &damon_sysfs_weights_ktype, + "as->kobj, "weights"); + if (err) + kobject_put(&weights->kobj); + else + quotas->weights =3D weights; + return err; +} + +static void damon_sysfs_quotas_rm_dirs(struct damon_sysfs_quotas *quotas) +{ + kobject_put("as->weights->kobj); +} + +static ssize_t ms_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct damon_sysfs_quotas *quotas =3D container_of(kobj, + struct damon_sysfs_quotas, kobj); + + return sysfs_emit(buf, "%lu\n", quotas->ms); +} + +static ssize_t ms_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct damon_sysfs_quotas *quotas =3D container_of(kobj, + struct damon_sysfs_quotas, kobj); + int err =3D kstrtoul(buf, 0, "as->ms); + + if (err) + return -EINVAL; + return count; +} + +static ssize_t bytes_show(struct kobject *kobj, struct kobj_attribute *att= r, + char *buf) +{ + struct damon_sysfs_quotas *quotas =3D container_of(kobj, + struct damon_sysfs_quotas, kobj); + + return sysfs_emit(buf, "%lu\n", quotas->sz); +} + +static ssize_t bytes_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_quotas *quotas =3D container_of(kobj, + struct damon_sysfs_quotas, kobj); + int err =3D kstrtoul(buf, 0, "as->sz); + + if (err) + return -EINVAL; + return count; +} + +static ssize_t reset_interval_ms_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_quotas *quotas =3D container_of(kobj, + struct damon_sysfs_quotas, kobj); + + return sysfs_emit(buf, "%lu\n", quotas->reset_interval_ms); +} + +static ssize_t reset_interval_ms_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_quotas *quotas =3D container_of(kobj, + struct damon_sysfs_quotas, kobj); + int err =3D kstrtoul(buf, 0, "as->reset_interval_ms); + + if (err) + return -EINVAL; + return count; +} + +static void damon_sysfs_quotas_release(struct kobject *kobj) +{ + kfree(container_of(kobj, struct damon_sysfs_quotas, kobj)); +} + +static struct kobj_attribute damon_sysfs_quotas_ms_attr =3D + __ATTR_RW_MODE(ms, 0600); + +static struct kobj_attribute damon_sysfs_quotas_sz_attr =3D + __ATTR_RW_MODE(bytes, 0600); + +static struct kobj_attribute damon_sysfs_quotas_reset_interval_ms_attr =3D + __ATTR_RW_MODE(reset_interval_ms, 0600); + +static struct attribute *damon_sysfs_quotas_attrs[] =3D { + &damon_sysfs_quotas_ms_attr.attr, + &damon_sysfs_quotas_sz_attr.attr, + &damon_sysfs_quotas_reset_interval_ms_attr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(damon_sysfs_quotas); + +static struct kobj_type damon_sysfs_quotas_ktype =3D { + .release =3D damon_sysfs_quotas_release, + .sysfs_ops =3D &kobj_sysfs_ops, + .default_groups =3D damon_sysfs_quotas_groups, +}; + +/* + * access_pattern directory + */ + +struct damon_sysfs_access_pattern { + struct kobject kobj; + struct damon_sysfs_ul_range *sz; + struct damon_sysfs_ul_range *nr_accesses; + struct damon_sysfs_ul_range *age; +}; + +static +struct damon_sysfs_access_pattern *damon_sysfs_access_pattern_alloc(void) +{ + struct damon_sysfs_access_pattern *access_pattern =3D + kmalloc(sizeof(*access_pattern), GFP_KERNEL); + + if (!access_pattern) + return NULL; + access_pattern->kobj =3D (struct kobject){}; + return access_pattern; +} + +static int damon_sysfs_access_pattern_add_range_dir( + struct damon_sysfs_access_pattern *access_pattern, + struct damon_sysfs_ul_range **range_dir_ptr, + char *name) +{ + struct damon_sysfs_ul_range *range =3D damon_sysfs_ul_range_alloc(0, 0); + int err; + + if (!range) + return -ENOMEM; + err =3D kobject_init_and_add(&range->kobj, &damon_sysfs_ul_range_ktype, + &access_pattern->kobj, name); + if (err) + kobject_put(&range->kobj); + else + *range_dir_ptr =3D range; + return err; +} + +static int damon_sysfs_access_pattern_add_dirs( + struct damon_sysfs_access_pattern *access_pattern) +{ + int err; + + err =3D damon_sysfs_access_pattern_add_range_dir(access_pattern, + &access_pattern->sz, "sz"); + if (err) + goto put_sz_out; + + err =3D damon_sysfs_access_pattern_add_range_dir(access_pattern, + &access_pattern->nr_accesses, "nr_accesses"); + if (err) + goto put_nr_accesses_sz_out; + + err =3D damon_sysfs_access_pattern_add_range_dir(access_pattern, + &access_pattern->age, "age"); + if (err) + goto put_age_nr_accesses_sz_out; + return 0; + +put_age_nr_accesses_sz_out: + kobject_put(&access_pattern->age->kobj); + access_pattern->age =3D NULL; +put_nr_accesses_sz_out: + kobject_put(&access_pattern->nr_accesses->kobj); + access_pattern->nr_accesses =3D NULL; +put_sz_out: + kobject_put(&access_pattern->sz->kobj); + access_pattern->sz =3D NULL; + return err; +} + +static void damon_sysfs_access_pattern_rm_dirs( + struct damon_sysfs_access_pattern *access_pattern) +{ + kobject_put(&access_pattern->sz->kobj); + kobject_put(&access_pattern->nr_accesses->kobj); + kobject_put(&access_pattern->age->kobj); +} + +static void damon_sysfs_access_pattern_release(struct kobject *kobj) +{ + kfree(container_of(kobj, struct damon_sysfs_access_pattern, kobj)); +} + +static struct attribute *damon_sysfs_access_pattern_attrs[] =3D { + NULL, +}; +ATTRIBUTE_GROUPS(damon_sysfs_access_pattern); + +static struct kobj_type damon_sysfs_access_pattern_ktype =3D { + .release =3D damon_sysfs_access_pattern_release, + .sysfs_ops =3D &kobj_sysfs_ops, + .default_groups =3D damon_sysfs_access_pattern_groups, +}; + +/* + * scheme directory + */ + +struct damon_sysfs_scheme { + struct kobject kobj; + enum damos_action action; + struct damon_sysfs_access_pattern *access_pattern; + struct damon_sysfs_quotas *quotas; + struct damon_sysfs_watermarks *watermarks; + struct damon_sysfs_stats *stats; +}; + +/* This should match with enum damos_action */ +static const char * const damon_sysfs_damos_action_strs[] =3D { + "willneed", + "cold", + "pageout", + "hugepage", + "nohugepage", + "lru_prio", + "lru_deprio", + "stat", +}; + +static struct damon_sysfs_scheme *damon_sysfs_scheme_alloc( + enum damos_action action) +{ + struct damon_sysfs_scheme *scheme =3D kmalloc(sizeof(*scheme), + GFP_KERNEL); + + if (!scheme) + return NULL; + scheme->kobj =3D (struct kobject){}; + scheme->action =3D action; + return scheme; +} + +static int damon_sysfs_scheme_set_access_pattern( + struct damon_sysfs_scheme *scheme) +{ + struct damon_sysfs_access_pattern *access_pattern; + int err; + + access_pattern =3D damon_sysfs_access_pattern_alloc(); + if (!access_pattern) + return -ENOMEM; + err =3D kobject_init_and_add(&access_pattern->kobj, + &damon_sysfs_access_pattern_ktype, &scheme->kobj, + "access_pattern"); + if (err) + goto out; + err =3D damon_sysfs_access_pattern_add_dirs(access_pattern); + if (err) + goto out; + scheme->access_pattern =3D access_pattern; + return 0; + +out: + kobject_put(&access_pattern->kobj); + return err; +} + +static int damon_sysfs_scheme_set_quotas(struct damon_sysfs_scheme *scheme) +{ + struct damon_sysfs_quotas *quotas =3D damon_sysfs_quotas_alloc(); + int err; + + if (!quotas) + return -ENOMEM; + err =3D kobject_init_and_add("as->kobj, &damon_sysfs_quotas_ktype, + &scheme->kobj, "quotas"); + if (err) + goto out; + err =3D damon_sysfs_quotas_add_dirs(quotas); + if (err) + goto out; + scheme->quotas =3D quotas; + return 0; + +out: + kobject_put("as->kobj); + return err; +} + +static int damon_sysfs_scheme_set_watermarks(struct damon_sysfs_scheme *sc= heme) +{ + struct damon_sysfs_watermarks *watermarks =3D + damon_sysfs_watermarks_alloc(DAMOS_WMARK_NONE, 0, 0, 0, 0); + int err; + + if (!watermarks) + return -ENOMEM; + err =3D kobject_init_and_add(&watermarks->kobj, + &damon_sysfs_watermarks_ktype, &scheme->kobj, + "watermarks"); + if (err) + kobject_put(&watermarks->kobj); + else + scheme->watermarks =3D watermarks; + return err; +} + +static int damon_sysfs_scheme_set_stats(struct damon_sysfs_scheme *scheme) +{ + struct damon_sysfs_stats *stats =3D damon_sysfs_stats_alloc(); + int err; + + if (!stats) + return -ENOMEM; + err =3D kobject_init_and_add(&stats->kobj, &damon_sysfs_stats_ktype, + &scheme->kobj, "stats"); + if (err) + kobject_put(&stats->kobj); + else + scheme->stats =3D stats; + return err; +} + +static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme) +{ + int err; + + err =3D damon_sysfs_scheme_set_access_pattern(scheme); + if (err) + return err; + err =3D damon_sysfs_scheme_set_quotas(scheme); + if (err) + goto put_access_pattern_out; + err =3D damon_sysfs_scheme_set_watermarks(scheme); + if (err) + goto put_quotas_access_pattern_out; + err =3D damon_sysfs_scheme_set_stats(scheme); + if (err) + goto put_watermarks_quotas_access_pattern_out; + return 0; + +put_watermarks_quotas_access_pattern_out: + kobject_put(&scheme->watermarks->kobj); + scheme->watermarks =3D NULL; +put_quotas_access_pattern_out: + kobject_put(&scheme->quotas->kobj); + scheme->quotas =3D NULL; +put_access_pattern_out: + kobject_put(&scheme->access_pattern->kobj); + scheme->access_pattern =3D NULL; + return err; +} + +static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme) +{ + damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern); + kobject_put(&scheme->access_pattern->kobj); + damon_sysfs_quotas_rm_dirs(scheme->quotas); + kobject_put(&scheme->quotas->kobj); + kobject_put(&scheme->watermarks->kobj); + kobject_put(&scheme->stats->kobj); +} + +static ssize_t action_show(struct kobject *kobj, struct kobj_attribute *at= tr, + char *buf) +{ + struct damon_sysfs_scheme *scheme =3D container_of(kobj, + struct damon_sysfs_scheme, kobj); + + return sysfs_emit(buf, "%s\n", + damon_sysfs_damos_action_strs[scheme->action]); +} + +static ssize_t action_store(struct kobject *kobj, struct kobj_attribute *a= ttr, + const char *buf, size_t count) +{ + struct damon_sysfs_scheme *scheme =3D container_of(kobj, + struct damon_sysfs_scheme, kobj); + enum damos_action action; + + for (action =3D 0; action < NR_DAMOS_ACTIONS; action++) { + if (sysfs_streq(buf, damon_sysfs_damos_action_strs[action])) { + scheme->action =3D action; + return count; + } + } + return -EINVAL; +} + +static void damon_sysfs_scheme_release(struct kobject *kobj) +{ + kfree(container_of(kobj, struct damon_sysfs_scheme, kobj)); +} + +static struct kobj_attribute damon_sysfs_scheme_action_attr =3D + __ATTR_RW_MODE(action, 0600); + +static struct attribute *damon_sysfs_scheme_attrs[] =3D { + &damon_sysfs_scheme_action_attr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(damon_sysfs_scheme); + +static struct kobj_type damon_sysfs_scheme_ktype =3D { + .release =3D damon_sysfs_scheme_release, + .sysfs_ops =3D &kobj_sysfs_ops, + .default_groups =3D damon_sysfs_scheme_groups, +}; + +/* + * schemes directory + */ + +struct damon_sysfs_schemes *damon_sysfs_schemes_alloc(void) +{ + return kzalloc(sizeof(struct damon_sysfs_schemes), GFP_KERNEL); +} + +void damon_sysfs_schemes_rm_dirs(struct damon_sysfs_schemes *schemes) +{ + struct damon_sysfs_scheme **schemes_arr =3D schemes->schemes_arr; + int i; + + for (i =3D 0; i < schemes->nr; i++) { + damon_sysfs_scheme_rm_dirs(schemes_arr[i]); + kobject_put(&schemes_arr[i]->kobj); + } + schemes->nr =3D 0; + kfree(schemes_arr); + schemes->schemes_arr =3D NULL; +} + +static int damon_sysfs_schemes_add_dirs(struct damon_sysfs_schemes *scheme= s, + int nr_schemes) +{ + struct damon_sysfs_scheme **schemes_arr, *scheme; + int err, i; + + damon_sysfs_schemes_rm_dirs(schemes); + if (!nr_schemes) + return 0; + + schemes_arr =3D kmalloc_array(nr_schemes, sizeof(*schemes_arr), + GFP_KERNEL | __GFP_NOWARN); + if (!schemes_arr) + return -ENOMEM; + schemes->schemes_arr =3D schemes_arr; + + for (i =3D 0; i < nr_schemes; i++) { + scheme =3D damon_sysfs_scheme_alloc(DAMOS_STAT); + if (!scheme) { + damon_sysfs_schemes_rm_dirs(schemes); + return -ENOMEM; + } + + err =3D kobject_init_and_add(&scheme->kobj, + &damon_sysfs_scheme_ktype, &schemes->kobj, + "%d", i); + if (err) + goto out; + err =3D damon_sysfs_scheme_add_dirs(scheme); + if (err) + goto out; + + schemes_arr[i] =3D scheme; + schemes->nr++; + } + return 0; + +out: + damon_sysfs_schemes_rm_dirs(schemes); + kobject_put(&scheme->kobj); + return err; +} + +static ssize_t nr_schemes_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct damon_sysfs_schemes *schemes =3D container_of(kobj, + struct damon_sysfs_schemes, kobj); + + return sysfs_emit(buf, "%d\n", schemes->nr); +} + +static ssize_t nr_schemes_store(struct kobject *kobj, + struct kobj_attribute *attr, const char *buf, size_t count) +{ + struct damon_sysfs_schemes *schemes; + int nr, err =3D kstrtoint(buf, 0, &nr); + + if (err) + return err; + if (nr < 0) + return -EINVAL; + + schemes =3D container_of(kobj, struct damon_sysfs_schemes, kobj); + + if (!mutex_trylock(&damon_sysfs_lock)) + return -EBUSY; + err =3D damon_sysfs_schemes_add_dirs(schemes, nr); + mutex_unlock(&damon_sysfs_lock); + if (err) + return err; + return count; +} + +static void damon_sysfs_schemes_release(struct kobject *kobj) +{ + kfree(container_of(kobj, struct damon_sysfs_schemes, kobj)); +} + +static struct kobj_attribute damon_sysfs_schemes_nr_attr =3D + __ATTR_RW_MODE(nr_schemes, 0600); + +static struct attribute *damon_sysfs_schemes_attrs[] =3D { + &damon_sysfs_schemes_nr_attr.attr, + NULL, +}; +ATTRIBUTE_GROUPS(damon_sysfs_schemes); + +struct kobj_type damon_sysfs_schemes_ktype =3D { + .release =3D damon_sysfs_schemes_release, + .sysfs_ops =3D &kobj_sysfs_ops, + .default_groups =3D damon_sysfs_schemes_groups, +}; + +static struct damos *damon_sysfs_mk_scheme( + struct damon_sysfs_scheme *sysfs_scheme) +{ + struct damon_sysfs_access_pattern *access_pattern =3D + sysfs_scheme->access_pattern; + struct damon_sysfs_quotas *sysfs_quotas =3D sysfs_scheme->quotas; + struct damon_sysfs_weights *sysfs_weights =3D sysfs_quotas->weights; + struct damon_sysfs_watermarks *sysfs_wmarks =3D sysfs_scheme->watermarks; + + struct damos_access_pattern pattern =3D { + .min_sz_region =3D access_pattern->sz->min, + .max_sz_region =3D access_pattern->sz->max, + .min_nr_accesses =3D access_pattern->nr_accesses->min, + .max_nr_accesses =3D access_pattern->nr_accesses->max, + .min_age_region =3D access_pattern->age->min, + .max_age_region =3D access_pattern->age->max, + }; + struct damos_quota quota =3D { + .ms =3D sysfs_quotas->ms, + .sz =3D sysfs_quotas->sz, + .reset_interval =3D sysfs_quotas->reset_interval_ms, + .weight_sz =3D sysfs_weights->sz, + .weight_nr_accesses =3D sysfs_weights->nr_accesses, + .weight_age =3D sysfs_weights->age, + }; + struct damos_watermarks wmarks =3D { + .metric =3D sysfs_wmarks->metric, + .interval =3D sysfs_wmarks->interval_us, + .high =3D sysfs_wmarks->high, + .mid =3D sysfs_wmarks->mid, + .low =3D sysfs_wmarks->low, + }; + + return damon_new_scheme(&pattern, sysfs_scheme->action, "a, + &wmarks); +} + +int damon_sysfs_set_schemes(struct damon_ctx *ctx, + struct damon_sysfs_schemes *sysfs_schemes) +{ + int i; + + for (i =3D 0; i < sysfs_schemes->nr; i++) { + struct damos *scheme, *next; + + scheme =3D damon_sysfs_mk_scheme(sysfs_schemes->schemes_arr[i]); + if (!scheme) { + damon_for_each_scheme_safe(scheme, next, ctx) + damon_destroy_scheme(scheme); + return -ENOMEM; + } + damon_add_scheme(ctx, scheme); + } + return 0; +} + +void damon_sysfs_schemes_update_stats( + struct damon_sysfs_schemes *sysfs_schemes, + struct damon_ctx *ctx) +{ + struct damos *scheme; + int schemes_idx =3D 0; + + damon_for_each_scheme(scheme, ctx) { + struct damon_sysfs_stats *sysfs_stats; + + sysfs_stats =3D sysfs_schemes->schemes_arr[schemes_idx++]->stats; + sysfs_stats->nr_tried =3D scheme->stat.nr_tried; + sysfs_stats->sz_tried =3D scheme->stat.sz_tried; + sysfs_stats->nr_applied =3D scheme->stat.nr_applied; + sysfs_stats->sz_applied =3D scheme->stat.sz_applied; + sysfs_stats->qt_exceeds =3D scheme->stat.qt_exceeds; + } +} diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c index 082c55e68e0e..284daf274b3e 100644 --- a/mm/damon/sysfs.c +++ b/mm/damon/sysfs.c @@ -11,949 +11,6 @@ =20 #include "sysfs-common.h" =20 -/* - * schemes/stats directory - */ - -struct damon_sysfs_stats { - struct kobject kobj; - unsigned long nr_tried; - unsigned long sz_tried; - unsigned long nr_applied; - unsigned long sz_applied; - unsigned long qt_exceeds; -}; - -static struct damon_sysfs_stats *damon_sysfs_stats_alloc(void) -{ - return kzalloc(sizeof(struct damon_sysfs_stats), GFP_KERNEL); -} - -static ssize_t nr_tried_show(struct kobject *kobj, struct kobj_attribute *= attr, - char *buf) -{ - struct damon_sysfs_stats *stats =3D container_of(kobj, - struct damon_sysfs_stats, kobj); - - return sysfs_emit(buf, "%lu\n", stats->nr_tried); -} - -static ssize_t sz_tried_show(struct kobject *kobj, struct kobj_attribute *= attr, - char *buf) -{ - struct damon_sysfs_stats *stats =3D container_of(kobj, - struct damon_sysfs_stats, kobj); - - return sysfs_emit(buf, "%lu\n", stats->sz_tried); -} - -static ssize_t nr_applied_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_stats *stats =3D container_of(kobj, - struct damon_sysfs_stats, kobj); - - return sysfs_emit(buf, "%lu\n", stats->nr_applied); -} - -static ssize_t sz_applied_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_stats *stats =3D container_of(kobj, - struct damon_sysfs_stats, kobj); - - return sysfs_emit(buf, "%lu\n", stats->sz_applied); -} - -static ssize_t qt_exceeds_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_stats *stats =3D container_of(kobj, - struct damon_sysfs_stats, kobj); - - return sysfs_emit(buf, "%lu\n", stats->qt_exceeds); -} - -static void damon_sysfs_stats_release(struct kobject *kobj) -{ - kfree(container_of(kobj, struct damon_sysfs_stats, kobj)); -} - -static struct kobj_attribute damon_sysfs_stats_nr_tried_attr =3D - __ATTR_RO_MODE(nr_tried, 0400); - -static struct kobj_attribute damon_sysfs_stats_sz_tried_attr =3D - __ATTR_RO_MODE(sz_tried, 0400); - -static struct kobj_attribute damon_sysfs_stats_nr_applied_attr =3D - __ATTR_RO_MODE(nr_applied, 0400); - -static struct kobj_attribute damon_sysfs_stats_sz_applied_attr =3D - __ATTR_RO_MODE(sz_applied, 0400); - -static struct kobj_attribute damon_sysfs_stats_qt_exceeds_attr =3D - __ATTR_RO_MODE(qt_exceeds, 0400); - -static struct attribute *damon_sysfs_stats_attrs[] =3D { - &damon_sysfs_stats_nr_tried_attr.attr, - &damon_sysfs_stats_sz_tried_attr.attr, - &damon_sysfs_stats_nr_applied_attr.attr, - &damon_sysfs_stats_sz_applied_attr.attr, - &damon_sysfs_stats_qt_exceeds_attr.attr, - NULL, -}; -ATTRIBUTE_GROUPS(damon_sysfs_stats); - -static struct kobj_type damon_sysfs_stats_ktype =3D { - .release =3D damon_sysfs_stats_release, - .sysfs_ops =3D &kobj_sysfs_ops, - .default_groups =3D damon_sysfs_stats_groups, -}; - -/* - * watermarks directory - */ - -struct damon_sysfs_watermarks { - struct kobject kobj; - enum damos_wmark_metric metric; - unsigned long interval_us; - unsigned long high; - unsigned long mid; - unsigned long low; -}; - -static struct damon_sysfs_watermarks *damon_sysfs_watermarks_alloc( - enum damos_wmark_metric metric, unsigned long interval_us, - unsigned long high, unsigned long mid, unsigned long low) -{ - struct damon_sysfs_watermarks *watermarks =3D kmalloc( - sizeof(*watermarks), GFP_KERNEL); - - if (!watermarks) - return NULL; - watermarks->kobj =3D (struct kobject){}; - watermarks->metric =3D metric; - watermarks->interval_us =3D interval_us; - watermarks->high =3D high; - watermarks->mid =3D mid; - watermarks->low =3D low; - return watermarks; -} - -/* Should match with enum damos_wmark_metric */ -static const char * const damon_sysfs_wmark_metric_strs[] =3D { - "none", - "free_mem_rate", -}; - -static ssize_t metric_show(struct kobject *kobj, struct kobj_attribute *at= tr, - char *buf) -{ - struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, - struct damon_sysfs_watermarks, kobj); - - return sysfs_emit(buf, "%s\n", - damon_sysfs_wmark_metric_strs[watermarks->metric]); -} - -static ssize_t metric_store(struct kobject *kobj, struct kobj_attribute *a= ttr, - const char *buf, size_t count) -{ - struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, - struct damon_sysfs_watermarks, kobj); - enum damos_wmark_metric metric; - - for (metric =3D 0; metric < NR_DAMOS_WMARK_METRICS; metric++) { - if (sysfs_streq(buf, damon_sysfs_wmark_metric_strs[metric])) { - watermarks->metric =3D metric; - return count; - } - } - return -EINVAL; -} - -static ssize_t interval_us_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, - struct damon_sysfs_watermarks, kobj); - - return sysfs_emit(buf, "%lu\n", watermarks->interval_us); -} - -static ssize_t interval_us_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, - struct damon_sysfs_watermarks, kobj); - int err =3D kstrtoul(buf, 0, &watermarks->interval_us); - - return err ? err : count; -} - -static ssize_t high_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, - struct damon_sysfs_watermarks, kobj); - - return sysfs_emit(buf, "%lu\n", watermarks->high); -} - -static ssize_t high_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, - struct damon_sysfs_watermarks, kobj); - int err =3D kstrtoul(buf, 0, &watermarks->high); - - return err ? err : count; -} - -static ssize_t mid_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, - struct damon_sysfs_watermarks, kobj); - - return sysfs_emit(buf, "%lu\n", watermarks->mid); -} - -static ssize_t mid_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, - struct damon_sysfs_watermarks, kobj); - int err =3D kstrtoul(buf, 0, &watermarks->mid); - - return err ? err : count; -} - -static ssize_t low_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, - struct damon_sysfs_watermarks, kobj); - - return sysfs_emit(buf, "%lu\n", watermarks->low); -} - -static ssize_t low_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct damon_sysfs_watermarks *watermarks =3D container_of(kobj, - struct damon_sysfs_watermarks, kobj); - int err =3D kstrtoul(buf, 0, &watermarks->low); - - return err ? err : count; -} - -static void damon_sysfs_watermarks_release(struct kobject *kobj) -{ - kfree(container_of(kobj, struct damon_sysfs_watermarks, kobj)); -} - -static struct kobj_attribute damon_sysfs_watermarks_metric_attr =3D - __ATTR_RW_MODE(metric, 0600); - -static struct kobj_attribute damon_sysfs_watermarks_interval_us_attr =3D - __ATTR_RW_MODE(interval_us, 0600); - -static struct kobj_attribute damon_sysfs_watermarks_high_attr =3D - __ATTR_RW_MODE(high, 0600); - -static struct kobj_attribute damon_sysfs_watermarks_mid_attr =3D - __ATTR_RW_MODE(mid, 0600); - -static struct kobj_attribute damon_sysfs_watermarks_low_attr =3D - __ATTR_RW_MODE(low, 0600); - -static struct attribute *damon_sysfs_watermarks_attrs[] =3D { - &damon_sysfs_watermarks_metric_attr.attr, - &damon_sysfs_watermarks_interval_us_attr.attr, - &damon_sysfs_watermarks_high_attr.attr, - &damon_sysfs_watermarks_mid_attr.attr, - &damon_sysfs_watermarks_low_attr.attr, - NULL, -}; -ATTRIBUTE_GROUPS(damon_sysfs_watermarks); - -static struct kobj_type damon_sysfs_watermarks_ktype =3D { - .release =3D damon_sysfs_watermarks_release, - .sysfs_ops =3D &kobj_sysfs_ops, - .default_groups =3D damon_sysfs_watermarks_groups, -}; - -/* - * scheme/weights directory - */ - -struct damon_sysfs_weights { - struct kobject kobj; - unsigned int sz; - unsigned int nr_accesses; - unsigned int age; -}; - -static struct damon_sysfs_weights *damon_sysfs_weights_alloc(unsigned int = sz, - unsigned int nr_accesses, unsigned int age) -{ - struct damon_sysfs_weights *weights =3D kmalloc(sizeof(*weights), - GFP_KERNEL); - - if (!weights) - return NULL; - weights->kobj =3D (struct kobject){}; - weights->sz =3D sz; - weights->nr_accesses =3D nr_accesses; - weights->age =3D age; - return weights; -} - -static ssize_t sz_permil_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_weights *weights =3D container_of(kobj, - struct damon_sysfs_weights, kobj); - - return sysfs_emit(buf, "%u\n", weights->sz); -} - -static ssize_t sz_permil_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct damon_sysfs_weights *weights =3D container_of(kobj, - struct damon_sysfs_weights, kobj); - int err =3D kstrtouint(buf, 0, &weights->sz); - - return err ? err : count; -} - -static ssize_t nr_accesses_permil_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_weights *weights =3D container_of(kobj, - struct damon_sysfs_weights, kobj); - - return sysfs_emit(buf, "%u\n", weights->nr_accesses); -} - -static ssize_t nr_accesses_permil_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct damon_sysfs_weights *weights =3D container_of(kobj, - struct damon_sysfs_weights, kobj); - int err =3D kstrtouint(buf, 0, &weights->nr_accesses); - - return err ? err : count; -} - -static ssize_t age_permil_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_weights *weights =3D container_of(kobj, - struct damon_sysfs_weights, kobj); - - return sysfs_emit(buf, "%u\n", weights->age); -} - -static ssize_t age_permil_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct damon_sysfs_weights *weights =3D container_of(kobj, - struct damon_sysfs_weights, kobj); - int err =3D kstrtouint(buf, 0, &weights->age); - - return err ? err : count; -} - -static void damon_sysfs_weights_release(struct kobject *kobj) -{ - kfree(container_of(kobj, struct damon_sysfs_weights, kobj)); -} - -static struct kobj_attribute damon_sysfs_weights_sz_attr =3D - __ATTR_RW_MODE(sz_permil, 0600); - -static struct kobj_attribute damon_sysfs_weights_nr_accesses_attr =3D - __ATTR_RW_MODE(nr_accesses_permil, 0600); - -static struct kobj_attribute damon_sysfs_weights_age_attr =3D - __ATTR_RW_MODE(age_permil, 0600); - -static struct attribute *damon_sysfs_weights_attrs[] =3D { - &damon_sysfs_weights_sz_attr.attr, - &damon_sysfs_weights_nr_accesses_attr.attr, - &damon_sysfs_weights_age_attr.attr, - NULL, -}; -ATTRIBUTE_GROUPS(damon_sysfs_weights); - -static struct kobj_type damon_sysfs_weights_ktype =3D { - .release =3D damon_sysfs_weights_release, - .sysfs_ops =3D &kobj_sysfs_ops, - .default_groups =3D damon_sysfs_weights_groups, -}; - -/* - * quotas directory - */ - -struct damon_sysfs_quotas { - struct kobject kobj; - struct damon_sysfs_weights *weights; - unsigned long ms; - unsigned long sz; - unsigned long reset_interval_ms; -}; - -static struct damon_sysfs_quotas *damon_sysfs_quotas_alloc(void) -{ - return kzalloc(sizeof(struct damon_sysfs_quotas), GFP_KERNEL); -} - -static int damon_sysfs_quotas_add_dirs(struct damon_sysfs_quotas *quotas) -{ - struct damon_sysfs_weights *weights; - int err; - - weights =3D damon_sysfs_weights_alloc(0, 0, 0); - if (!weights) - return -ENOMEM; - - err =3D kobject_init_and_add(&weights->kobj, &damon_sysfs_weights_ktype, - "as->kobj, "weights"); - if (err) - kobject_put(&weights->kobj); - else - quotas->weights =3D weights; - return err; -} - -static void damon_sysfs_quotas_rm_dirs(struct damon_sysfs_quotas *quotas) -{ - kobject_put("as->weights->kobj); -} - -static ssize_t ms_show(struct kobject *kobj, struct kobj_attribute *attr, - char *buf) -{ - struct damon_sysfs_quotas *quotas =3D container_of(kobj, - struct damon_sysfs_quotas, kobj); - - return sysfs_emit(buf, "%lu\n", quotas->ms); -} - -static ssize_t ms_store(struct kobject *kobj, struct kobj_attribute *attr, - const char *buf, size_t count) -{ - struct damon_sysfs_quotas *quotas =3D container_of(kobj, - struct damon_sysfs_quotas, kobj); - int err =3D kstrtoul(buf, 0, "as->ms); - - if (err) - return -EINVAL; - return count; -} - -static ssize_t bytes_show(struct kobject *kobj, struct kobj_attribute *att= r, - char *buf) -{ - struct damon_sysfs_quotas *quotas =3D container_of(kobj, - struct damon_sysfs_quotas, kobj); - - return sysfs_emit(buf, "%lu\n", quotas->sz); -} - -static ssize_t bytes_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct damon_sysfs_quotas *quotas =3D container_of(kobj, - struct damon_sysfs_quotas, kobj); - int err =3D kstrtoul(buf, 0, "as->sz); - - if (err) - return -EINVAL; - return count; -} - -static ssize_t reset_interval_ms_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_quotas *quotas =3D container_of(kobj, - struct damon_sysfs_quotas, kobj); - - return sysfs_emit(buf, "%lu\n", quotas->reset_interval_ms); -} - -static ssize_t reset_interval_ms_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct damon_sysfs_quotas *quotas =3D container_of(kobj, - struct damon_sysfs_quotas, kobj); - int err =3D kstrtoul(buf, 0, "as->reset_interval_ms); - - if (err) - return -EINVAL; - return count; -} - -static void damon_sysfs_quotas_release(struct kobject *kobj) -{ - kfree(container_of(kobj, struct damon_sysfs_quotas, kobj)); -} - -static struct kobj_attribute damon_sysfs_quotas_ms_attr =3D - __ATTR_RW_MODE(ms, 0600); - -static struct kobj_attribute damon_sysfs_quotas_sz_attr =3D - __ATTR_RW_MODE(bytes, 0600); - -static struct kobj_attribute damon_sysfs_quotas_reset_interval_ms_attr =3D - __ATTR_RW_MODE(reset_interval_ms, 0600); - -static struct attribute *damon_sysfs_quotas_attrs[] =3D { - &damon_sysfs_quotas_ms_attr.attr, - &damon_sysfs_quotas_sz_attr.attr, - &damon_sysfs_quotas_reset_interval_ms_attr.attr, - NULL, -}; -ATTRIBUTE_GROUPS(damon_sysfs_quotas); - -static struct kobj_type damon_sysfs_quotas_ktype =3D { - .release =3D damon_sysfs_quotas_release, - .sysfs_ops =3D &kobj_sysfs_ops, - .default_groups =3D damon_sysfs_quotas_groups, -}; - -/* - * access_pattern directory - */ - -struct damon_sysfs_access_pattern { - struct kobject kobj; - struct damon_sysfs_ul_range *sz; - struct damon_sysfs_ul_range *nr_accesses; - struct damon_sysfs_ul_range *age; -}; - -static -struct damon_sysfs_access_pattern *damon_sysfs_access_pattern_alloc(void) -{ - struct damon_sysfs_access_pattern *access_pattern =3D - kmalloc(sizeof(*access_pattern), GFP_KERNEL); - - if (!access_pattern) - return NULL; - access_pattern->kobj =3D (struct kobject){}; - return access_pattern; -} - -static int damon_sysfs_access_pattern_add_range_dir( - struct damon_sysfs_access_pattern *access_pattern, - struct damon_sysfs_ul_range **range_dir_ptr, - char *name) -{ - struct damon_sysfs_ul_range *range =3D damon_sysfs_ul_range_alloc(0, 0); - int err; - - if (!range) - return -ENOMEM; - err =3D kobject_init_and_add(&range->kobj, &damon_sysfs_ul_range_ktype, - &access_pattern->kobj, name); - if (err) - kobject_put(&range->kobj); - else - *range_dir_ptr =3D range; - return err; -} - -static int damon_sysfs_access_pattern_add_dirs( - struct damon_sysfs_access_pattern *access_pattern) -{ - int err; - - err =3D damon_sysfs_access_pattern_add_range_dir(access_pattern, - &access_pattern->sz, "sz"); - if (err) - goto put_sz_out; - - err =3D damon_sysfs_access_pattern_add_range_dir(access_pattern, - &access_pattern->nr_accesses, "nr_accesses"); - if (err) - goto put_nr_accesses_sz_out; - - err =3D damon_sysfs_access_pattern_add_range_dir(access_pattern, - &access_pattern->age, "age"); - if (err) - goto put_age_nr_accesses_sz_out; - return 0; - -put_age_nr_accesses_sz_out: - kobject_put(&access_pattern->age->kobj); - access_pattern->age =3D NULL; -put_nr_accesses_sz_out: - kobject_put(&access_pattern->nr_accesses->kobj); - access_pattern->nr_accesses =3D NULL; -put_sz_out: - kobject_put(&access_pattern->sz->kobj); - access_pattern->sz =3D NULL; - return err; -} - -static void damon_sysfs_access_pattern_rm_dirs( - struct damon_sysfs_access_pattern *access_pattern) -{ - kobject_put(&access_pattern->sz->kobj); - kobject_put(&access_pattern->nr_accesses->kobj); - kobject_put(&access_pattern->age->kobj); -} - -static void damon_sysfs_access_pattern_release(struct kobject *kobj) -{ - kfree(container_of(kobj, struct damon_sysfs_access_pattern, kobj)); -} - -static struct attribute *damon_sysfs_access_pattern_attrs[] =3D { - NULL, -}; -ATTRIBUTE_GROUPS(damon_sysfs_access_pattern); - -static struct kobj_type damon_sysfs_access_pattern_ktype =3D { - .release =3D damon_sysfs_access_pattern_release, - .sysfs_ops =3D &kobj_sysfs_ops, - .default_groups =3D damon_sysfs_access_pattern_groups, -}; - -/* - * scheme directory - */ - -struct damon_sysfs_scheme { - struct kobject kobj; - enum damos_action action; - struct damon_sysfs_access_pattern *access_pattern; - struct damon_sysfs_quotas *quotas; - struct damon_sysfs_watermarks *watermarks; - struct damon_sysfs_stats *stats; -}; - -/* This should match with enum damos_action */ -static const char * const damon_sysfs_damos_action_strs[] =3D { - "willneed", - "cold", - "pageout", - "hugepage", - "nohugepage", - "lru_prio", - "lru_deprio", - "stat", -}; - -static struct damon_sysfs_scheme *damon_sysfs_scheme_alloc( - enum damos_action action) -{ - struct damon_sysfs_scheme *scheme =3D kmalloc(sizeof(*scheme), - GFP_KERNEL); - - if (!scheme) - return NULL; - scheme->kobj =3D (struct kobject){}; - scheme->action =3D action; - return scheme; -} - -static int damon_sysfs_scheme_set_access_pattern( - struct damon_sysfs_scheme *scheme) -{ - struct damon_sysfs_access_pattern *access_pattern; - int err; - - access_pattern =3D damon_sysfs_access_pattern_alloc(); - if (!access_pattern) - return -ENOMEM; - err =3D kobject_init_and_add(&access_pattern->kobj, - &damon_sysfs_access_pattern_ktype, &scheme->kobj, - "access_pattern"); - if (err) - goto out; - err =3D damon_sysfs_access_pattern_add_dirs(access_pattern); - if (err) - goto out; - scheme->access_pattern =3D access_pattern; - return 0; - -out: - kobject_put(&access_pattern->kobj); - return err; -} - -static int damon_sysfs_scheme_set_quotas(struct damon_sysfs_scheme *scheme) -{ - struct damon_sysfs_quotas *quotas =3D damon_sysfs_quotas_alloc(); - int err; - - if (!quotas) - return -ENOMEM; - err =3D kobject_init_and_add("as->kobj, &damon_sysfs_quotas_ktype, - &scheme->kobj, "quotas"); - if (err) - goto out; - err =3D damon_sysfs_quotas_add_dirs(quotas); - if (err) - goto out; - scheme->quotas =3D quotas; - return 0; - -out: - kobject_put("as->kobj); - return err; -} - -static int damon_sysfs_scheme_set_watermarks(struct damon_sysfs_scheme *sc= heme) -{ - struct damon_sysfs_watermarks *watermarks =3D - damon_sysfs_watermarks_alloc(DAMOS_WMARK_NONE, 0, 0, 0, 0); - int err; - - if (!watermarks) - return -ENOMEM; - err =3D kobject_init_and_add(&watermarks->kobj, - &damon_sysfs_watermarks_ktype, &scheme->kobj, - "watermarks"); - if (err) - kobject_put(&watermarks->kobj); - else - scheme->watermarks =3D watermarks; - return err; -} - -static int damon_sysfs_scheme_set_stats(struct damon_sysfs_scheme *scheme) -{ - struct damon_sysfs_stats *stats =3D damon_sysfs_stats_alloc(); - int err; - - if (!stats) - return -ENOMEM; - err =3D kobject_init_and_add(&stats->kobj, &damon_sysfs_stats_ktype, - &scheme->kobj, "stats"); - if (err) - kobject_put(&stats->kobj); - else - scheme->stats =3D stats; - return err; -} - -static int damon_sysfs_scheme_add_dirs(struct damon_sysfs_scheme *scheme) -{ - int err; - - err =3D damon_sysfs_scheme_set_access_pattern(scheme); - if (err) - return err; - err =3D damon_sysfs_scheme_set_quotas(scheme); - if (err) - goto put_access_pattern_out; - err =3D damon_sysfs_scheme_set_watermarks(scheme); - if (err) - goto put_quotas_access_pattern_out; - err =3D damon_sysfs_scheme_set_stats(scheme); - if (err) - goto put_watermarks_quotas_access_pattern_out; - return 0; - -put_watermarks_quotas_access_pattern_out: - kobject_put(&scheme->watermarks->kobj); - scheme->watermarks =3D NULL; -put_quotas_access_pattern_out: - kobject_put(&scheme->quotas->kobj); - scheme->quotas =3D NULL; -put_access_pattern_out: - kobject_put(&scheme->access_pattern->kobj); - scheme->access_pattern =3D NULL; - return err; -} - -static void damon_sysfs_scheme_rm_dirs(struct damon_sysfs_scheme *scheme) -{ - damon_sysfs_access_pattern_rm_dirs(scheme->access_pattern); - kobject_put(&scheme->access_pattern->kobj); - damon_sysfs_quotas_rm_dirs(scheme->quotas); - kobject_put(&scheme->quotas->kobj); - kobject_put(&scheme->watermarks->kobj); - kobject_put(&scheme->stats->kobj); -} - -static ssize_t action_show(struct kobject *kobj, struct kobj_attribute *at= tr, - char *buf) -{ - struct damon_sysfs_scheme *scheme =3D container_of(kobj, - struct damon_sysfs_scheme, kobj); - - return sysfs_emit(buf, "%s\n", - damon_sysfs_damos_action_strs[scheme->action]); -} - -static ssize_t action_store(struct kobject *kobj, struct kobj_attribute *a= ttr, - const char *buf, size_t count) -{ - struct damon_sysfs_scheme *scheme =3D container_of(kobj, - struct damon_sysfs_scheme, kobj); - enum damos_action action; - - for (action =3D 0; action < NR_DAMOS_ACTIONS; action++) { - if (sysfs_streq(buf, damon_sysfs_damos_action_strs[action])) { - scheme->action =3D action; - return count; - } - } - return -EINVAL; -} - -static void damon_sysfs_scheme_release(struct kobject *kobj) -{ - kfree(container_of(kobj, struct damon_sysfs_scheme, kobj)); -} - -static struct kobj_attribute damon_sysfs_scheme_action_attr =3D - __ATTR_RW_MODE(action, 0600); - -static struct attribute *damon_sysfs_scheme_attrs[] =3D { - &damon_sysfs_scheme_action_attr.attr, - NULL, -}; -ATTRIBUTE_GROUPS(damon_sysfs_scheme); - -static struct kobj_type damon_sysfs_scheme_ktype =3D { - .release =3D damon_sysfs_scheme_release, - .sysfs_ops =3D &kobj_sysfs_ops, - .default_groups =3D damon_sysfs_scheme_groups, -}; - -/* - * schemes directory - */ - -struct damon_sysfs_schemes { - struct kobject kobj; - struct damon_sysfs_scheme **schemes_arr; - int nr; -}; - -static struct damon_sysfs_schemes *damon_sysfs_schemes_alloc(void) -{ - return kzalloc(sizeof(struct damon_sysfs_schemes), GFP_KERNEL); -} - -static void damon_sysfs_schemes_rm_dirs(struct damon_sysfs_schemes *scheme= s) -{ - struct damon_sysfs_scheme **schemes_arr =3D schemes->schemes_arr; - int i; - - for (i =3D 0; i < schemes->nr; i++) { - damon_sysfs_scheme_rm_dirs(schemes_arr[i]); - kobject_put(&schemes_arr[i]->kobj); - } - schemes->nr =3D 0; - kfree(schemes_arr); - schemes->schemes_arr =3D NULL; -} - -static int damon_sysfs_schemes_add_dirs(struct damon_sysfs_schemes *scheme= s, - int nr_schemes) -{ - struct damon_sysfs_scheme **schemes_arr, *scheme; - int err, i; - - damon_sysfs_schemes_rm_dirs(schemes); - if (!nr_schemes) - return 0; - - schemes_arr =3D kmalloc_array(nr_schemes, sizeof(*schemes_arr), - GFP_KERNEL | __GFP_NOWARN); - if (!schemes_arr) - return -ENOMEM; - schemes->schemes_arr =3D schemes_arr; - - for (i =3D 0; i < nr_schemes; i++) { - scheme =3D damon_sysfs_scheme_alloc(DAMOS_STAT); - if (!scheme) { - damon_sysfs_schemes_rm_dirs(schemes); - return -ENOMEM; - } - - err =3D kobject_init_and_add(&scheme->kobj, - &damon_sysfs_scheme_ktype, &schemes->kobj, - "%d", i); - if (err) - goto out; - err =3D damon_sysfs_scheme_add_dirs(scheme); - if (err) - goto out; - - schemes_arr[i] =3D scheme; - schemes->nr++; - } - return 0; - -out: - damon_sysfs_schemes_rm_dirs(schemes); - kobject_put(&scheme->kobj); - return err; -} - -static ssize_t nr_schemes_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct damon_sysfs_schemes *schemes =3D container_of(kobj, - struct damon_sysfs_schemes, kobj); - - return sysfs_emit(buf, "%d\n", schemes->nr); -} - -static ssize_t nr_schemes_store(struct kobject *kobj, - struct kobj_attribute *attr, const char *buf, size_t count) -{ - struct damon_sysfs_schemes *schemes; - int nr, err =3D kstrtoint(buf, 0, &nr); - - if (err) - return err; - if (nr < 0) - return -EINVAL; - - schemes =3D container_of(kobj, struct damon_sysfs_schemes, kobj); - - if (!mutex_trylock(&damon_sysfs_lock)) - return -EBUSY; - err =3D damon_sysfs_schemes_add_dirs(schemes, nr); - mutex_unlock(&damon_sysfs_lock); - if (err) - return err; - return count; -} - -static void damon_sysfs_schemes_release(struct kobject *kobj) -{ - kfree(container_of(kobj, struct damon_sysfs_schemes, kobj)); -} - -static struct kobj_attribute damon_sysfs_schemes_nr_attr =3D - __ATTR_RW_MODE(nr_schemes, 0600); - -static struct attribute *damon_sysfs_schemes_attrs[] =3D { - &damon_sysfs_schemes_nr_attr.attr, - NULL, -}; -ATTRIBUTE_GROUPS(damon_sysfs_schemes); - -static struct kobj_type damon_sysfs_schemes_ktype =3D { - .release =3D damon_sysfs_schemes_release, - .sysfs_ops =3D &kobj_sysfs_ops, - .default_groups =3D damon_sysfs_schemes_groups, -}; - /* * init region directory */ @@ -2133,62 +1190,6 @@ static int damon_sysfs_set_targets(struct damon_ctx = *ctx, return 0; } =20 -static struct damos *damon_sysfs_mk_scheme( - struct damon_sysfs_scheme *sysfs_scheme) -{ - struct damon_sysfs_access_pattern *access_pattern =3D - sysfs_scheme->access_pattern; - struct damon_sysfs_quotas *sysfs_quotas =3D sysfs_scheme->quotas; - struct damon_sysfs_weights *sysfs_weights =3D sysfs_quotas->weights; - struct damon_sysfs_watermarks *sysfs_wmarks =3D sysfs_scheme->watermarks; - - struct damos_access_pattern pattern =3D { - .min_sz_region =3D access_pattern->sz->min, - .max_sz_region =3D access_pattern->sz->max, - .min_nr_accesses =3D access_pattern->nr_accesses->min, - .max_nr_accesses =3D access_pattern->nr_accesses->max, - .min_age_region =3D access_pattern->age->min, - .max_age_region =3D access_pattern->age->max, - }; - struct damos_quota quota =3D { - .ms =3D sysfs_quotas->ms, - .sz =3D sysfs_quotas->sz, - .reset_interval =3D sysfs_quotas->reset_interval_ms, - .weight_sz =3D sysfs_weights->sz, - .weight_nr_accesses =3D sysfs_weights->nr_accesses, - .weight_age =3D sysfs_weights->age, - }; - struct damos_watermarks wmarks =3D { - .metric =3D sysfs_wmarks->metric, - .interval =3D sysfs_wmarks->interval_us, - .high =3D sysfs_wmarks->high, - .mid =3D sysfs_wmarks->mid, - .low =3D sysfs_wmarks->low, - }; - - return damon_new_scheme(&pattern, sysfs_scheme->action, "a, - &wmarks); -} - -static int damon_sysfs_set_schemes(struct damon_ctx *ctx, - struct damon_sysfs_schemes *sysfs_schemes) -{ - int i; - - for (i =3D 0; i < sysfs_schemes->nr; i++) { - struct damos *scheme, *next; - - scheme =3D damon_sysfs_mk_scheme(sysfs_schemes->schemes_arr[i]); - if (!scheme) { - damon_for_each_scheme_safe(scheme, next, ctx) - damon_destroy_scheme(scheme); - return -ENOMEM; - } - damon_add_scheme(ctx, scheme); - } - return 0; -} - static void damon_sysfs_before_terminate(struct damon_ctx *ctx) { struct damon_target *t, *next; @@ -2204,25 +1205,6 @@ static void damon_sysfs_before_terminate(struct damo= n_ctx *ctx) mutex_unlock(&ctx->kdamond_lock); } =20 -static void damon_sysfs_schemes_update_stats( - struct damon_sysfs_schemes *sysfs_schemes, - struct damon_ctx *ctx) -{ - struct damos *scheme; - int schemes_idx =3D 0; - - damon_for_each_scheme(scheme, ctx) { - struct damon_sysfs_stats *sysfs_stats; - - sysfs_stats =3D sysfs_schemes->schemes_arr[schemes_idx++]->stats; - sysfs_stats->nr_tried =3D scheme->stat.nr_tried; - sysfs_stats->sz_tried =3D scheme->stat.sz_tried; - sysfs_stats->nr_applied =3D scheme->stat.nr_applied; - sysfs_stats->sz_applied =3D scheme->stat.sz_applied; - sysfs_stats->qt_exceeds =3D scheme->stat.qt_exceeds; - } -} - /* * damon_sysfs_upd_schemes_stats() - Update schemes stats sysfs files. * @kdamond: The kobject wrapper that associated to the kdamond thread. --=20 2.25.1 From nobody Wed Apr 8 07:59:16 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 71915C38A2D for ; Wed, 26 Oct 2022 23:00:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234145AbiJZXAu (ORCPT ); Wed, 26 Oct 2022 19:00:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41242 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234034AbiJZXAE (ORCPT ); Wed, 26 Oct 2022 19:00:04 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E02FB2B1B7 for ; Wed, 26 Oct 2022 15:59:59 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id A7E7BB8247B for ; Wed, 26 Oct 2022 22:59:57 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id F3A76C433C1; Wed, 26 Oct 2022 22:59:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825196; bh=xh7wrkUfCZyyYQCz1FTbZYGhTBtYeEWznNRmu6lB2kI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iT929Iyg7VIVF+XtoOZCDIZ7VUEBLbW2jCx3W7Ewsr5rU+hfe41kcCPbUEGFk+hRS hP2v1ya1nU1ayJdJ6IuzW0p1iP1U7fMeBogqwg2mO/EM7Z+ycHQWGQs13rvCZmyj8J tD/H77e9OBtuoYDA1F7Puk3ZJq16ngy1tojzFMjtcet85BaWbimDvD4e704++rE39c iyT8h1C8MyG4q2bAw0dVoqzPFMiK67vGQ8wo68kRUy6ePchmHJjxWWjrQ+/V2muOpW q7F6eRDvKgJhodfgYyiyNhLaVj1MShih235EUJhhT/DGAQ4H/qeZPiz2ZqzfYf60xD JpiOjaNVwTJaQ== From: SeongJae Park To: Andrew Morton Cc: linux-kernel@vger.kernel.org, damon@lists.linux.dev, linux-mm@kvack.org, SeongJae Park Subject: [PATCH v2 11/12] mm/damon/modules: deduplicate init steps for DAMON context setup Date: Wed, 26 Oct 2022 22:59:42 +0000 Message-Id: <20221026225943.100429-12-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" DAMON_RECLAIM and DAMON_LRU_SORT has duplicated code for DAMON context and target initializations. Deduplicate the part by implementing a function for the initialization in 'modules-common.c' and using it. Signed-off-by: SeongJae Park Signed-off-by: Andrew Morton --- mm/damon/Makefile | 4 ++-- mm/damon/lru_sort.c | 17 +++------------- mm/damon/modules-common.c | 42 +++++++++++++++++++++++++++++++++++++++ mm/damon/modules-common.h | 3 +++ mm/damon/reclaim.c | 17 +++------------- 5 files changed, 53 insertions(+), 30 deletions(-) create mode 100644 mm/damon/modules-common.c diff --git a/mm/damon/Makefile b/mm/damon/Makefile index 1e86f5253d7f..f7add3f4aa79 100644 --- a/mm/damon/Makefile +++ b/mm/damon/Makefile @@ -5,5 +5,5 @@ obj-$(CONFIG_DAMON_VADDR) +=3D ops-common.o vaddr.o obj-$(CONFIG_DAMON_PADDR) +=3D ops-common.o paddr.o obj-$(CONFIG_DAMON_SYSFS) +=3D sysfs-common.o sysfs-schemes.o sysfs.o obj-$(CONFIG_DAMON_DBGFS) +=3D dbgfs.o -obj-$(CONFIG_DAMON_RECLAIM) +=3D reclaim.o -obj-$(CONFIG_DAMON_LRU_SORT) +=3D lru_sort.o +obj-$(CONFIG_DAMON_RECLAIM) +=3D modules-common.o reclaim.o +obj-$(CONFIG_DAMON_LRU_SORT) +=3D modules-common.o lru_sort.o diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c index efbc2bda8b9c..a1896c5acfe9 100644 --- a/mm/damon/lru_sort.c +++ b/mm/damon/lru_sort.c @@ -314,25 +314,14 @@ static int damon_lru_sort_after_wmarks_check(struct d= amon_ctx *c) =20 static int __init damon_lru_sort_init(void) { - ctx =3D damon_new_ctx(); - if (!ctx) - return -ENOMEM; + int err =3D damon_modules_new_paddr_ctx_target(&ctx, &target); =20 - if (damon_select_ops(ctx, DAMON_OPS_PADDR)) { - damon_destroy_ctx(ctx); - return -EINVAL; - } + if (err) + return err; =20 ctx->callback.after_wmarks_check =3D damon_lru_sort_after_wmarks_check; ctx->callback.after_aggregation =3D damon_lru_sort_after_aggregation; =20 - target =3D damon_new_target(); - if (!target) { - damon_destroy_ctx(ctx); - return -ENOMEM; - } - damon_add_target(ctx, target); - schedule_delayed_work(&damon_lru_sort_timer, 0); =20 damon_lru_sort_initialized =3D true; diff --git a/mm/damon/modules-common.c b/mm/damon/modules-common.c new file mode 100644 index 000000000000..b2381a8466ec --- /dev/null +++ b/mm/damon/modules-common.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Common Primitives for DAMON Modules + * + * Author: SeongJae Park + */ + +#include + +#include "modules-common.h" + +/* + * Allocate, set, and return a DAMON context for the physical address spac= e. + * @ctxp: Pointer to save the point to the newly created context + * @targetp: Pointer to save the point to the newly created target + */ +int damon_modules_new_paddr_ctx_target(struct damon_ctx **ctxp, + struct damon_target **targetp) +{ + struct damon_ctx *ctx; + struct damon_target *target; + + ctx =3D damon_new_ctx(); + if (!ctx) + return -ENOMEM; + + if (damon_select_ops(ctx, DAMON_OPS_PADDR)) { + damon_destroy_ctx(ctx); + return -EINVAL; + } + + target =3D damon_new_target(); + if (!target) { + damon_destroy_ctx(ctx); + return -ENOMEM; + } + damon_add_target(ctx, target); + + *ctxp =3D ctx; + *targetp =3D target; + return 0; +} diff --git a/mm/damon/modules-common.h b/mm/damon/modules-common.h index 5a4921851d32..f49cdb417005 100644 --- a/mm/damon/modules-common.h +++ b/mm/damon/modules-common.h @@ -44,3 +44,6 @@ 0400); \ module_param_named(nr_##qt_exceed_name, stat.qt_exceeds, ulong, \ 0400); + +int damon_modules_new_paddr_ctx_target(struct damon_ctx **ctxp, + struct damon_target **targetp); diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c index 162c9b1ca00f..3173f373435c 100644 --- a/mm/damon/reclaim.c +++ b/mm/damon/reclaim.c @@ -256,25 +256,14 @@ static int damon_reclaim_after_wmarks_check(struct da= mon_ctx *c) =20 static int __init damon_reclaim_init(void) { - ctx =3D damon_new_ctx(); - if (!ctx) - return -ENOMEM; + int err =3D damon_modules_new_paddr_ctx_target(&ctx, &target); =20 - if (damon_select_ops(ctx, DAMON_OPS_PADDR)) { - damon_destroy_ctx(ctx); - return -EINVAL; - } + if (err) + return err; =20 ctx->callback.after_wmarks_check =3D damon_reclaim_after_wmarks_check; ctx->callback.after_aggregation =3D damon_reclaim_after_aggregation; =20 - target =3D damon_new_target(); - if (!target) { - damon_destroy_ctx(ctx); - return -ENOMEM; - } - damon_add_target(ctx, target); - schedule_delayed_work(&damon_reclaim_timer, 0); =20 damon_reclaim_initialized =3D true; --=20 2.25.1 From nobody Wed Apr 8 07:59:16 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 0FE71C38A2D for ; Wed, 26 Oct 2022 23:00:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233295AbiJZXAy (ORCPT ); Wed, 26 Oct 2022 19:00:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41244 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234035AbiJZXAE (ORCPT ); Wed, 26 Oct 2022 19:00:04 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B0F32A41A for ; Wed, 26 Oct 2022 15:59:58 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 25B4B620ED for ; Wed, 26 Oct 2022 22:59:57 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 92C01C433D6; Wed, 26 Oct 2022 22:59:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1666825196; bh=QkoSP5dy50ivjFi2Kea4D2nh4Z8LDeoDCm4zKPAaAhQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ALm56epckyb/8rY95yBicPcsnjav4f+T26VCXKs6HLb5x+abgQaLlxHSCewgdBFgG DmBDFTQbQf9i1yAAJ3O91Qqkmtsg/8OSKXdGQKyKltSzOsnCpg8zxq6HlYfMG8dPgU ggiJ7kjnBJ2MbC3Ex0BlPUAk7UqDIdSEtzRR1mCHOclIQ6Qo6Q8pYa08iKBCWk8AIw 6XozkgTsCSvFP1spmNDTYeBgcoD1RYHGDW2RCX1rNsjrCq53tiZWQJt0Dntinf5tLC Cinn0dXhLsNZo5uRyLGqgMXi1vmyF5iD7a3R90G1EueEexUPmekq+yzDc8fxlHisa0 E3iIL0zsIovBg== From: SeongJae Park To: Andrew Morton Cc: damon@lists.linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, SeongJae Park Subject: [PATCH v2 12/12] mm/damon/{reclaim,lru_sort}: remove unnecessarily included headers Date: Wed, 26 Oct 2022 22:59:43 +0000 Message-Id: <20221026225943.100429-13-sj@kernel.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221026225943.100429-1-sj@kernel.org> References: <20221026225943.100429-1-sj@kernel.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Some headers that 'reclaim.c' and 'lru_sort.c' are including are unnecessary now owing to previous cleanups and refactorings. Remove those. Signed-off-by: SeongJae Park Signed-off-by: Andrew Morton --- mm/damon/lru_sort.c | 2 -- mm/damon/reclaim.c | 2 -- 2 files changed, 4 deletions(-) diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c index a1896c5acfe9..5c60163e556c 100644 --- a/mm/damon/lru_sort.c +++ b/mm/damon/lru_sort.c @@ -8,9 +8,7 @@ #define pr_fmt(fmt) "damon-lru-sort: " fmt =20 #include -#include #include -#include #include =20 #include "modules-common.h" diff --git a/mm/damon/reclaim.c b/mm/damon/reclaim.c index 3173f373435c..e14eb30c01f4 100644 --- a/mm/damon/reclaim.c +++ b/mm/damon/reclaim.c @@ -8,9 +8,7 @@ #define pr_fmt(fmt) "damon-reclaim: " fmt =20 #include -#include #include -#include #include =20 #include "modules-common.h" --=20 2.25.1