|
Oliver Neukum |
8d1d68 |
From 317f29c14d0cca09952f1022491454b23455ebcb Mon Sep 17 00:00:00 2001
|
|
Oliver Neukum |
8d1d68 |
From: Stephen Boyd <swboyd@chromium.org>
|
|
Oliver Neukum |
8d1d68 |
Date: Wed, 11 May 2022 13:19:51 -0700
|
|
Oliver Neukum |
8d1d68 |
Subject: [PATCH] timers: Provide a better debugobjects hint for delayed works
|
|
Oliver Neukum |
8d1d68 |
Git-commit: 317f29c14d0cca09952f1022491454b23455ebcb
|
|
Oliver Neukum |
8d1d68 |
References: bsc#1207210
|
|
Oliver Neukum |
8d1d68 |
Patch-mainline: v5.19-rc1
|
|
Oliver Neukum |
8d1d68 |
|
|
Oliver Neukum |
8d1d68 |
With debugobjects enabled the timer hint for freeing of active timers
|
|
Oliver Neukum |
8d1d68 |
embedded inside delayed works is always the same, i.e. the hint is
|
|
Oliver Neukum |
8d1d68 |
delayed_work_timer_fn, even though the function the delayed work is going
|
|
Oliver Neukum |
8d1d68 |
to run can be wildly different depending on what work was queued. Enabling
|
|
Oliver Neukum |
8d1d68 |
workqueue debugobjects doesn't help either because the delayed work isn't
|
|
Oliver Neukum |
8d1d68 |
considered active until it is actually queued to run on a workqueue. If the
|
|
Oliver Neukum |
8d1d68 |
work is freed while the timer is pending the work isn't considered active
|
|
Oliver Neukum |
8d1d68 |
so there is no information from workqueue debugobjects.
|
|
Oliver Neukum |
8d1d68 |
|
|
Oliver Neukum |
8d1d68 |
Special case delayed works in the timer debugobjects hint logic so that the
|
|
Oliver Neukum |
8d1d68 |
delayed work function is returned instead of the delayed_work_timer_fn.
|
|
Oliver Neukum |
8d1d68 |
This will help to understand which delayed work was pending that got
|
|
Oliver Neukum |
8d1d68 |
freed.
|
|
Oliver Neukum |
8d1d68 |
|
|
Oliver Neukum |
8d1d68 |
Apply the same treatment for kthread_delayed_work because it follows the
|
|
Oliver Neukum |
8d1d68 |
same pattern.
|
|
Oliver Neukum |
8d1d68 |
|
|
Oliver Neukum |
8d1d68 |
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Oliver Neukum |
8d1d68 |
Signed-off-by: Stephen Boyd <swboyd@chromium.org>
|
|
Oliver Neukum |
8d1d68 |
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Oliver Neukum |
8d1d68 |
Link: https://lore.kernel.org/r/20220511201951.42408-1-swboyd@chromium.org
|
|
Oliver Neukum |
8d1d68 |
Signed-off-by: Oliver Neukum <oneukum@suse.com>
|
|
Oliver Neukum |
8d1d68 |
---
|
|
Oliver Neukum |
8d1d68 |
kernel/time/timer.c | 32 +++++++++++++++++++++++++++++++-
|
|
Oliver Neukum |
8d1d68 |
1 file changed, 31 insertions(+), 1 deletion(-)
|
|
Oliver Neukum |
8d1d68 |
|
|
Oliver Neukum |
8d1d68 |
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
|
|
Oliver Neukum |
8d1d68 |
index ef082d43c307..a0666d948147 100644
|
|
Oliver Neukum |
8d1d68 |
--- a/kernel/time/timer.c
|
|
Oliver Neukum |
8d1d68 |
+++ b/kernel/time/timer.c
|
|
Oliver Neukum |
8d1d68 |
@@ -638,9 +638,39 @@ static void internal_add_timer(struct timer_base *base, struct timer_list *timer
|
|
Oliver Neukum |
8d1d68 |
|
|
Oliver Neukum |
8d1d68 |
static const struct debug_obj_descr timer_debug_descr;
|
|
Oliver Neukum |
8d1d68 |
|
|
Oliver Neukum |
8d1d68 |
+struct timer_hint {
|
|
Oliver Neukum |
8d1d68 |
+ void (*function)(struct timer_list *t);
|
|
Oliver Neukum |
8d1d68 |
+ long offset;
|
|
Oliver Neukum |
8d1d68 |
+};
|
|
Oliver Neukum |
8d1d68 |
+
|
|
Oliver Neukum |
8d1d68 |
+#define TIMER_HINT(fn, container, timr, hintfn) \
|
|
Oliver Neukum |
8d1d68 |
+ { \
|
|
Oliver Neukum |
8d1d68 |
+ .function = fn, \
|
|
Oliver Neukum |
8d1d68 |
+ .offset = offsetof(container, hintfn) - \
|
|
Oliver Neukum |
8d1d68 |
+ offsetof(container, timr) \
|
|
Oliver Neukum |
8d1d68 |
+ }
|
|
Oliver Neukum |
8d1d68 |
+
|
|
Oliver Neukum |
8d1d68 |
+static const struct timer_hint timer_hints[] = {
|
|
Oliver Neukum |
8d1d68 |
+ TIMER_HINT(delayed_work_timer_fn,
|
|
Oliver Neukum |
8d1d68 |
+ struct delayed_work, timer, work.func),
|
|
Oliver Neukum |
8d1d68 |
+ TIMER_HINT(kthread_delayed_work_timer_fn,
|
|
Oliver Neukum |
8d1d68 |
+ struct kthread_delayed_work, timer, work.func),
|
|
Oliver Neukum |
8d1d68 |
+};
|
|
Oliver Neukum |
8d1d68 |
+
|
|
Oliver Neukum |
8d1d68 |
static void *timer_debug_hint(void *addr)
|
|
Oliver Neukum |
8d1d68 |
{
|
|
Oliver Neukum |
8d1d68 |
- return ((struct timer_list *) addr)->function;
|
|
Oliver Neukum |
8d1d68 |
+ struct timer_list *timer = addr;
|
|
Oliver Neukum |
8d1d68 |
+ int i;
|
|
Oliver Neukum |
8d1d68 |
+
|
|
Oliver Neukum |
8d1d68 |
+ for (i = 0; i < ARRAY_SIZE(timer_hints); i++) {
|
|
Oliver Neukum |
8d1d68 |
+ if (timer_hints[i].function == timer->function) {
|
|
Oliver Neukum |
8d1d68 |
+ void (**fn)(void) = addr + timer_hints[i].offset;
|
|
Oliver Neukum |
8d1d68 |
+
|
|
Oliver Neukum |
8d1d68 |
+ return *fn;
|
|
Oliver Neukum |
8d1d68 |
+ }
|
|
Oliver Neukum |
8d1d68 |
+ }
|
|
Oliver Neukum |
8d1d68 |
+
|
|
Oliver Neukum |
8d1d68 |
+ return timer->function;
|
|
Oliver Neukum |
8d1d68 |
}
|
|
Oliver Neukum |
8d1d68 |
|
|
Oliver Neukum |
8d1d68 |
static bool timer_is_static_object(void *addr)
|
|
Oliver Neukum |
8d1d68 |
--
|
|
Oliver Neukum |
8d1d68 |
2.39.0
|
|
Oliver Neukum |
8d1d68 |
|