diff options
| author | Tejun Heo <tj@kernel.org> | 2012-08-03 10:30:45 -0700 | 
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2012-08-03 10:30:45 -0700 | 
| commit | d8e794dfd51c368ed3f686b7f4172830b60ae47b (patch) | |
| tree | 72e930ab0a14bf50fa1dc6802722483247b72806 /include/linux/workqueue.h | |
| parent | 8930caba3dbdd8b86dd6934a5920bf61b53a931e (diff) | |
| download | olio-linux-3.10-d8e794dfd51c368ed3f686b7f4172830b60ae47b.tar.xz olio-linux-3.10-d8e794dfd51c368ed3f686b7f4172830b60ae47b.zip  | |
workqueue: set delayed_work->timer function on initialization
delayed_work->timer.function is currently initialized during
queue_delayed_work_on().  Export delayed_work_timer_fn() and set
delayed_work timer function during delayed_work initialization
together with other fields.
This ensures the timer function is always valid on an initialized
delayed_work.  This is to help mod_delayed_work() implementation.
To detect delayed_work users which diddle with the internal timer,
trigger WARN if timer function doesn't match on queue.
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'include/linux/workqueue.h')
| -rw-r--r-- | include/linux/workqueue.h | 13 | 
1 files changed, 11 insertions, 2 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 278dc5ddb73..ab95fef38d5 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -16,6 +16,7 @@ struct workqueue_struct;  struct work_struct;  typedef void (*work_func_t)(struct work_struct *work); +void delayed_work_timer_fn(unsigned long __data);  /*   * The first word is the work queue pointer and the flags rolled into @@ -124,12 +125,14 @@ struct execute_work {  #define __DELAYED_WORK_INITIALIZER(n, f) {			\  	.work = __WORK_INITIALIZER((n).work, (f)),		\ -	.timer = TIMER_INITIALIZER(NULL, 0, 0),			\ +	.timer = TIMER_INITIALIZER(delayed_work_timer_fn,	\ +				0, (unsigned long)&(n)),	\  	}  #define __DEFERRED_WORK_INITIALIZER(n, f) {			\  	.work = __WORK_INITIALIZER((n).work, (f)),		\ -	.timer = TIMER_DEFERRED_INITIALIZER(NULL, 0, 0),	\ +	.timer = TIMER_DEFERRED_INITIALIZER(delayed_work_timer_fn, \ +				0, (unsigned long)&(n)),	\  	}  #define DECLARE_WORK(n, f)					\ @@ -207,18 +210,24 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }  	do {							\  		INIT_WORK(&(_work)->work, (_func));		\  		init_timer(&(_work)->timer);			\ +		(_work)->timer.function = delayed_work_timer_fn;\ +		(_work)->timer.data = (unsigned long)(_work);	\  	} while (0)  #define INIT_DELAYED_WORK_ONSTACK(_work, _func)			\  	do {							\  		INIT_WORK_ONSTACK(&(_work)->work, (_func));	\  		init_timer_on_stack(&(_work)->timer);		\ +		(_work)->timer.function = delayed_work_timer_fn;\ +		(_work)->timer.data = (unsigned long)(_work);	\  	} while (0)  #define INIT_DELAYED_WORK_DEFERRABLE(_work, _func)		\  	do {							\  		INIT_WORK(&(_work)->work, (_func));		\  		init_timer_deferrable(&(_work)->timer);		\ +		(_work)->timer.function = delayed_work_timer_fn;\ +		(_work)->timer.data = (unsigned long)(_work);	\  	} while (0)  /**  |