Skip to content

Commit 317f29c

Browse files
bebarinoKAGA-KOKO
authored andcommitted
timers: Provide a better debugobjects hint for delayed works
With debugobjects enabled the timer hint for freeing of active timers embedded inside delayed works is always the same, i.e. the hint is delayed_work_timer_fn, even though the function the delayed work is going to run can be wildly different depending on what work was queued. Enabling workqueue debugobjects doesn't help either because the delayed work isn't considered active until it is actually queued to run on a workqueue. If the work is freed while the timer is pending the work isn't considered active so there is no information from workqueue debugobjects. Special case delayed works in the timer debugobjects hint logic so that the delayed work function is returned instead of the delayed_work_timer_fn. This will help to understand which delayed work was pending that got freed. Apply the same treatment for kthread_delayed_work because it follows the same pattern. Suggested-by: Thomas Gleixner <[email protected]> Signed-off-by: Stephen Boyd <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent f4b62e1 commit 317f29c

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

kernel/time/timer.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,9 +638,39 @@ static void internal_add_timer(struct timer_base *base, struct timer_list *timer
638638

639639
static const struct debug_obj_descr timer_debug_descr;
640640

641+
struct timer_hint {
642+
void (*function)(struct timer_list *t);
643+
long offset;
644+
};
645+
646+
#define TIMER_HINT(fn, container, timr, hintfn) \
647+
{ \
648+
.function = fn, \
649+
.offset = offsetof(container, hintfn) - \
650+
offsetof(container, timr) \
651+
}
652+
653+
static const struct timer_hint timer_hints[] = {
654+
TIMER_HINT(delayed_work_timer_fn,
655+
struct delayed_work, timer, work.func),
656+
TIMER_HINT(kthread_delayed_work_timer_fn,
657+
struct kthread_delayed_work, timer, work.func),
658+
};
659+
641660
static void *timer_debug_hint(void *addr)
642661
{
643-
return ((struct timer_list *) addr)->function;
662+
struct timer_list *timer = addr;
663+
int i;
664+
665+
for (i = 0; i < ARRAY_SIZE(timer_hints); i++) {
666+
if (timer_hints[i].function == timer->function) {
667+
void (**fn)(void) = addr + timer_hints[i].offset;
668+
669+
return *fn;
670+
}
671+
}
672+
673+
return timer->function;
644674
}
645675

646676
static bool timer_is_static_object(void *addr)

0 commit comments

Comments
 (0)