Skip to content

Commit

Permalink
workqueue: kill NOAUTOREL works
Browse files Browse the repository at this point in the history
We don't have any users, and it is not so trivial to use NOAUTOREL works
correctly.  It is better to simplify API.

Delete NOAUTOREL support and rename work_release to work_clear_pending to
avoid a confusion.

Signed-off-by: Oleg Nesterov <oleg@tv-sign.ru>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Oleg Nesterov authored and Linus Torvalds committed May 9, 2007
1 parent c214b2c commit 23b2e59
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 58 deletions.
64 changes: 9 additions & 55 deletions include/linux/workqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,13 @@ typedef void (*work_func_t)(struct work_struct *work);
struct work_struct {
atomic_long_t data;
#define WORK_STRUCT_PENDING 0 /* T if work item pending execution */
#define WORK_STRUCT_NOAUTOREL 1 /* F if work item automatically released on exec */
#define WORK_STRUCT_FLAG_MASK (3UL)
#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
struct list_head entry;
work_func_t func;
};

#define WORK_DATA_INIT(autorelease) \
ATOMIC_LONG_INIT((autorelease) << WORK_STRUCT_NOAUTOREL)
#define WORK_DATA_INIT() ATOMIC_LONG_INIT(0)

struct delayed_work {
struct work_struct work;
Expand All @@ -44,14 +42,8 @@ struct execute_work {
};

#define __WORK_INITIALIZER(n, f) { \
.data = WORK_DATA_INIT(0), \
.entry = { &(n).entry, &(n).entry }, \
.func = (f), \
}

#define __WORK_INITIALIZER_NAR(n, f) { \
.data = WORK_DATA_INIT(1), \
.entry = { &(n).entry, &(n).entry }, \
.data = WORK_DATA_INIT(), \
.entry = { &(n).entry, &(n).entry }, \
.func = (f), \
}

Expand All @@ -60,23 +52,12 @@ struct execute_work {
.timer = TIMER_INITIALIZER(NULL, 0, 0), \
}

#define __DELAYED_WORK_INITIALIZER_NAR(n, f) { \
.work = __WORK_INITIALIZER_NAR((n).work, (f)), \
.timer = TIMER_INITIALIZER(NULL, 0, 0), \
}

#define DECLARE_WORK(n, f) \
struct work_struct n = __WORK_INITIALIZER(n, f)

#define DECLARE_WORK_NAR(n, f) \
struct work_struct n = __WORK_INITIALIZER_NAR(n, f)

#define DECLARE_DELAYED_WORK(n, f) \
struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f)

#define DECLARE_DELAYED_WORK_NAR(n, f) \
struct dwork_struct n = __DELAYED_WORK_INITIALIZER_NAR(n, f)

/*
* initialize a work item's function pointer
*/
Expand All @@ -95,16 +76,9 @@ struct execute_work {
* assignment of the work data initializer allows the compiler
* to generate better code.
*/
#define INIT_WORK(_work, _func) \
do { \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(0); \
INIT_LIST_HEAD(&(_work)->entry); \
PREPARE_WORK((_work), (_func)); \
} while (0)

#define INIT_WORK_NAR(_work, _func) \
#define INIT_WORK(_work, _func) \
do { \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(1); \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
INIT_LIST_HEAD(&(_work)->entry); \
PREPARE_WORK((_work), (_func)); \
} while (0)
Expand All @@ -115,12 +89,6 @@ struct execute_work {
init_timer(&(_work)->timer); \
} while (0)

#define INIT_DELAYED_WORK_NAR(_work, _func) \
do { \
INIT_WORK_NAR(&(_work)->work, (_func)); \
init_timer(&(_work)->timer); \
} while (0)

#define INIT_DELAYED_WORK_DEFERRABLE(_work, _func) \
do { \
INIT_WORK(&(_work)->work, (_func)); \
Expand All @@ -143,24 +111,10 @@ struct execute_work {
work_pending(&(w)->work)

/**
* work_release - Release a work item under execution
* @work: The work item to release
*
* This is used to release a work item that has been initialised with automatic
* release mode disabled (WORK_STRUCT_NOAUTOREL is set). This gives the work
* function the opportunity to grab auxiliary data from the container of the
* work_struct before clearing the pending bit as the work_struct may be
* subject to deallocation the moment the pending bit is cleared.
*
* In such a case, this should be called in the work function after it has
* fetched any data it may require from the containter of the work_struct.
* After this function has been called, the work_struct may be scheduled for
* further execution or it may be deallocated unless other precautions are
* taken.
*
* This should also be used to release a delayed work item.
* work_clear_pending - for internal use only, mark a work item as not pending
* @work: The work item in question
*/
#define work_release(work) \
#define work_clear_pending(work) \
clear_bit(WORK_STRUCT_PENDING, work_data_bits(work))


Expand Down Expand Up @@ -205,7 +159,7 @@ static inline int cancel_delayed_work(struct delayed_work *work)

ret = del_timer(&work->timer);
if (ret)
work_release(&work->work);
work_clear_pending(&work->work);
return ret;
}

Expand Down
5 changes: 2 additions & 3 deletions kernel/workqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,7 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq)
spin_unlock_irq(&cwq->lock);

BUG_ON(get_wq_data(work) != cwq);
if (!test_bit(WORK_STRUCT_NOAUTOREL, work_data_bits(work)))
work_release(work);
work_clear_pending(work);
f(work);

if (unlikely(in_atomic() || lockdep_depth(current) > 0)) {
Expand Down Expand Up @@ -453,7 +452,7 @@ void flush_work(struct workqueue_struct *wq, struct work_struct *work)
*/
spin_lock_irq(&cwq->lock);
list_del_init(&work->entry);
work_release(work);
work_clear_pending(work);
spin_unlock_irq(&cwq->lock);

for_each_cpu_mask(cpu, *cpu_map)
Expand Down

0 comments on commit 23b2e59

Please sign in to comment.