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 | #ifdef CONFIG_DEBUG_OBJECTS_WORK | 191 | #ifdef CONFIG_DEBUG_OBJECTS_WORK |
| 192 | extern void __init_work(struct work_struct *work, int onstack); | 192 | extern void __init_work(struct work_struct *work, int onstack); |
| 193 | extern void destroy_work_on_stack(struct work_struct *work); | 193 | extern void destroy_work_on_stack(struct work_struct *work); |
| 194 | extern void destroy_delayed_work_on_stack(struct delayed_work *work); | ||
| 194 | static inline unsigned int work_static(struct work_struct *work) | 195 | static inline unsigned int work_static(struct work_struct *work) |
| 195 | { | 196 | { |
| 196 | return *work_data_bits(work) & WORK_STRUCT_STATIC; | 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 | #else | 199 | #else |
| 199 | static inline void __init_work(struct work_struct *work, int onstack) { } | 200 | static inline void __init_work(struct work_struct *work, int onstack) { } |
| 200 | static inline void destroy_work_on_stack(struct work_struct *work) { } | 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 | static inline unsigned int work_static(struct work_struct *work) { return 0; } | 203 | static inline unsigned int work_static(struct work_struct *work) { return 0; } |
| 202 | #endif | 204 | #endif |
| 203 | 205 | ||
| @@ -516,6 +516,13 @@ void destroy_work_on_stack(struct work_struct *work) · 515 unmodified lines | |||
| 516 | } | 516 | } |
| 517 | EXPORT_SYMBOL_GPL(destroy_work_on_stack); | 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 | #else | 526 | #else |
| 520 | static inline void debug_work_activate(struct work_struct *work) { } | 527 | static inline void debug_work_activate(struct work_struct *work) { } |
| 521 | static inline void debug_work_deactivate(struct work_struct *work) { } | 528 | static inline void debug_work_deactivate(struct work_struct *work) { } |