--- /dev/null
+From fb44d589bf3148e13452185a6e772a7efbf2d684 Mon Sep 17 00:00:00 2001
+From: Ashutosh Desai <ashutoshdesai993@gmail.com>
+Date: Wed, 15 Apr 2026 05:00:00 +0000
+Subject: drm/v3d: Reject empty multisync extension to prevent infinite loop
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Ashutosh Desai <ashutoshdesai993@gmail.com>
+
+commit fb44d589bf3148e13452185a6e772a7efbf2d684 upstream.
+
+v3d_get_extensions() walks a userspace-provided singly-linked list of
+ioctl extensions without any bound on the chain length. A local user
+can craft a self-referential extension (ext->next == &ext) with zero
+in_sync_count and out_sync_count, which bypasses the existing duplicate-
+extension guard:
+
+ if (se->in_sync_count || se->out_sync_count)
+ return -EINVAL;
+
+The guard never fires because v3d_get_multisync_post_deps() returns
+immediately when count is zero, leaving both fields at zero on every
+iteration. The result is an infinite loop in kernel context, blocking
+the calling thread and pegging a CPU core indefinitely.
+
+Fix this by rejecting a multisync extension where both in_sync_count
+and out_sync_count are zero in v3d_get_multisync_submit_deps(). An
+empty multisync carries no synchronization information and serves no
+useful purpose, so returning -EINVAL for such an extension is the
+correct defense against this attack vector.
+
+Fixes: e4165ae8304e ("drm/v3d: add multiple syncobjs support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Ashutosh Desai <ashutoshdesai993@gmail.com>
+Link: https://patch.msgid.link/20260415050000.3816128-1-ashutoshdesai993@gmail.com
+Signed-off-by: MaĆra Canal <mcanal@igalia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/v3d/v3d_gem.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/gpu/drm/v3d/v3d_gem.c
++++ b/drivers/gpu/drm/v3d/v3d_gem.c
+@@ -649,6 +649,11 @@ v3d_get_multisync_submit_deps(struct drm
+ if (multisync.pad)
+ return -EINVAL;
+
++ if (!multisync.in_sync_count && !multisync.out_sync_count) {
++ DRM_DEBUG("Empty multisync extension\n");
++ return -EINVAL;
++ }
++
+ ret = v3d_get_multisync_post_deps(file_priv, data, multisync.out_sync_count,
+ multisync.out_syncs);
+ if (ret)
--- /dev/null
+From a8aebe93a4938c0ca1941eeaae821738f869be3d Mon Sep 17 00:00:00 2001
+From: Corey Minyard <corey@minyard.net>
+Date: Tue, 21 Apr 2026 06:50:22 -0500
+Subject: ipmi:ssif: NULL thread on error
+
+From: Corey Minyard <corey@minyard.net>
+
+commit a8aebe93a4938c0ca1941eeaae821738f869be3d upstream.
+
+Cleanup code was checking the thread for NULL, but it was possibly
+a PTR_ERR() in one spot.
+
+Spotted with static analysis.
+
+Link: https://sourceforge.net/p/openipmi/mailman/message/59324676/
+Fixes: 75c486cb1bca ("ipmi:ssif: Clean up kthread on errors")
+Cc: <stable@vger.kernel.org> # 91eb7ec72612: ipmi:ssif: Remove unnecessary indention
+Cc: stable@vger.kernel.org
+Signed-off-by: Corey Minyard <corey@minyard.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/ipmi/ipmi_ssif.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/char/ipmi/ipmi_ssif.c
++++ b/drivers/char/ipmi/ipmi_ssif.c
+@@ -1886,6 +1886,7 @@ static int ssif_probe(struct i2c_client
+ "kssif%4.4x", thread_num);
+ if (IS_ERR(ssif_info->thread)) {
+ rv = PTR_ERR(ssif_info->thread);
++ ssif_info->thread = NULL;
+ dev_notice(&ssif_info->client->dev,
+ "Could not start kernel thread: error %d\n",
+ rv);
--- /dev/null
+From 91eb7ec7261254b6875909df767185838598e21e Mon Sep 17 00:00:00 2001
+From: Corey Minyard <corey@minyard.net>
+Date: Mon, 13 Apr 2026 07:09:15 -0500
+Subject: ipmi:ssif: Remove unnecessary indention
+
+From: Corey Minyard <corey@minyard.net>
+
+commit 91eb7ec7261254b6875909df767185838598e21e upstream.
+
+A section was in {} that didn't need to be, move the variable
+definition to the top and set th eindentino properly.
+
+Signed-off-by: Corey Minyard <corey@minyard.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/char/ipmi/ipmi_ssif.c | 28 ++++++++++++----------------
+ 1 file changed, 12 insertions(+), 16 deletions(-)
+
+--- a/drivers/char/ipmi/ipmi_ssif.c
++++ b/drivers/char/ipmi/ipmi_ssif.c
+@@ -1670,6 +1670,7 @@ static int ssif_probe(struct i2c_client
+ int len = 0;
+ int i;
+ u8 slave_addr = 0;
++ unsigned int thread_num;
+ struct ssif_addr_info *addr_info = NULL;
+
+ mutex_lock(&ssif_infos_mutex);
+@@ -1878,22 +1879,17 @@ static int ssif_probe(struct i2c_client
+ ssif_info->handlers.request_events = request_events;
+ ssif_info->handlers.set_need_watch = ssif_set_need_watch;
+
+- {
+- unsigned int thread_num;
+-
+- thread_num = ((i2c_adapter_id(ssif_info->client->adapter)
+- << 8) |
+- ssif_info->client->addr);
+- init_completion(&ssif_info->wake_thread);
+- ssif_info->thread = kthread_run(ipmi_ssif_thread, ssif_info,
+- "kssif%4.4x", thread_num);
+- if (IS_ERR(ssif_info->thread)) {
+- rv = PTR_ERR(ssif_info->thread);
+- dev_notice(&ssif_info->client->dev,
+- "Could not start kernel thread: error %d\n",
+- rv);
+- goto out;
+- }
++ thread_num = ((i2c_adapter_id(ssif_info->client->adapter) << 8) |
++ ssif_info->client->addr);
++ init_completion(&ssif_info->wake_thread);
++ ssif_info->thread = kthread_run(ipmi_ssif_thread, ssif_info,
++ "kssif%4.4x", thread_num);
++ if (IS_ERR(ssif_info->thread)) {
++ rv = PTR_ERR(ssif_info->thread);
++ dev_notice(&ssif_info->client->dev,
++ "Could not start kernel thread: error %d\n",
++ rv);
++ goto out;
+ }
+
+ dev_set_drvdata(&ssif_info->client->dev, ssif_info);
--- /dev/null
+From 4262c53236977de3ceaa3bf2aefdf772c9b874dd Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sj@kernel.org>
+Date: Thu, 15 Jan 2026 07:20:41 -0800
+Subject: mm/damon/core: implement damon_kdamond_pid()
+
+From: SeongJae Park <sj@kernel.org>
+
+commit 4262c53236977de3ceaa3bf2aefdf772c9b874dd upstream.
+
+Patch series "mm/damon: hide kdamond and kdamond_lock from API callers".
+
+'kdamond' and 'kdamond_lock' fields initially exposed to DAMON API callers
+for flexible synchronization and use cases. As DAMON API became somewhat
+complicated compared to the early days, Keeping those exposed could only
+encourage the API callers to invent more creative but complicated and
+difficult-to-debug use cases.
+
+Fortunately DAMON API callers didn't invent that many creative use cases.
+There exist only two use cases of 'kdamond' and 'kdamond_lock'. Finding
+whether the kdamond is actively running, and getting the pid of the
+kdamond. For the first use case, a dedicated API function, namely
+'damon_is_running()' is provided, and all DAMON API callers are using the
+function for the use case. Hence only the second use case is where the
+fields are directly being used by DAMON API callers.
+
+To prevent future invention of complicated and erroneous use cases of the
+fields, hide the fields from the API callers. For that, provide new
+dedicated DAMON API functions for the remaining use case, namely
+damon_kdamond_pid(), migrate DAMON API callers to use the new function,
+and mark the fields as private fields.
+
+
+This patch (of 5):
+
+'kdamond' and 'kdamond_lock' are directly being used by DAMON API callers
+for getting the pid of the corresponding kdamond. To discourage invention
+of creative but complicated and erroneous new usages of the fields that
+require careful synchronization, implement a new API function that can
+simply be used without the manual synchronizations.
+
+Link: https://lkml.kernel.org/r/20260115152047.68415-1-sj@kernel.org
+Link: https://lkml.kernel.org/r/20260115152047.68415-2-sj@kernel.org
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/damon.h | 1 +
+ mm/damon/core.c | 17 +++++++++++++++++
+ 2 files changed, 18 insertions(+)
+
+--- a/include/linux/damon.h
++++ b/include/linux/damon.h
+@@ -572,6 +572,7 @@ static inline unsigned int damon_max_nr_
+
+ int damon_start(struct damon_ctx **ctxs, int nr_ctxs, bool exclusive);
+ int damon_stop(struct damon_ctx **ctxs, int nr_ctxs);
++int damon_kdamond_pid(struct damon_ctx *ctx);
+
+ int damon_set_region_biggest_system_ram_default(struct damon_target *t,
+ unsigned long *start, unsigned long *end);
+--- a/mm/damon/core.c
++++ b/mm/damon/core.c
+@@ -643,6 +643,23 @@ static bool damon_check_reset_time_inter
+ return true;
+ }
+
++/**
++ * damon_kdamond_pid() - Return pid of a given DAMON context's worker thread.
++ * @ctx: The DAMON context of the question.
++ *
++ * Return: pid if @ctx is running, negative error code otherwise.
++ */
++int damon_kdamond_pid(struct damon_ctx *ctx)
++{
++ int pid = -EINVAL;
++
++ mutex_lock(&ctx->kdamond_lock);
++ if (ctx->kdamond)
++ pid = ctx->kdamond->pid;
++ mutex_unlock(&ctx->kdamond_lock);
++ return pid;
++}
++
+ /*
+ * Check whether it is time to flush the aggregated information
+ */
--- /dev/null
+From b98b7ff6025ae82570d4915e083f0cbd8d48b3cf Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sj@kernel.org>
+Date: Sun, 19 Apr 2026 09:10:01 -0700
+Subject: mm/damon/lru_sort: detect and use fresh enabled and kdamond_pid values
+
+From: SeongJae Park <sj@kernel.org>
+
+commit b98b7ff6025ae82570d4915e083f0cbd8d48b3cf upstream.
+
+DAMON_LRU_SORT updates 'enabled' and 'kdamond_pid' parameter values, which
+represents the running status of its kdamond, when the user explicitly
+requests start/stop of the kdamond. The kdamond can, however, be stopped
+in events other than the explicit user request in the following three
+events.
+
+1. ctx->regions_score_histogram allocation failure at beginning of the
+ execution,
+2. damon_commit_ctx() failure due to invalid user input, and
+3. damon_commit_ctx() failure due to its internal allocation failures.
+
+Hence, if the kdamond is stopped by the above three events, the values of
+the status parameters can be stale. Users could show the stale values and
+be confused. This is already bad, but the real consequence is worse.
+DAMON_LRU_SORT avoids unnecessary damon_start() and damon_stop() calls
+based on the 'enabled' parameter value. And the update of 'enabled'
+parameter value depends on the damon_start() and damon_stop() call
+results. Hence, once the kdamond has stopped by the unintentional events,
+the user cannot restart the kdamond before the system reboot. For
+example, the issue can be reproduced via below steps.
+
+ # cd /sys/module/damon_lru_sort/parameters
+ #
+ # # start DAMON_LRU_SORT
+ # echo Y > enabled
+ # ps -ef | grep kdamond
+ root 806 2 0 17:53 ? 00:00:00 [kdamond.0]
+ root 808 803 0 17:53 pts/4 00:00:00 grep kdamond
+ #
+ # # commit wrong input to stop kdamond withou explicit stop request
+ # echo 3 > addr_unit
+ # echo Y > commit_inputs
+ bash: echo: write error: Invalid argument
+ #
+ # # confirm kdamond is stopped
+ # ps -ef | grep kdamond
+ root 811 803 0 17:53 pts/4 00:00:00 grep kdamond
+ #
+ # # users casn now show stable status
+ # cat enabled
+ Y
+ # cat kdamond_pid
+ 806
+ #
+ # # even after fixing the wrong parameter,
+ # # kdamond cannot be restarted.
+ # echo 1 > addr_unit
+ # echo Y > enabled
+ # ps -ef | grep kdamond
+ root 815 803 0 17:54 pts/4 00:00:00 grep kdamond
+
+The problem will only rarely happen in real and common setups for the
+following reasons. The allocation failures are unlikely in such setups
+since those allocations are arguably too small to fail. Also sane users
+on real production environments may not commit wrong input parameters.
+But once it happens, the consequence is quite bad. And the bug is a bug.
+
+The issue stems from the fact that there are multiple events that can
+change the status, and following all the events is challenging.
+Dynamically detect and use the fresh status for the parameters when those
+are requested.
+
+Link: https://lore.kernel.org/20260419161003.79176-3-sj@kernel.org
+Fixes: 40e983cca927 ("mm/damon: introduce DAMON-based LRU-lists Sorting")
+Co-developed-by: Liew Rui Yan <aethernet65535@gmail.com>
+Signed-off-by: Liew Rui Yan <aethernet65535@gmail.com>
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org> # 6.0.x
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/damon.h | 1
+ mm/damon/core.c | 16 +++++++++
+ mm/damon/lru_sort.c | 84 +++++++++++++++++++++++++++++++++-----------------
+ 3 files changed, 73 insertions(+), 28 deletions(-)
+
+--- a/include/linux/damon.h
++++ b/include/linux/damon.h
+@@ -572,6 +572,7 @@ static inline unsigned int damon_max_nr_
+
+ int damon_start(struct damon_ctx **ctxs, int nr_ctxs, bool exclusive);
+ int damon_stop(struct damon_ctx **ctxs, int nr_ctxs);
++bool damon_is_running(struct damon_ctx *ctx);
+ int damon_kdamond_pid(struct damon_ctx *ctx);
+
+ int damon_set_region_biggest_system_ram_default(struct damon_target *t,
+--- a/mm/damon/core.c
++++ b/mm/damon/core.c
+@@ -644,6 +644,22 @@ static bool damon_check_reset_time_inter
+ }
+
+ /**
++ * damon_is_running() - Returns if a given DAMON context is running.
++ * @ctx: The DAMON context to see if running.
++ *
++ * Return: true if @ctx is running, false otherwise.
++ */
++bool damon_is_running(struct damon_ctx *ctx)
++{
++ bool running;
++
++ mutex_lock(&ctx->kdamond_lock);
++ running = ctx->kdamond != NULL;
++ mutex_unlock(&ctx->kdamond_lock);
++ return running;
++}
++
++/**
+ * damon_kdamond_pid() - Return pid of a given DAMON context's worker thread.
+ * @ctx: The DAMON context of the question.
+ *
+--- a/mm/damon/lru_sort.c
++++ b/mm/damon/lru_sort.c
+@@ -113,15 +113,6 @@ module_param(monitor_region_start, ulong
+ static unsigned long monitor_region_end __read_mostly;
+ module_param(monitor_region_end, ulong, 0600);
+
+-/*
+- * PID of the DAMON thread
+- *
+- * If DAMON_LRU_SORT is enabled, this becomes the PID of the worker thread.
+- * Else, -1.
+- */
+-static int kdamond_pid __read_mostly = -1;
+-module_param(kdamond_pid, int, 0400);
+-
+ static struct damos_stat damon_lru_sort_hot_stat;
+ DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_lru_sort_hot_stat,
+ lru_sort_tried_hot_regions, lru_sorted_hot_regions,
+@@ -249,37 +240,32 @@ static int damon_lru_sort_turn(bool on)
+ {
+ int err;
+
+- if (!on) {
+- err = damon_stop(&ctx, 1);
+- if (!err)
+- kdamond_pid = -1;
+- return err;
+- }
++ if (!on)
++ return damon_stop(&ctx, 1);
+
+ err = damon_lru_sort_apply_parameters();
+ if (err)
+ return err;
+
+- err = damon_start(&ctx, 1, true);
+- if (err)
+- return err;
+- kdamond_pid = ctx->kdamond->pid;
+- return 0;
++ return damon_start(&ctx, 1, true);
++}
++
++static bool damon_lru_sort_enabled(void)
++{
++ if (!ctx)
++ return false;
++ return damon_is_running(ctx);
+ }
+
+ static struct delayed_work damon_lru_sort_timer;
+ static void damon_lru_sort_timer_fn(struct work_struct *work)
+ {
+- static bool last_enabled;
+ bool now_enabled;
+
+ now_enabled = enabled;
+- if (last_enabled != now_enabled) {
+- if (!damon_lru_sort_turn(now_enabled))
+- last_enabled = now_enabled;
+- else
+- enabled = last_enabled;
+- }
++ if (damon_lru_sort_enabled() == now_enabled)
++ return;
++ damon_lru_sort_turn(now_enabled);
+ }
+ static DECLARE_DELAYED_WORK(damon_lru_sort_timer, damon_lru_sort_timer_fn);
+
+@@ -301,15 +287,57 @@ static int damon_lru_sort_enabled_store(
+ return 0;
+ }
+
++static int damon_lru_sort_enabled_load(char *buffer,
++ const struct kernel_param *kp)
++{
++ return sprintf(buffer, "%c\n", damon_lru_sort_enabled() ? 'Y' : 'N');
++}
++
+ static const struct kernel_param_ops enabled_param_ops = {
+ .set = damon_lru_sort_enabled_store,
+- .get = param_get_bool,
++ .get = damon_lru_sort_enabled_load,
+ };
+
+ module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
+ MODULE_PARM_DESC(enabled,
+ "Enable or disable DAMON_LRU_SORT (default: disabled)");
+
++static int damon_lru_sort_kdamond_pid_store(const char *val,
++ const struct kernel_param *kp)
++{
++ /*
++ * kdamond_pid is read-only, but kernel command line could write it.
++ * Do nothing here.
++ */
++ return 0;
++}
++
++static int damon_lru_sort_kdamond_pid_load(char *buffer,
++ const struct kernel_param *kp)
++{
++ int kdamond_pid = -1;
++
++ if (ctx) {
++ kdamond_pid = damon_kdamond_pid(ctx);
++ if (kdamond_pid < 0)
++ kdamond_pid = -1;
++ }
++ return sprintf(buffer, "%d\n", kdamond_pid);
++}
++
++static const struct kernel_param_ops kdamond_pid_param_ops = {
++ .set = damon_lru_sort_kdamond_pid_store,
++ .get = damon_lru_sort_kdamond_pid_load,
++};
++
++/*
++ * PID of the DAMON thread
++ *
++ * If DAMON_LRU_SORT is enabled, this becomes the PID of the worker thread.
++ * Else, -1.
++ */
++module_param_cb(kdamond_pid, &kdamond_pid_param_ops, NULL, 0400);
++
+ static int damon_lru_sort_handle_commit_inputs(void)
+ {
+ int err;
--- /dev/null
+From 64a140afa5ed1c6f5ba6d451512cbdbbab1ba339 Mon Sep 17 00:00:00 2001
+From: SeongJae Park <sj@kernel.org>
+Date: Sun, 19 Apr 2026 09:10:00 -0700
+Subject: mm/damon/reclaim: detect and use fresh enabled and kdamond_pid values
+
+From: SeongJae Park <sj@kernel.org>
+
+commit 64a140afa5ed1c6f5ba6d451512cbdbbab1ba339 upstream.
+
+Patch series "mm/damon/modules: detect and use fresh status", v3.
+
+DAMON modules including DAMON_RECLAIM, DAMON_LRU_SORT and DAMON_STAT
+commonly expose the kdamond running status via their parameters. Under
+certain scenarios including wrong user inputs and memory allocation
+failures, those parameter values can be stale. It can confuse users. For
+DAMON_RECLAIM and DAMON_LRU_SORT, it even makes the kdamond unable to be
+restarted before the system reboot.
+
+The problem comes from the fact that there are multiple events for the
+status changes and it is difficult to follow up all the scenarios. Fix
+the issue by detecting and using the status on demand, instead of using a
+cached status that is difficult to be updated.
+
+Patches 1-3 fix the bugs in DAMON_RECLAIM, DAMON_LRU_SORT and DAMON_STAT
+in the order.
+
+
+This patch (of 3):
+
+DAMON_RECLAIM updates 'enabled' and 'kdamond_pid' parameter values, which
+represents the running status of its kdamond, when the user explicitly
+requests start/stop of the kdamond. The kdamond can, however, be stopped
+in events other than the explicit user request in the following three
+events.
+
+1. ctx->regions_score_histogram allocation failure at beginning of the
+ execution,
+2. damon_commit_ctx() failure due to invalid user input, and
+3. damon_commit_ctx() failure due to its internal allocation failures.
+
+Hence, if the kdamond is stopped by the above three events, the values of
+the status parameters can be stale. Users could show the stale values and
+be confused. This is already bad, but the real consequence is worse.
+DAMON_RECLAIM avoids unnecessary damon_start() and damon_stop() calls
+based on the 'enabled' parameter value. And the update of 'enabled'
+parameter value depends on the damon_start() and damon_stop() call
+results. Hence, once the kdamond has stopped by the unintentional events,
+the user cannot restart the kdamond before the system reboot. For
+example, the issue can be reproduced via below steps.
+
+ # cd /sys/module/damon_reclaim/parameters
+ #
+ # # start DAMON_RECLAIM
+ # echo Y > enabled
+ # ps -ef | grep kdamond
+ root 806 2 0 17:53 ? 00:00:00 [kdamond.0]
+ root 808 803 0 17:53 pts/4 00:00:00 grep kdamond
+ #
+ # # commit wrong input to stop kdamond withou explicit stop request
+ # echo 3 > addr_unit
+ # echo Y > commit_inputs
+ bash: echo: write error: Invalid argument
+ #
+ # # confirm kdamond is stopped
+ # ps -ef | grep kdamond
+ root 811 803 0 17:53 pts/4 00:00:00 grep kdamond
+ #
+ # # users casn now show stable status
+ # cat enabled
+ Y
+ # cat kdamond_pid
+ 806
+ #
+ # # even after fixing the wrong parameter,
+ # # kdamond cannot be restarted.
+ # echo 1 > addr_unit
+ # echo Y > enabled
+ # ps -ef | grep kdamond
+ root 815 803 0 17:54 pts/4 00:00:00 grep kdamond
+
+The problem will only rarely happen in real and common setups for the
+following reasons. The allocation failures are unlikely in such setups
+since those allocations are arguably too small to fail. Also sane users
+on real production environments may not commit wrong input parameters.
+But once it happens, the consequence is quite bad. And the bug is a bug.
+
+The issue stems from the fact that there are multiple events that can
+change the status, and following all the events is challenging.
+Dynamically detect and use the fresh status for the parameters when those
+are requested.
+
+Link: https://lore.kernel.org/20260419161003.79176-1-sj@kernel.org
+Link: https://lore.kernel.org/20260419161003.79176-2-sj@kernel.org
+Fixes: e035c280f6df ("mm/damon/reclaim: support online inputs update")
+Co-developed-by: Liew Rui Yan <aethernet65535@gmail.com>
+Signed-off-by: Liew Rui Yan <aethernet65535@gmail.com>
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Cc: <stable@vger.kernel.org> # 5.19.x
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: SeongJae Park <sj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/damon/reclaim.c | 84 +++++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 56 insertions(+), 28 deletions(-)
+
+--- a/mm/damon/reclaim.c
++++ b/mm/damon/reclaim.c
+@@ -100,15 +100,6 @@ module_param(monitor_region_start, ulong
+ static unsigned long monitor_region_end __read_mostly;
+ module_param(monitor_region_end, ulong, 0600);
+
+-/*
+- * PID of the DAMON thread
+- *
+- * If DAMON_RECLAIM is enabled, this becomes the PID of the worker thread.
+- * Else, -1.
+- */
+-static int kdamond_pid __read_mostly = -1;
+-module_param(kdamond_pid, int, 0400);
+-
+ static struct damos_stat damon_reclaim_stat;
+ DEFINE_DAMON_MODULES_DAMOS_STATS_PARAMS(damon_reclaim_stat,
+ reclaim_tried_regions, reclaimed_regions, quota_exceeds);
+@@ -184,37 +175,32 @@ static int damon_reclaim_turn(bool on)
+ {
+ int err;
+
+- if (!on) {
+- err = damon_stop(&ctx, 1);
+- if (!err)
+- kdamond_pid = -1;
+- return err;
+- }
++ if (!on)
++ return damon_stop(&ctx, 1);
+
+ err = damon_reclaim_apply_parameters();
+ if (err)
+ return err;
+
+- err = damon_start(&ctx, 1, true);
+- if (err)
+- return err;
+- kdamond_pid = ctx->kdamond->pid;
+- return 0;
++ return damon_start(&ctx, 1, true);
++}
++
++static bool damon_reclaim_enabled(void)
++{
++ if (!ctx)
++ return false;
++ return damon_is_running(ctx);
+ }
+
+ static struct delayed_work damon_reclaim_timer;
+ static void damon_reclaim_timer_fn(struct work_struct *work)
+ {
+- static bool last_enabled;
+ bool now_enabled;
+
+ now_enabled = enabled;
+- if (last_enabled != now_enabled) {
+- if (!damon_reclaim_turn(now_enabled))
+- last_enabled = now_enabled;
+- else
+- enabled = last_enabled;
+- }
++ if (damon_reclaim_enabled() != now_enabled)
++ return;
++ damon_reclaim_turn(now_enabled);
+ }
+ static DECLARE_DELAYED_WORK(damon_reclaim_timer, damon_reclaim_timer_fn);
+
+@@ -236,15 +222,57 @@ static int damon_reclaim_enabled_store(c
+ return 0;
+ }
+
++static int damon_reclaim_enabled_load(char *buffer,
++ const struct kernel_param *kp)
++{
++ return sprintf(buffer, "%c\n", damon_reclaim_enabled() ? 'Y' : 'N');
++}
++
+ static const struct kernel_param_ops enabled_param_ops = {
+ .set = damon_reclaim_enabled_store,
+- .get = param_get_bool,
++ .get = damon_reclaim_enabled_load,
+ };
+
+ module_param_cb(enabled, &enabled_param_ops, &enabled, 0600);
+ MODULE_PARM_DESC(enabled,
+ "Enable or disable DAMON_RECLAIM (default: disabled)");
+
++static int damon_reclaim_kdamond_pid_store(const char *val,
++ const struct kernel_param *kp)
++{
++ /*
++ * kdamond_pid is read-only, but kernel command line could write it.
++ * Do nothing here.
++ */
++ return 0;
++}
++
++static int damon_reclaim_kdamond_pid_load(char *buffer,
++ const struct kernel_param *kp)
++{
++ int kdamond_pid = -1;
++
++ if (ctx) {
++ kdamond_pid = damon_kdamond_pid(ctx);
++ if (kdamond_pid < 0)
++ kdamond_pid = -1;
++ }
++ return sprintf(buffer, "%d\n", kdamond_pid);
++}
++
++static const struct kernel_param_ops kdamond_pid_param_ops = {
++ .set = damon_reclaim_kdamond_pid_store,
++ .get = damon_reclaim_kdamond_pid_load,
++};
++
++/*
++ * PID of the DAMON thread
++ *
++ * If DAMON_RECLAIM is enabled, this becomes the PID of the worker thread.
++ * Else, -1.
++ */
++module_param_cb(kdamond_pid, &kdamond_pid_param_ops, NULL, 0400);
++
+ static int damon_reclaim_handle_commit_inputs(void)
+ {
+ int err;
mm-damon-core-disallow-time-quota-setting-zero-esz.patch
usb-typec-tcpm-reset-internal-port-states-on-soft-reset-ams.patch
lib-crypto-mpi-fix-integer-underflow-in-mpi_read_raw_from_sgl.patch
+ipmi-ssif-remove-unnecessary-indention.patch
+ipmi-ssif-null-thread-on-error.patch
+mm-damon-core-implement-damon_kdamond_pid.patch
+mm-damon-lru_sort-detect-and-use-fresh-enabled-and-kdamond_pid-values.patch
+mm-damon-reclaim-detect-and-use-fresh-enabled-and-kdamond_pid-values.patch
+drm-v3d-reject-empty-multisync-extension-to-prevent-infinite-loop.patch