If a delayed or deferrable work is on stack we need to tell debug objects that we are destroying the timer and the work. Otherwise we leak the tracking object.
Unified · Split
| @@ -191,6 +191,7 @@ struct execute_work { · 190 unmodified lines | ||
| 191 | 191 | #ifdef CONFIG_DEBUG_OBJECTS_WORK |
| 192 | 192 | extern void __init_work(struct work_struct *work, int onstack); |
| 193 | 193 | extern void destroy_work_on_stack(struct work_struct *work); |
| 194 | +extern void destroy_delayed_work_on_stack(struct delayed_work *work); | |
| 194 | 195 | static inline unsigned int work_static(struct work_struct *work) |
| 195 | 196 | { |
| 196 | 197 | return *work_data_bits(work) & WORK_STRUCT_STATIC; |
| @@ -198,6 +199,7 @@ static inline unsigned int work_static(struct work_struct *work) · 1 unmodified line | ||
| 198 | 199 | #else |
| 199 | 200 | static inline void __init_work(struct work_struct *work, int onstack) { } |
| 200 | 201 | static inline void destroy_work_on_stack(struct work_struct *work) { } |
| 202 | +static inline void destroy_delayed_work_on_stack(struct delayed_work *work) { } | |
| 201 | 203 | static inline unsigned int work_static(struct work_struct *work) { return 0; } |
| 202 | 204 | #endif |
| 203 | 205 | |
| @@ -516,6 +516,13 @@ void destroy_work_on_stack(struct work_struct *work) · 515 unmodified lines | ||
| 516 | 516 | } |
| 517 | 517 | EXPORT_SYMBOL_GPL(destroy_work_on_stack); |
| 518 | 518 | |
| 519 | +void destroy_delayed_work_on_stack(struct delayed_work *work) | |
| 520 | +{ | |
| 521 | + destroy_timer_on_stack(&work->timer); | |
| 522 | + debug_object_free(&work->work, &work_debug_descr); | |
| 523 | +} | |
| 524 | +EXPORT_SYMBOL_GPL(destroy_delayed_work_on_stack); | |
| 525 | + | |
| 519 | 526 | #else |
| 520 | 527 | static inline void debug_work_activate(struct work_struct *work) { } |
| 521 | 528 | static inline void debug_work_deactivate(struct work_struct *work) { } |