11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * workqueue.h --- work queue handling for Linux. 31da177e4SLinus Torvalds */ 41da177e4SLinus Torvalds 51da177e4SLinus Torvalds #ifndef _LINUX_WORKQUEUE_H 61da177e4SLinus Torvalds #define _LINUX_WORKQUEUE_H 71da177e4SLinus Torvalds 81da177e4SLinus Torvalds #include <linux/timer.h> 91da177e4SLinus Torvalds #include <linux/linkage.h> 101da177e4SLinus Torvalds #include <linux/bitops.h> 114e6045f1SJohannes Berg #include <linux/lockdep.h> 12a08727baSLinus Torvalds #include <asm/atomic.h> 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds struct workqueue_struct; 151da177e4SLinus Torvalds 1665f27f38SDavid Howells struct work_struct; 1765f27f38SDavid Howells typedef void (*work_func_t)(struct work_struct *work); 186bb49e59SDavid Howells 19a08727baSLinus Torvalds /* 20a08727baSLinus Torvalds * The first word is the work queue pointer and the flags rolled into 21a08727baSLinus Torvalds * one 22a08727baSLinus Torvalds */ 23a08727baSLinus Torvalds #define work_data_bits(work) ((unsigned long *)(&(work)->data)) 24a08727baSLinus Torvalds 2522df02bbSTejun Heo enum { 2622df02bbSTejun Heo WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */ 27affee4b2STejun Heo WORK_STRUCT_LINKED_BIT = 1, /* next work is linked to this one */ 2822df02bbSTejun Heo #ifdef CONFIG_DEBUG_OBJECTS_WORK 29affee4b2STejun Heo WORK_STRUCT_STATIC_BIT = 2, /* static initializer (debugobjects) */ 3073f53c4aSTejun Heo WORK_STRUCT_COLOR_SHIFT = 3, /* color for workqueue flushing */ 310f900049STejun Heo #else 3273f53c4aSTejun Heo WORK_STRUCT_COLOR_SHIFT = 2, /* color for workqueue flushing */ 3322df02bbSTejun Heo #endif 3422df02bbSTejun Heo 3573f53c4aSTejun Heo WORK_STRUCT_COLOR_BITS = 4, 3673f53c4aSTejun Heo 3722df02bbSTejun Heo WORK_STRUCT_PENDING = 1 << WORK_STRUCT_PENDING_BIT, 38affee4b2STejun Heo WORK_STRUCT_LINKED = 1 << WORK_STRUCT_LINKED_BIT, 3922df02bbSTejun Heo #ifdef CONFIG_DEBUG_OBJECTS_WORK 4022df02bbSTejun Heo WORK_STRUCT_STATIC = 1 << WORK_STRUCT_STATIC_BIT, 4122df02bbSTejun Heo #else 4222df02bbSTejun Heo WORK_STRUCT_STATIC = 0, 4322df02bbSTejun Heo #endif 4422df02bbSTejun Heo 4573f53c4aSTejun Heo /* 4673f53c4aSTejun Heo * The last color is no color used for works which don't 4773f53c4aSTejun Heo * participate in workqueue flushing. 4873f53c4aSTejun Heo */ 4973f53c4aSTejun Heo WORK_NR_COLORS = (1 << WORK_STRUCT_COLOR_BITS) - 1, 5073f53c4aSTejun Heo WORK_NO_COLOR = WORK_NR_COLORS, 5173f53c4aSTejun Heo 5273f53c4aSTejun Heo /* 5373f53c4aSTejun Heo * Reserve 6 bits off of cwq pointer w/ debugobjects turned 5473f53c4aSTejun Heo * off. This makes cwqs aligned to 64 bytes which isn't too 5573f53c4aSTejun Heo * excessive while allowing 15 workqueue flush colors. 5673f53c4aSTejun Heo */ 5773f53c4aSTejun Heo WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + 5873f53c4aSTejun Heo WORK_STRUCT_COLOR_BITS, 5973f53c4aSTejun Heo 600f900049STejun Heo WORK_STRUCT_FLAG_MASK = (1UL << WORK_STRUCT_FLAG_BITS) - 1, 6122df02bbSTejun Heo WORK_STRUCT_WQ_DATA_MASK = ~WORK_STRUCT_FLAG_MASK, 6222df02bbSTejun Heo }; 6322df02bbSTejun Heo 641da177e4SLinus Torvalds struct work_struct { 65a08727baSLinus Torvalds atomic_long_t data; 661da177e4SLinus Torvalds struct list_head entry; 676bb49e59SDavid Howells work_func_t func; 684e6045f1SJohannes Berg #ifdef CONFIG_LOCKDEP 694e6045f1SJohannes Berg struct lockdep_map lockdep_map; 704e6045f1SJohannes Berg #endif 7152bad64dSDavid Howells }; 7252bad64dSDavid Howells 7323b2e599SOleg Nesterov #define WORK_DATA_INIT() ATOMIC_LONG_INIT(0) 7422df02bbSTejun Heo #define WORK_DATA_STATIC_INIT() ATOMIC_LONG_INIT(WORK_STRUCT_STATIC) 75a08727baSLinus Torvalds 7652bad64dSDavid Howells struct delayed_work { 7752bad64dSDavid Howells struct work_struct work; 781da177e4SLinus Torvalds struct timer_list timer; 791da177e4SLinus Torvalds }; 801da177e4SLinus Torvalds 81bf6aede7SJean Delvare static inline struct delayed_work *to_delayed_work(struct work_struct *work) 82bf6aede7SJean Delvare { 83bf6aede7SJean Delvare return container_of(work, struct delayed_work, work); 84bf6aede7SJean Delvare } 85bf6aede7SJean Delvare 861fa44ecaSJames Bottomley struct execute_work { 871fa44ecaSJames Bottomley struct work_struct work; 881fa44ecaSJames Bottomley }; 891fa44ecaSJames Bottomley 904e6045f1SJohannes Berg #ifdef CONFIG_LOCKDEP 914e6045f1SJohannes Berg /* 924e6045f1SJohannes Berg * NB: because we have to copy the lockdep_map, setting _key 934e6045f1SJohannes Berg * here is required, otherwise it could get initialised to the 944e6045f1SJohannes Berg * copy of the lockdep_map! 954e6045f1SJohannes Berg */ 964e6045f1SJohannes Berg #define __WORK_INIT_LOCKDEP_MAP(n, k) \ 974e6045f1SJohannes Berg .lockdep_map = STATIC_LOCKDEP_MAP_INIT(n, k), 984e6045f1SJohannes Berg #else 994e6045f1SJohannes Berg #define __WORK_INIT_LOCKDEP_MAP(n, k) 1004e6045f1SJohannes Berg #endif 1014e6045f1SJohannes Berg 10265f27f38SDavid Howells #define __WORK_INITIALIZER(n, f) { \ 103dc186ad7SThomas Gleixner .data = WORK_DATA_STATIC_INIT(), \ 10465f27f38SDavid Howells .entry = { &(n).entry, &(n).entry }, \ 10565f27f38SDavid Howells .func = (f), \ 1064e6045f1SJohannes Berg __WORK_INIT_LOCKDEP_MAP(#n, &(n)) \ 10765f27f38SDavid Howells } 10865f27f38SDavid Howells 10965f27f38SDavid Howells #define __DELAYED_WORK_INITIALIZER(n, f) { \ 11065f27f38SDavid Howells .work = __WORK_INITIALIZER((n).work, (f)), \ 1111da177e4SLinus Torvalds .timer = TIMER_INITIALIZER(NULL, 0, 0), \ 1121da177e4SLinus Torvalds } 1131da177e4SLinus Torvalds 11465f27f38SDavid Howells #define DECLARE_WORK(n, f) \ 11565f27f38SDavid Howells struct work_struct n = __WORK_INITIALIZER(n, f) 11665f27f38SDavid Howells 11765f27f38SDavid Howells #define DECLARE_DELAYED_WORK(n, f) \ 11865f27f38SDavid Howells struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f) 11965f27f38SDavid Howells 1201da177e4SLinus Torvalds /* 12165f27f38SDavid Howells * initialize a work item's function pointer 1221da177e4SLinus Torvalds */ 12365f27f38SDavid Howells #define PREPARE_WORK(_work, _func) \ 1241da177e4SLinus Torvalds do { \ 12552bad64dSDavid Howells (_work)->func = (_func); \ 1261da177e4SLinus Torvalds } while (0) 1271da177e4SLinus Torvalds 12865f27f38SDavid Howells #define PREPARE_DELAYED_WORK(_work, _func) \ 12965f27f38SDavid Howells PREPARE_WORK(&(_work)->work, (_func)) 13052bad64dSDavid Howells 131dc186ad7SThomas Gleixner #ifdef CONFIG_DEBUG_OBJECTS_WORK 132dc186ad7SThomas Gleixner extern void __init_work(struct work_struct *work, int onstack); 133dc186ad7SThomas Gleixner extern void destroy_work_on_stack(struct work_struct *work); 1344690c4abSTejun Heo static inline unsigned int work_static(struct work_struct *work) 1354690c4abSTejun Heo { 13622df02bbSTejun Heo return *work_data_bits(work) & WORK_STRUCT_STATIC; 1374690c4abSTejun Heo } 138dc186ad7SThomas Gleixner #else 139dc186ad7SThomas Gleixner static inline void __init_work(struct work_struct *work, int onstack) { } 140dc186ad7SThomas Gleixner static inline void destroy_work_on_stack(struct work_struct *work) { } 1414690c4abSTejun Heo static inline unsigned int work_static(struct work_struct *work) { return 0; } 142dc186ad7SThomas Gleixner #endif 143dc186ad7SThomas Gleixner 1441da177e4SLinus Torvalds /* 14552bad64dSDavid Howells * initialize all of a work item in one go 146a08727baSLinus Torvalds * 147b9049df5SDmitri Vorobiev * NOTE! No point in using "atomic_long_set()": using a direct 148a08727baSLinus Torvalds * assignment of the work data initializer allows the compiler 149a08727baSLinus Torvalds * to generate better code. 1501da177e4SLinus Torvalds */ 1514e6045f1SJohannes Berg #ifdef CONFIG_LOCKDEP 152dc186ad7SThomas Gleixner #define __INIT_WORK(_work, _func, _onstack) \ 1534e6045f1SJohannes Berg do { \ 1544e6045f1SJohannes Berg static struct lock_class_key __key; \ 1554e6045f1SJohannes Berg \ 156dc186ad7SThomas Gleixner __init_work((_work), _onstack); \ 1574e6045f1SJohannes Berg (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ 1584e6045f1SJohannes Berg lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0);\ 1594e6045f1SJohannes Berg INIT_LIST_HEAD(&(_work)->entry); \ 1604e6045f1SJohannes Berg PREPARE_WORK((_work), (_func)); \ 1614e6045f1SJohannes Berg } while (0) 1624e6045f1SJohannes Berg #else 163dc186ad7SThomas Gleixner #define __INIT_WORK(_work, _func, _onstack) \ 1641da177e4SLinus Torvalds do { \ 165dc186ad7SThomas Gleixner __init_work((_work), _onstack); \ 16623b2e599SOleg Nesterov (_work)->data = (atomic_long_t) WORK_DATA_INIT(); \ 16765f27f38SDavid Howells INIT_LIST_HEAD(&(_work)->entry); \ 16865f27f38SDavid Howells PREPARE_WORK((_work), (_func)); \ 16965f27f38SDavid Howells } while (0) 1704e6045f1SJohannes Berg #endif 17165f27f38SDavid Howells 172dc186ad7SThomas Gleixner #define INIT_WORK(_work, _func) \ 173dc186ad7SThomas Gleixner do { \ 174dc186ad7SThomas Gleixner __INIT_WORK((_work), (_func), 0); \ 175dc186ad7SThomas Gleixner } while (0) 176dc186ad7SThomas Gleixner 177dc186ad7SThomas Gleixner #define INIT_WORK_ON_STACK(_work, _func) \ 178dc186ad7SThomas Gleixner do { \ 179dc186ad7SThomas Gleixner __INIT_WORK((_work), (_func), 1); \ 180dc186ad7SThomas Gleixner } while (0) 181dc186ad7SThomas Gleixner 18265f27f38SDavid Howells #define INIT_DELAYED_WORK(_work, _func) \ 18365f27f38SDavid Howells do { \ 18465f27f38SDavid Howells INIT_WORK(&(_work)->work, (_func)); \ 18565f27f38SDavid Howells init_timer(&(_work)->timer); \ 18665f27f38SDavid Howells } while (0) 18765f27f38SDavid Howells 1886d612b0fSPeter Zijlstra #define INIT_DELAYED_WORK_ON_STACK(_work, _func) \ 1896d612b0fSPeter Zijlstra do { \ 190dc186ad7SThomas Gleixner INIT_WORK_ON_STACK(&(_work)->work, (_func)); \ 1916d612b0fSPeter Zijlstra init_timer_on_stack(&(_work)->timer); \ 1926d612b0fSPeter Zijlstra } while (0) 1936d612b0fSPeter Zijlstra 19428287033SVenki Pallipadi #define INIT_DELAYED_WORK_DEFERRABLE(_work, _func) \ 19528287033SVenki Pallipadi do { \ 19628287033SVenki Pallipadi INIT_WORK(&(_work)->work, (_func)); \ 19728287033SVenki Pallipadi init_timer_deferrable(&(_work)->timer); \ 19828287033SVenki Pallipadi } while (0) 19928287033SVenki Pallipadi 200365970a1SDavid Howells /** 201365970a1SDavid Howells * work_pending - Find out whether a work item is currently pending 202365970a1SDavid Howells * @work: The work item in question 203365970a1SDavid Howells */ 204365970a1SDavid Howells #define work_pending(work) \ 20522df02bbSTejun Heo test_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work)) 206365970a1SDavid Howells 207365970a1SDavid Howells /** 208365970a1SDavid Howells * delayed_work_pending - Find out whether a delayable work item is currently 209365970a1SDavid Howells * pending 210365970a1SDavid Howells * @work: The work item in question 211365970a1SDavid Howells */ 2120221872aSLinus Torvalds #define delayed_work_pending(w) \ 2130221872aSLinus Torvalds work_pending(&(w)->work) 214365970a1SDavid Howells 21565f27f38SDavid Howells /** 21623b2e599SOleg Nesterov * work_clear_pending - for internal use only, mark a work item as not pending 21723b2e599SOleg Nesterov * @work: The work item in question 21865f27f38SDavid Howells */ 21923b2e599SOleg Nesterov #define work_clear_pending(work) \ 22022df02bbSTejun Heo clear_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work)) 22165f27f38SDavid Howells 22297e37d7bSTejun Heo enum { 22397e37d7bSTejun Heo WQ_FREEZEABLE = 1 << 0, /* freeze during suspend */ 22497e37d7bSTejun Heo WQ_SINGLE_THREAD = 1 << 1, /* no per-cpu worker */ 22597e37d7bSTejun Heo }; 22652bad64dSDavid Howells 2274e6045f1SJohannes Berg extern struct workqueue_struct * 2281e19ffc6STejun Heo __create_workqueue_key(const char *name, unsigned int flags, int max_active, 229c790bce0STejun Heo struct lock_class_key *key, const char *lock_name); 2304e6045f1SJohannes Berg 2314e6045f1SJohannes Berg #ifdef CONFIG_LOCKDEP 2321e19ffc6STejun Heo #define __create_workqueue(name, flags, max_active) \ 2334e6045f1SJohannes Berg ({ \ 2344e6045f1SJohannes Berg static struct lock_class_key __key; \ 235eb13ba87SJohannes Berg const char *__lock_name; \ 236eb13ba87SJohannes Berg \ 237eb13ba87SJohannes Berg if (__builtin_constant_p(name)) \ 238eb13ba87SJohannes Berg __lock_name = (name); \ 239eb13ba87SJohannes Berg else \ 240eb13ba87SJohannes Berg __lock_name = #name; \ 2414e6045f1SJohannes Berg \ 2421e19ffc6STejun Heo __create_workqueue_key((name), (flags), (max_active), \ 2431e19ffc6STejun Heo &__key, __lock_name); \ 2444e6045f1SJohannes Berg }) 2454e6045f1SJohannes Berg #else 2461e19ffc6STejun Heo #define __create_workqueue(name, flags, max_active) \ 2471e19ffc6STejun Heo __create_workqueue_key((name), (flags), (max_active), NULL, NULL) 2484e6045f1SJohannes Berg #endif 2494e6045f1SJohannes Berg 25097e37d7bSTejun Heo #define create_workqueue(name) \ 2511e19ffc6STejun Heo __create_workqueue((name), 0, 1) 25297e37d7bSTejun Heo #define create_freezeable_workqueue(name) \ 2531e19ffc6STejun Heo __create_workqueue((name), WQ_FREEZEABLE | WQ_SINGLE_THREAD, 1) 25497e37d7bSTejun Heo #define create_singlethread_workqueue(name) \ 2551e19ffc6STejun Heo __create_workqueue((name), WQ_SINGLE_THREAD, 1) 2561da177e4SLinus Torvalds 2571da177e4SLinus Torvalds extern void destroy_workqueue(struct workqueue_struct *wq); 2581da177e4SLinus Torvalds 259b3c97528SHarvey Harrison extern int queue_work(struct workqueue_struct *wq, struct work_struct *work); 260c1a220e7SZhang Rui extern int queue_work_on(int cpu, struct workqueue_struct *wq, 261c1a220e7SZhang Rui struct work_struct *work); 262b3c97528SHarvey Harrison extern int queue_delayed_work(struct workqueue_struct *wq, 263b3c97528SHarvey Harrison struct delayed_work *work, unsigned long delay); 2647a6bc1cdSVenkatesh Pallipadi extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, 26552bad64dSDavid Howells struct delayed_work *work, unsigned long delay); 26628e53bddSOleg Nesterov 267b3c97528SHarvey Harrison extern void flush_workqueue(struct workqueue_struct *wq); 26828e53bddSOleg Nesterov extern void flush_scheduled_work(void); 26943046b60SLinus Torvalds extern void flush_delayed_work(struct delayed_work *work); 2701da177e4SLinus Torvalds 271b3c97528SHarvey Harrison extern int schedule_work(struct work_struct *work); 272c1a220e7SZhang Rui extern int schedule_work_on(int cpu, struct work_struct *work); 273b3c97528SHarvey Harrison extern int schedule_delayed_work(struct delayed_work *work, unsigned long delay); 27428e53bddSOleg Nesterov extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, 27528e53bddSOleg Nesterov unsigned long delay); 27665f27f38SDavid Howells extern int schedule_on_each_cpu(work_func_t func); 2771da177e4SLinus Torvalds extern int current_is_keventd(void); 2781da177e4SLinus Torvalds extern int keventd_up(void); 2791da177e4SLinus Torvalds 2801da177e4SLinus Torvalds extern void init_workqueues(void); 28165f27f38SDavid Howells int execute_in_process_context(work_func_t fn, struct execute_work *); 2821da177e4SLinus Torvalds 283db700897SOleg Nesterov extern int flush_work(struct work_struct *work); 284db700897SOleg Nesterov 2851f1f642eSOleg Nesterov extern int cancel_work_sync(struct work_struct *work); 28628e53bddSOleg Nesterov 2871da177e4SLinus Torvalds /* 2881da177e4SLinus Torvalds * Kill off a pending schedule_delayed_work(). Note that the work callback 289071b6386SOleg Nesterov * function may still be running on return from cancel_delayed_work(), unless 290071b6386SOleg Nesterov * it returns 1 and the work doesn't re-arm itself. Run flush_workqueue() or 29128e53bddSOleg Nesterov * cancel_work_sync() to wait on it. 2921da177e4SLinus Torvalds */ 29352bad64dSDavid Howells static inline int cancel_delayed_work(struct delayed_work *work) 2941da177e4SLinus Torvalds { 2951da177e4SLinus Torvalds int ret; 2961da177e4SLinus Torvalds 297223a10a9SOleg Nesterov ret = del_timer_sync(&work->timer); 2981da177e4SLinus Torvalds if (ret) 29923b2e599SOleg Nesterov work_clear_pending(&work->work); 3001da177e4SLinus Torvalds return ret; 3011da177e4SLinus Torvalds } 3021da177e4SLinus Torvalds 3034e49627bSOleg Nesterov /* 3044e49627bSOleg Nesterov * Like above, but uses del_timer() instead of del_timer_sync(). This means, 3054e49627bSOleg Nesterov * if it returns 0 the timer function may be running and the queueing is in 3064e49627bSOleg Nesterov * progress. 3074e49627bSOleg Nesterov */ 3084e49627bSOleg Nesterov static inline int __cancel_delayed_work(struct delayed_work *work) 3094e49627bSOleg Nesterov { 3104e49627bSOleg Nesterov int ret; 3114e49627bSOleg Nesterov 3124e49627bSOleg Nesterov ret = del_timer(&work->timer); 3134e49627bSOleg Nesterov if (ret) 3144e49627bSOleg Nesterov work_clear_pending(&work->work); 3154e49627bSOleg Nesterov return ret; 3164e49627bSOleg Nesterov } 3174e49627bSOleg Nesterov 3181f1f642eSOleg Nesterov extern int cancel_delayed_work_sync(struct delayed_work *work); 3191634c48fSOleg Nesterov 320f5a421a4SOleg Nesterov /* Obsolete. use cancel_delayed_work_sync() */ 3211634c48fSOleg Nesterov static inline 3221634c48fSOleg Nesterov void cancel_rearming_delayed_workqueue(struct workqueue_struct *wq, 3231634c48fSOleg Nesterov struct delayed_work *work) 3241634c48fSOleg Nesterov { 325f5a421a4SOleg Nesterov cancel_delayed_work_sync(work); 326f5a421a4SOleg Nesterov } 327f5a421a4SOleg Nesterov 328f5a421a4SOleg Nesterov /* Obsolete. use cancel_delayed_work_sync() */ 329f5a421a4SOleg Nesterov static inline 330f5a421a4SOleg Nesterov void cancel_rearming_delayed_work(struct delayed_work *work) 331f5a421a4SOleg Nesterov { 332f5a421a4SOleg Nesterov cancel_delayed_work_sync(work); 3331634c48fSOleg Nesterov } 3341634c48fSOleg Nesterov 3352d3854a3SRusty Russell #ifndef CONFIG_SMP 3362d3854a3SRusty Russell static inline long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) 3372d3854a3SRusty Russell { 3382d3854a3SRusty Russell return fn(arg); 3392d3854a3SRusty Russell } 3402d3854a3SRusty Russell #else 3412d3854a3SRusty Russell long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg); 3422d3854a3SRusty Russell #endif /* CONFIG_SMP */ 343a0a1a5fdSTejun Heo 344a0a1a5fdSTejun Heo #ifdef CONFIG_FREEZER 345a0a1a5fdSTejun Heo extern void freeze_workqueues_begin(void); 346a0a1a5fdSTejun Heo extern bool freeze_workqueues_busy(void); 347a0a1a5fdSTejun Heo extern void thaw_workqueues(void); 348a0a1a5fdSTejun Heo #endif /* CONFIG_FREEZER */ 349a0a1a5fdSTejun Heo 3501da177e4SLinus Torvalds #endif 351