xref: /openbmc/linux/include/linux/workqueue.h (revision 65f27f38)
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>
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds struct workqueue_struct;
131da177e4SLinus Torvalds 
1465f27f38SDavid Howells struct work_struct;
1565f27f38SDavid Howells typedef void (*work_func_t)(struct work_struct *work);
166bb49e59SDavid Howells 
171da177e4SLinus Torvalds struct work_struct {
1865f27f38SDavid Howells 	/* the first word is the work queue pointer and the flags rolled into
1965f27f38SDavid Howells 	 * one */
20365970a1SDavid Howells 	unsigned long management;
21365970a1SDavid Howells #define WORK_STRUCT_PENDING 0		/* T if work item pending execution */
2265f27f38SDavid Howells #define WORK_STRUCT_NOAUTOREL 1		/* F if work item automatically released on exec */
23365970a1SDavid Howells #define WORK_STRUCT_FLAG_MASK (3UL)
24365970a1SDavid Howells #define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
251da177e4SLinus Torvalds 	struct list_head entry;
266bb49e59SDavid Howells 	work_func_t func;
2752bad64dSDavid Howells };
2852bad64dSDavid Howells 
2952bad64dSDavid Howells struct delayed_work {
3052bad64dSDavid Howells 	struct work_struct work;
311da177e4SLinus Torvalds 	struct timer_list timer;
321da177e4SLinus Torvalds };
331da177e4SLinus Torvalds 
341fa44ecaSJames Bottomley struct execute_work {
351fa44ecaSJames Bottomley 	struct work_struct work;
361fa44ecaSJames Bottomley };
371fa44ecaSJames Bottomley 
3865f27f38SDavid Howells #define __WORK_INITIALIZER(n, f) {				\
3965f27f38SDavid Howells 	.management = 0,					\
401da177e4SLinus Torvalds         .entry	= { &(n).entry, &(n).entry },			\
411da177e4SLinus Torvalds 	.func = (f),						\
4252bad64dSDavid Howells 	}
4352bad64dSDavid Howells 
4465f27f38SDavid Howells #define __WORK_INITIALIZER_NAR(n, f) {				\
4565f27f38SDavid Howells 	.management = (1 << WORK_STRUCT_NOAUTOREL),		\
4665f27f38SDavid Howells         .entry	= { &(n).entry, &(n).entry },			\
4765f27f38SDavid Howells 	.func = (f),						\
4865f27f38SDavid Howells 	}
4965f27f38SDavid Howells 
5065f27f38SDavid Howells #define __DELAYED_WORK_INITIALIZER(n, f) {			\
5165f27f38SDavid Howells 	.work = __WORK_INITIALIZER((n).work, (f)),		\
521da177e4SLinus Torvalds 	.timer = TIMER_INITIALIZER(NULL, 0, 0),			\
531da177e4SLinus Torvalds 	}
541da177e4SLinus Torvalds 
5565f27f38SDavid Howells #define __DELAYED_WORK_INITIALIZER_NAR(n, f) {			\
5665f27f38SDavid Howells 	.work = __WORK_INITIALIZER_NAR((n).work, (f)),		\
5765f27f38SDavid Howells 	.timer = TIMER_INITIALIZER(NULL, 0, 0),			\
5865f27f38SDavid Howells 	}
591da177e4SLinus Torvalds 
6065f27f38SDavid Howells #define DECLARE_WORK(n, f)					\
6165f27f38SDavid Howells 	struct work_struct n = __WORK_INITIALIZER(n, f)
6265f27f38SDavid Howells 
6365f27f38SDavid Howells #define DECLARE_WORK_NAR(n, f)					\
6465f27f38SDavid Howells 	struct work_struct n = __WORK_INITIALIZER_NAR(n, f)
6565f27f38SDavid Howells 
6665f27f38SDavid Howells #define DECLARE_DELAYED_WORK(n, f)				\
6765f27f38SDavid Howells 	struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f)
6865f27f38SDavid Howells 
6965f27f38SDavid Howells #define DECLARE_DELAYED_WORK_NAR(n, f)			\
7065f27f38SDavid Howells 	struct dwork_struct n = __DELAYED_WORK_INITIALIZER_NAR(n, f)
7152bad64dSDavid Howells 
721da177e4SLinus Torvalds /*
7365f27f38SDavid Howells  * initialize a work item's function pointer
741da177e4SLinus Torvalds  */
7565f27f38SDavid Howells #define PREPARE_WORK(_work, _func)				\
761da177e4SLinus Torvalds 	do {							\
7752bad64dSDavid Howells 		(_work)->func = (_func);			\
781da177e4SLinus Torvalds 	} while (0)
791da177e4SLinus Torvalds 
8065f27f38SDavid Howells #define PREPARE_DELAYED_WORK(_work, _func)			\
8165f27f38SDavid Howells 	PREPARE_WORK(&(_work)->work, (_func))
8252bad64dSDavid Howells 
831da177e4SLinus Torvalds /*
8452bad64dSDavid Howells  * initialize all of a work item in one go
851da177e4SLinus Torvalds  */
8665f27f38SDavid Howells #define INIT_WORK(_work, _func)					\
871da177e4SLinus Torvalds 	do {							\
88365970a1SDavid Howells 		(_work)->management = 0;			\
8965f27f38SDavid Howells 		INIT_LIST_HEAD(&(_work)->entry);		\
9065f27f38SDavid Howells 		PREPARE_WORK((_work), (_func));			\
9152bad64dSDavid Howells 	} while (0)
9252bad64dSDavid Howells 
9365f27f38SDavid Howells #define INIT_WORK_NAR(_work, _func)					\
9452bad64dSDavid Howells 	do {								\
9565f27f38SDavid Howells 		(_work)->management = (1 << WORK_STRUCT_NOAUTOREL);	\
9665f27f38SDavid Howells 		INIT_LIST_HEAD(&(_work)->entry);			\
9765f27f38SDavid Howells 		PREPARE_WORK((_work), (_func));				\
9865f27f38SDavid Howells 	} while (0)
9965f27f38SDavid Howells 
10065f27f38SDavid Howells #define INIT_DELAYED_WORK(_work, _func)				\
10165f27f38SDavid Howells 	do {							\
10265f27f38SDavid Howells 		INIT_WORK(&(_work)->work, (_func));		\
10365f27f38SDavid Howells 		init_timer(&(_work)->timer);			\
10465f27f38SDavid Howells 	} while (0)
10565f27f38SDavid Howells 
10665f27f38SDavid Howells #define INIT_DELAYED_WORK_NAR(_work, _func)			\
10765f27f38SDavid Howells 	do {							\
10865f27f38SDavid Howells 		INIT_WORK_NAR(&(_work)->work, (_func));		\
1091da177e4SLinus Torvalds 		init_timer(&(_work)->timer);			\
1101da177e4SLinus Torvalds 	} while (0)
1111da177e4SLinus Torvalds 
112365970a1SDavid Howells /**
113365970a1SDavid Howells  * work_pending - Find out whether a work item is currently pending
114365970a1SDavid Howells  * @work: The work item in question
115365970a1SDavid Howells  */
116365970a1SDavid Howells #define work_pending(work) \
117365970a1SDavid Howells 	test_bit(WORK_STRUCT_PENDING, &(work)->management)
118365970a1SDavid Howells 
119365970a1SDavid Howells /**
120365970a1SDavid Howells  * delayed_work_pending - Find out whether a delayable work item is currently
121365970a1SDavid Howells  * pending
122365970a1SDavid Howells  * @work: The work item in question
123365970a1SDavid Howells  */
124365970a1SDavid Howells #define delayed_work_pending(work) \
125365970a1SDavid Howells 	test_bit(WORK_STRUCT_PENDING, &(work)->work.management)
126365970a1SDavid Howells 
12765f27f38SDavid Howells /**
12865f27f38SDavid Howells  * work_release - Release a work item under execution
12965f27f38SDavid Howells  * @work: The work item to release
13065f27f38SDavid Howells  *
13165f27f38SDavid Howells  * This is used to release a work item that has been initialised with automatic
13265f27f38SDavid Howells  * release mode disabled (WORK_STRUCT_NOAUTOREL is set).  This gives the work
13365f27f38SDavid Howells  * function the opportunity to grab auxiliary data from the container of the
13465f27f38SDavid Howells  * work_struct before clearing the pending bit as the work_struct may be
13565f27f38SDavid Howells  * subject to deallocation the moment the pending bit is cleared.
13665f27f38SDavid Howells  *
13765f27f38SDavid Howells  * In such a case, this should be called in the work function after it has
13865f27f38SDavid Howells  * fetched any data it may require from the containter of the work_struct.
13965f27f38SDavid Howells  * After this function has been called, the work_struct may be scheduled for
14065f27f38SDavid Howells  * further execution or it may be deallocated unless other precautions are
14165f27f38SDavid Howells  * taken.
14265f27f38SDavid Howells  *
14365f27f38SDavid Howells  * This should also be used to release a delayed work item.
14465f27f38SDavid Howells  */
14565f27f38SDavid Howells #define work_release(work) \
14665f27f38SDavid Howells 	clear_bit(WORK_STRUCT_PENDING, &(work)->management)
14765f27f38SDavid Howells 
14852bad64dSDavid Howells 
1491da177e4SLinus Torvalds extern struct workqueue_struct *__create_workqueue(const char *name,
1501da177e4SLinus Torvalds 						    int singlethread);
1511da177e4SLinus Torvalds #define create_workqueue(name) __create_workqueue((name), 0)
1521da177e4SLinus Torvalds #define create_singlethread_workqueue(name) __create_workqueue((name), 1)
1531da177e4SLinus Torvalds 
1541da177e4SLinus Torvalds extern void destroy_workqueue(struct workqueue_struct *wq);
1551da177e4SLinus Torvalds 
1561da177e4SLinus Torvalds extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work));
15752bad64dSDavid Howells extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay));
1587a6bc1cdSVenkatesh Pallipadi extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
15952bad64dSDavid Howells 	struct delayed_work *work, unsigned long delay);
1601da177e4SLinus Torvalds extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq));
1611da177e4SLinus Torvalds 
1621da177e4SLinus Torvalds extern int FASTCALL(schedule_work(struct work_struct *work));
16352bad64dSDavid Howells extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay));
1641da177e4SLinus Torvalds 
16552bad64dSDavid Howells extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay);
16665f27f38SDavid Howells extern int schedule_on_each_cpu(work_func_t func);
1671da177e4SLinus Torvalds extern void flush_scheduled_work(void);
1681da177e4SLinus Torvalds extern int current_is_keventd(void);
1691da177e4SLinus Torvalds extern int keventd_up(void);
1701da177e4SLinus Torvalds 
1711da177e4SLinus Torvalds extern void init_workqueues(void);
17252bad64dSDavid Howells void cancel_rearming_delayed_work(struct delayed_work *work);
17381ddef77SJames Bottomley void cancel_rearming_delayed_workqueue(struct workqueue_struct *,
17452bad64dSDavid Howells 				       struct delayed_work *);
17565f27f38SDavid Howells int execute_in_process_context(work_func_t fn, struct execute_work *);
1761da177e4SLinus Torvalds 
1771da177e4SLinus Torvalds /*
1781da177e4SLinus Torvalds  * Kill off a pending schedule_delayed_work().  Note that the work callback
1791da177e4SLinus Torvalds  * function may still be running on return from cancel_delayed_work().  Run
1801da177e4SLinus Torvalds  * flush_scheduled_work() to wait on it.
1811da177e4SLinus Torvalds  */
18252bad64dSDavid Howells static inline int cancel_delayed_work(struct delayed_work *work)
1831da177e4SLinus Torvalds {
1841da177e4SLinus Torvalds 	int ret;
1851da177e4SLinus Torvalds 
1861da177e4SLinus Torvalds 	ret = del_timer_sync(&work->timer);
1871da177e4SLinus Torvalds 	if (ret)
188365970a1SDavid Howells 		clear_bit(WORK_STRUCT_PENDING, &work->work.management);
1891da177e4SLinus Torvalds 	return ret;
1901da177e4SLinus Torvalds }
1911da177e4SLinus Torvalds 
1921da177e4SLinus Torvalds #endif
193