Because DAMON sleeps in uninterruptible mode, /proc/loadavg reports fake
load while DAMON is turned on, though it is doing nothing. This can
confuse users[1]. To avoid the case, this commit makes DAMON sleeps in
idle mode.
[1] https://lore.kernel.org/all/11868371.O9o76ZdvQC@natalenko.name/
Fixes: 2224d8485492 ("mm: introduce Data Access MONitor (DAMON)")
Reported-by: Oleksandr Natalenko <oleksandr(a)natalenko.name>
Signed-off-by: SeongJae Park <sj(a)kernel.org>
Cc: <stable(a)vger.kernel.org> # 5.15.x
---
I think this needs to be applied on v5.15.y, but this cannot cleanly
applied there as is. I will back-port this on v5.15.y and post later
once this is merged in the mainline.
mm/damon/core.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index daacd9536c7c..7813f47aadc9 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -12,6 +12,8 @@
#include <linux/kthread.h>
#include <linux/mm.h>
#include <linux/random.h>
+#include <linux/sched.h>
+#include <linux/sched/debug.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -976,12 +978,25 @@ static unsigned long damos_wmark_wait_us(struct damos *scheme)
return 0;
}
+/* sleep for @usecs in idle mode */
+static void __sched damon_usleep_idle(unsigned long usecs)
+{
+ ktime_t exp = ktime_add_us(ktime_get(), usecs);
+ u64 delta = usecs * NSEC_PER_USEC / 100; /* allow 1% error */
+
+ for (;;) {
+ __set_current_state(TASK_IDLE);
+ if (!schedule_hrtimeout_range(&exp, delta, HRTIMER_MODE_ABS))
+ break;
+ }
+}
+
static void kdamond_usleep(unsigned long usecs)
{
if (usecs > 100 * 1000)
- schedule_timeout_interruptible(usecs_to_jiffies(usecs));
+ schedule_timeout_idle(usecs_to_jiffies(usecs));
else
- usleep_range(usecs, usecs + 1);
+ damon_usleep_idle(usecs);
}
/* Returns negative error code if it's not activated but should return */
@@ -1036,7 +1051,7 @@ static int kdamond_fn(void *data)
ctx->callback.after_sampling(ctx))
done = true;
- usleep_range(ctx->sample_interval, ctx->sample_interval + 1);
+ kdamond_usleep(ctx->sample_interval);
if (ctx->primitive.check_accesses)
max_nr_accesses = ctx->primitive.check_accesses(ctx);
--
2.17.1
Regression found on arm gcc-11 builds
Following build warnings / errors reported on stable-rc queue/5.10.
metadata:
git_describe: v5.10.81-155-gca79bd042925
git_repo: https://gitlab.com/Linaro/lkft/mirrors/stable/linux-stable-rc-queues
git_short_log: ca79bd042925 (\"x86/Kconfig: Fix an unused variable
error in dell-smm-hwmon\")
target_arch: arm
toolchain: gcc-11
build error :
--------------
arch/arm/boot/dts/bcm53016-meraki-mr32.dts:204.4-14: Warning
(reg_format): /srab@18007000/ports/port@0:reg: property has invalid
length (4 bytes) (#address-cells == 2, #size-cells == 1)
arch/arm/boot/dts/bcm53016-meraki-mr32.dts:209.4-14: Warning
(reg_format): /srab@18007000/ports/port@5:reg: property has invalid
length (4 bytes) (#address-cells == 2, #size-cells == 1)
arch/arm/boot/dts/bcm53016-meraki-mr32.dtb: Warning
(pci_device_bus_num): Failed prerequisite 'reg_format'
arch/arm/boot/dts/bcm53016-meraki-mr32.dtb: Warning (i2c_bus_reg):
Failed prerequisite 'reg_format'
arch/arm/boot/dts/bcm53016-meraki-mr32.dtb: Warning (spi_bus_reg):
Failed prerequisite 'reg_format'
arch/arm/boot/dts/bcm53016-meraki-mr32.dts:203.10-206.5: Warning
(avoid_default_addr_size): /srab@18007000/ports/port@0: Relying on
default #address-cells value
arch/arm/boot/dts/bcm53016-meraki-mr32.dts:203.10-206.5: Warning
(avoid_default_addr_size): /srab@18007000/ports/port@0: Relying on
default #size-cells value
arch/arm/boot/dts/bcm53016-meraki-mr32.dts:208.10-217.5: Warning
(avoid_default_addr_size): /srab@18007000/ports/port@5: Relying on
default #address-cells value
arch/arm/boot/dts/bcm53016-meraki-mr32.dts:208.10-217.5: Warning
(avoid_default_addr_size): /srab@18007000/ports/port@5: Relying on
default #size-cells value
drivers/cpuidle/cpuidle-tegra.c: In function 'tegra_cpuidle_probe':
drivers/cpuidle/cpuidle-tegra.c:349:38: error:
'TEGRA_SUSPEND_NOT_READY' undeclared (first use in this function); did
you mean 'TEGRA_SUSPEND_NONE'?
349 | if (tegra_pmc_get_suspend_mode() == TEGRA_SUSPEND_NOT_READY)
| ^~~~~~~~~~~~~~~~~~~~~~~
| TEGRA_SUSPEND_NONE
Reported-by: Linux Kernel Functional Testing <lkft(a)linaro.org>
due to the following patch,
cpuidle: tegra: Check whether PMC is ready
[ Upstream commit bdb1ffdad3b73e4d0538098fc02e2ea87a6b27cd ]
Check whether PMC is ready before proceeding with the cpuidle registration.
This fixes racing with the PMC driver probe order, which results in a
disabled deepest CC6 idling state if cpuidle driver is probed before the
PMC.
Acked-by: Daniel Lezcano <daniel.lezcano(a)linaro.org>
Signed-off-by: Dmitry Osipenko <digetx(a)gmail.com>
Signed-off-by: Thierry Reding <treding(a)nvidia.com>
Signed-off-by: Sasha Levin <sashal(a)kernel.org>
build link:
-----------
https://builds.tuxbuild.com//21Ma7IQryRIdyeUb4V2IeX4ePy8/build.log
build config:
-------------
https://builds.tuxbuild.com//21Ma7IQryRIdyeUb4V2IeX4ePy8/config
# To install tuxmake on your system globally
# sudo pip3 install -U tuxmake
tuxmake --runtime podman --target-arch arm --toolchain gcc-10
--kconfig defconfig \
--kconfig-add
https://builds.tuxbuild.com//21Ma7IQryRIdyeUb4V2IeX4ePy8/config
--
Linaro LKFT
https://lkft.linaro.org