From: SeongJae Park <sj@kernel.org>
To: JaeJoon Jung <rgbi3307@gmail.com>
Cc: SeongJae Park <sj@kernel.org>,
damon@lists.linux.dev, linux-mm@kvack.org, rgbi3307@nate.com
Subject: Re: [PATCH] mm/damon/core: modified control->repeat loop at the kdamond_call()
Date: Wed, 24 Dec 2025 17:07:21 -0800 [thread overview]
Message-ID: <20251225010722.14746-1-sj@kernel.org> (raw)
In-Reply-To: <20251224124355.31667-1-rgbi3307@gmail.com>
On Wed, 24 Dec 2025 21:43:54 +0900 JaeJoon Jung <rgbi3307@gmail.com> wrote:
> The kdamond_call() function is executed repeatedly in the kdamond_fn()
> kernel thread. The kdamond_call() function is implemented as a while loop.
> Therefore, it is important to improve the list processing logic here to
> ensure faster execution of control->fn().
That depends on how critical the performance is, and how much complexity the
optimization introduces. I have no idea about if the performance of
kdamond_call() is really important. If you have a realistic use case that
shows it, sharing it would be nice.
> For ease of explanation,
> the data structure names will be abbreviated as follows:
>
> damon_call_control.list: C.list
> ctx->call_controls: CTX.head
> repeat_controls: R.head
>
> the execution flow of the while loop of the kdamond_call() function,
>
> Before modification:
> Old while loop:
>
> CTX.head <-----> C.list <-----> C.list <----> C.list
> ^ | |
> | if (C.repeat) if (!C.repeat)
> restore: only one | |
> list_add_tail() list_del() list_del()
> | | |
> + | complete()
> R.head <------ list_add()
>
> To process C.repeat above, we use an additional list, repeat_controls.
Your above abbreviation didn't explain what C.repeat is. Maybe you mean
'damon_call_control.repeat'?
> The process of adding C.list to repeat_controls and then restoring it back
> to CTX.head is complex and inefficient.
I agree.
> Furthermore, there's the problem
> of restoring only a single C.list to CTX.head.
I had to take some time on understanding what this mean. And it seems you are
working on an old version of the tree, and therefore saying about an issue that
already fixed by commit 592e5c5f8ec6 ("mm/damon/core: fix memory leak of repeat
mode damon_call_control objects").
Please use mm-new as a baseline of DAMON patches, unless there are special
reasons. If there are special reasons, please explicitly specify.
>
> Below, repeat_controls is removed and the existing CTX.head is modified to
> loop once(1st rotation). This simplifies list processing and creates a
> more efficient structure.
>
> Modified while loop:
> Not used repeat_controls:
>
> CTX.head <-----> C.list <-----> C.list <----> C.list <-------+
> | | |
> if (C.repeat) if (!C.repeat) |
> | | |
> list_del() list_del() |
> | | |
> | complete() |
> | |
> first --------> list_add_tail() -----------+
>
> if (C.list == first) break;
>
> Signed-off-by: JaeJoon Jung <rgbi3307@gmail.com>
> ---
> mm/damon/core.c | 37 +++++++++++++++++++------------------
> 1 file changed, 19 insertions(+), 18 deletions(-)
>
> diff --git a/mm/damon/core.c b/mm/damon/core.c
> index 824aa8f22db3..babad37719b6 100644
> --- a/mm/damon/core.c
> +++ b/mm/damon/core.c
> @@ -2554,42 +2554,43 @@ static void kdamond_usleep(unsigned long usecs)
> */
> static void kdamond_call(struct damon_ctx *ctx, bool cancel)
> {
> - struct damon_call_control *control;
> - LIST_HEAD(repeat_controls);
> - int ret = 0;
> + struct damon_call_control *control, *first = NULL;
> + unsigned int idx = 0;
>
> while (true) {
> mutex_lock(&ctx->call_controls_lock);
> control = list_first_entry_or_null(&ctx->call_controls,
> struct damon_call_control, list);
> mutex_unlock(&ctx->call_controls_lock);
> - if (!control)
> +
> + /* check control empty or 1st rotation */
> + if (!control || control == first)
> break;
> - if (cancel) {
> +
> + if (++idx == 1)
> + first = control;
> +
> + if (cancel)
> control->canceled = true;
> - } else {
> - ret = control->fn(control->data);
> - control->return_code = ret;
> - }
> + else
> + control->return_code = control->fn(control->data);
> +
> mutex_lock(&ctx->call_controls_lock);
> list_del(&control->list);
> mutex_unlock(&ctx->call_controls_lock);
> +
> if (!control->repeat) {
> + /* run control->fn() one time */
> complete(&control->completion);
> } else if (control->canceled && control->dealloc_on_cancel) {
> kfree(control);
> - continue;
> } else {
> - list_add(&control->list, &repeat_controls);
> + /* to repeat next time */
> + mutex_lock(&ctx->call_controls_lock);
> + list_add_tail(&control->list, &ctx->call_controls);
> + mutex_unlock(&ctx->call_controls_lock);
> }
> }
Let's suppose there are two damon_call_control objects on the
ctx->call_controls. The first one has ->repeat unset, while the second one
has. Then, it seems the 'break' condition will never met and therefore this
loop will never finished. Am I missing something?
> - control = list_first_entry_or_null(&repeat_controls,
> - struct damon_call_control, list);
> - if (!control || cancel)
> - return;
> - mutex_lock(&ctx->call_controls_lock);
> - list_add_tail(&control->list, &ctx->call_controls);
> - mutex_unlock(&ctx->call_controls_lock);
As I mentioned above, apparently you are using an old version of the tree that
not having commit 592e5c5f8ec6 ("mm/damon/core: fix memory leak of repeat mode
damon_call_control objects") that modified this part. Please use mm-new as a
baseline, or specify reasons why you cannot do so.
> }
>
> /* Returns negative error code if it's not activated but should return */
> --
> 2.43.0
Thanks,
SJ
next prev parent reply other threads:[~2025-12-25 1:07 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-24 12:43 JaeJoon Jung
2025-12-25 1:07 ` SeongJae Park [this message]
2025-12-25 3:10 ` JaeJoon Jung
2025-12-25 20:00 ` SeongJae Park
2025-12-26 2:19 ` JaeJoon Jung
2025-12-26 18:31 ` SeongJae Park
2025-12-26 23:42 ` JaeJoon Jung
2025-12-30 0:14 ` JaeJoon Jung
2025-12-30 0:57 ` SeongJae Park
2025-12-31 1:28 ` SeongJae Park
2025-12-31 6:23 ` JaeJoon Jung
2025-12-31 15:29 ` SeongJae Park
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251225010722.14746-1-sj@kernel.org \
--to=sj@kernel.org \
--cc=damon@lists.linux.dev \
--cc=linux-mm@kvack.org \
--cc=rgbi3307@gmail.com \
--cc=rgbi3307@nate.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox