From 52bad64d95bd89e08c49ec5a071fa6dcbe5a1a9c Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 22 Nov 2006 14:54:01 +0000 Subject: WorkStruct: Separate delayable and non-delayable events. Separate delayable work items from non-delayable work items be splitting them into a separate structure (delayed_work), which incorporates a work_struct and the timer_list removed from work_struct. The work_struct struct is huge, and this limits it's usefulness. On a 64-bit architecture it's nearly 100 bytes in size. This reduces that by half for the non-delayable type of event. Signed-Off-By: David Howells --- include/linux/aio.h | 2 +- include/linux/kbd_kern.h | 2 +- include/linux/libata.h | 4 ++-- include/linux/nfs_fs_sb.h | 2 +- include/linux/sunrpc/rpc_pipe_fs.h | 2 +- include/linux/sunrpc/xprt.h | 2 +- include/linux/tty.h | 2 +- include/linux/workqueue.h | 44 +++++++++++++++++++++++++++----------- 8 files changed, 40 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/include/linux/aio.h b/include/linux/aio.h index 0d71c0041f1..9e350fd44d7 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h @@ -194,7 +194,7 @@ struct kioctx { struct aio_ring_info ring_info; - struct work_struct wq; + struct delayed_work wq; }; /* prototypes */ diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index efe0ee4cc80..06c58c423fe 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h @@ -158,7 +158,7 @@ static inline void con_schedule_flip(struct tty_struct *t) if (t->buf.tail != NULL) t->buf.tail->commit = t->buf.tail->used; spin_unlock_irqrestore(&t->buf.lock, flags); - schedule_work(&t->buf.work); + schedule_delayed_work(&t->buf.work, 0); } #endif diff --git a/include/linux/libata.h b/include/linux/libata.h index abd2debebca..5f04006e8dd 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -568,8 +568,8 @@ struct ata_port { struct ata_host *host; struct device *dev; - struct work_struct port_task; - struct work_struct hotplug_task; + struct delayed_work port_task; + struct delayed_work hotplug_task; struct work_struct scsi_rescan_task; unsigned int hsm_task_state; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 7ccfc7ef0a8..95796e6924f 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -51,7 +51,7 @@ struct nfs_client { unsigned long cl_lease_time; unsigned long cl_last_renewal; - struct work_struct cl_renewd; + struct delayed_work cl_renewd; struct rpc_wait_queue cl_rpcwaitq; diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h index a2eb9b4a9de..4a68125b6de 100644 --- a/include/linux/sunrpc/rpc_pipe_fs.h +++ b/include/linux/sunrpc/rpc_pipe_fs.h @@ -30,7 +30,7 @@ struct rpc_inode { #define RPC_PIPE_WAIT_FOR_OPEN 1 int flags; struct rpc_pipe_ops *ops; - struct work_struct queue_timeout; + struct delayed_work queue_timeout; }; static inline struct rpc_inode * diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 60394fbc4c7..3e04c1512fc 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -177,7 +177,7 @@ struct rpc_xprt { unsigned long connect_timeout, bind_timeout, reestablish_timeout; - struct work_struct connect_worker; + struct delayed_work connect_worker; unsigned short port; /* diff --git a/include/linux/tty.h b/include/linux/tty.h index 44091c0db0b..c1f71644616 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -53,7 +53,7 @@ struct tty_buffer { }; struct tty_bufhead { - struct work_struct work; + struct delayed_work work; struct semaphore pty_sem; spinlock_t lock; struct tty_buffer *head; /* Queue head */ diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 9bca3539a1e..9faaccae570 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -17,6 +17,10 @@ struct work_struct { void (*func)(void *); void *data; void *wq_data; +}; + +struct delayed_work { + struct work_struct work; struct timer_list timer; }; @@ -28,32 +32,48 @@ struct execute_work { .entry = { &(n).entry, &(n).entry }, \ .func = (f), \ .data = (d), \ + } + +#define __DELAYED_WORK_INITIALIZER(n, f, d) { \ + .work = __WORK_INITIALIZER((n).work, (f), (d)), \ .timer = TIMER_INITIALIZER(NULL, 0, 0), \ } #define DECLARE_WORK(n, f, d) \ struct work_struct n = __WORK_INITIALIZER(n, f, d) +#define DECLARE_DELAYED_WORK(n, f, d) \ + struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, d) + /* - * initialize a work-struct's func and data pointers: + * initialize a work item's function and data pointers */ #define PREPARE_WORK(_work, _func, _data) \ do { \ - (_work)->func = _func; \ - (_work)->data = _data; \ + (_work)->func = (_func); \ + (_work)->data = (_data); \ } while (0) +#define PREPARE_DELAYED_WORK(_work, _func, _data) \ + PREPARE_WORK(&(_work)->work, (_func), (_data)) + /* - * initialize all of a work-struct: + * initialize all of a work item in one go */ #define INIT_WORK(_work, _func, _data) \ do { \ INIT_LIST_HEAD(&(_work)->entry); \ (_work)->pending = 0; \ PREPARE_WORK((_work), (_func), (_data)); \ + } while (0) + +#define INIT_DELAYED_WORK(_work, _func, _data) \ + do { \ + INIT_WORK(&(_work)->work, (_func), (_data)); \ init_timer(&(_work)->timer); \ } while (0) + extern struct workqueue_struct *__create_workqueue(const char *name, int singlethread); #define create_workqueue(name) __create_workqueue((name), 0) @@ -62,24 +82,24 @@ extern struct workqueue_struct *__create_workqueue(const char *name, extern void destroy_workqueue(struct workqueue_struct *wq); extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work)); -extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct work_struct *work, unsigned long delay)); +extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay)); extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, - struct work_struct *work, unsigned long delay); + struct delayed_work *work, unsigned long delay); extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq)); extern int FASTCALL(schedule_work(struct work_struct *work)); -extern int FASTCALL(schedule_delayed_work(struct work_struct *work, unsigned long delay)); +extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay)); -extern int schedule_delayed_work_on(int cpu, struct work_struct *work, unsigned long delay); +extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay); extern int schedule_on_each_cpu(void (*func)(void *info), void *info); extern void flush_scheduled_work(void); extern int current_is_keventd(void); extern int keventd_up(void); extern void init_workqueues(void); -void cancel_rearming_delayed_work(struct work_struct *work); +void cancel_rearming_delayed_work(struct delayed_work *work); void cancel_rearming_delayed_workqueue(struct workqueue_struct *, - struct work_struct *); + struct delayed_work *); int execute_in_process_context(void (*fn)(void *), void *, struct execute_work *); @@ -88,13 +108,13 @@ int execute_in_process_context(void (*fn)(void *), void *, * function may still be running on return from cancel_delayed_work(). Run * flush_scheduled_work() to wait on it. */ -static inline int cancel_delayed_work(struct work_struct *work) +static inline int cancel_delayed_work(struct delayed_work *work) { int ret; ret = del_timer_sync(&work->timer); if (ret) - clear_bit(0, &work->pending); + clear_bit(0, &work->work.pending); return ret; } -- cgit v1.2.3 From 6bb49e5965c1fc399b4d3cd2b5cf2da535b330c0 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 22 Nov 2006 14:54:45 +0000 Subject: WorkStruct: Typedef the work function prototype Define a type for the work function prototype. It's not only kept in the work_struct struct, it's also passed as an argument to several functions. This makes it easier to change it. Signed-Off-By: David Howells --- include/linux/workqueue.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 9faaccae570..cef40b22ff9 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -11,10 +11,12 @@ struct workqueue_struct; +typedef void (*work_func_t)(void *data); + struct work_struct { unsigned long pending; struct list_head entry; - void (*func)(void *); + work_func_t func; void *data; void *wq_data; }; @@ -91,7 +93,7 @@ extern int FASTCALL(schedule_work(struct work_struct *work)); extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay)); extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay); -extern int schedule_on_each_cpu(void (*func)(void *info), void *info); +extern int schedule_on_each_cpu(work_func_t func, void *info); extern void flush_scheduled_work(void); extern int current_is_keventd(void); extern int keventd_up(void); @@ -100,8 +102,7 @@ extern void init_workqueues(void); void cancel_rearming_delayed_work(struct delayed_work *work); void cancel_rearming_delayed_workqueue(struct workqueue_struct *, struct delayed_work *); -int execute_in_process_context(void (*fn)(void *), void *, - struct execute_work *); +int execute_in_process_context(work_func_t fn, void *, struct execute_work *); /* * Kill off a pending schedule_delayed_work(). Note that the work callback -- cgit v1.2.3 From 365970a1ea76d81cb1ad2f652acb605f06dae256 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 22 Nov 2006 14:54:49 +0000 Subject: WorkStruct: Merge the pending bit into the wq_data pointer Reclaim a word from the size of the work_struct by folding the pending bit and the wq_data pointer together. This shouldn't cause misalignment problems as all pointers should be at least 4-byte aligned. Signed-Off-By: David Howells --- include/linux/workqueue.h | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index cef40b22ff9..ecc017d24cf 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -14,11 +14,15 @@ struct workqueue_struct; typedef void (*work_func_t)(void *data); struct work_struct { - unsigned long pending; + /* the first word is the work queue pointer and the pending flag + * rolled into one */ + unsigned long management; +#define WORK_STRUCT_PENDING 0 /* T if work item pending execution */ +#define WORK_STRUCT_FLAG_MASK (3UL) +#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK) struct list_head entry; work_func_t func; void *data; - void *wq_data; }; struct delayed_work { @@ -65,7 +69,7 @@ struct execute_work { #define INIT_WORK(_work, _func, _data) \ do { \ INIT_LIST_HEAD(&(_work)->entry); \ - (_work)->pending = 0; \ + (_work)->management = 0; \ PREPARE_WORK((_work), (_func), (_data)); \ } while (0) @@ -75,6 +79,21 @@ struct execute_work { init_timer(&(_work)->timer); \ } while (0) +/** + * work_pending - Find out whether a work item is currently pending + * @work: The work item in question + */ +#define work_pending(work) \ + test_bit(WORK_STRUCT_PENDING, &(work)->management) + +/** + * delayed_work_pending - Find out whether a delayable work item is currently + * pending + * @work: The work item in question + */ +#define delayed_work_pending(work) \ + test_bit(WORK_STRUCT_PENDING, &(work)->work.management) + extern struct workqueue_struct *__create_workqueue(const char *name, int singlethread); @@ -115,7 +134,7 @@ static inline int cancel_delayed_work(struct delayed_work *work) ret = del_timer_sync(&work->timer); if (ret) - clear_bit(0, &work->work.pending); + clear_bit(WORK_STRUCT_PENDING, &work->work.management); return ret; } -- cgit v1.2.3 From 65f27f38446e1976cc98fd3004b110fedcddd189 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 22 Nov 2006 14:55:48 +0000 Subject: WorkStruct: Pass the work_struct pointer instead of context data Pass the work_struct pointer to the work function rather than context data. The work function can use container_of() to work out the data. For the cases where the container of the work_struct may go away the moment the pending bit is cleared, it is made possible to defer the release of the structure by deferring the clearing of the pending bit. To make this work, an extra flag is introduced into the management side of the work_struct. This governs auto-release of the structure upon execution. Ordinarily, the work queue executor would release the work_struct for further scheduling or deallocation by clearing the pending bit prior to jumping to the work function. This means that, unless the driver makes some guarantee itself that the work_struct won't go away, the work function may not access anything else in the work_struct or its container lest they be deallocated.. This is a problem if the auxiliary data is taken away (as done by the last patch). However, if the pending bit is *not* cleared before jumping to the work function, then the work function *may* access the work_struct and its container with no problems. But then the work function must itself release the work_struct by calling work_release(). In most cases, automatic release is fine, so this is the default. Special initiators exist for the non-auto-release case (ending in _NAR). Signed-Off-By: David Howells --- include/linux/libata.h | 3 +- include/linux/workqueue.h | 99 ++++++++++++++++++++++++++++++---------- include/net/inet_timewait_sock.h | 2 +- 3 files changed, 78 insertions(+), 26 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 5f04006e8dd..b3f32eadbef 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -568,6 +568,7 @@ struct ata_port { struct ata_host *host; struct device *dev; + void *port_task_data; struct delayed_work port_task; struct delayed_work hotplug_task; struct work_struct scsi_rescan_task; @@ -747,7 +748,7 @@ extern int ata_ratelimit(void); extern unsigned int ata_busy_sleep(struct ata_port *ap, unsigned long timeout_pat, unsigned long timeout); -extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), +extern void ata_port_queue_task(struct ata_port *ap, work_func_t fn, void *data, unsigned long delay); extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, unsigned long interval_msec, diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index ecc017d24cf..4a3ea83c6d1 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -11,18 +11,19 @@ struct workqueue_struct; -typedef void (*work_func_t)(void *data); +struct work_struct; +typedef void (*work_func_t)(struct work_struct *work); struct work_struct { - /* the first word is the work queue pointer and the pending flag - * rolled into one */ + /* the first word is the work queue pointer and the flags rolled into + * one */ unsigned long management; #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; - void *data; }; struct delayed_work { @@ -34,48 +35,77 @@ struct execute_work { struct work_struct work; }; -#define __WORK_INITIALIZER(n, f, d) { \ +#define __WORK_INITIALIZER(n, f) { \ + .management = 0, \ .entry = { &(n).entry, &(n).entry }, \ .func = (f), \ - .data = (d), \ } -#define __DELAYED_WORK_INITIALIZER(n, f, d) { \ - .work = __WORK_INITIALIZER((n).work, (f), (d)), \ +#define __WORK_INITIALIZER_NAR(n, f) { \ + .management = (1 << WORK_STRUCT_NOAUTOREL), \ + .entry = { &(n).entry, &(n).entry }, \ + .func = (f), \ + } + +#define __DELAYED_WORK_INITIALIZER(n, f) { \ + .work = __WORK_INITIALIZER((n).work, (f)), \ + .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, d) \ - struct work_struct n = __WORK_INITIALIZER(n, f, d) +#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, d) \ - struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, d) +#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 and data pointers + * initialize a work item's function pointer */ -#define PREPARE_WORK(_work, _func, _data) \ +#define PREPARE_WORK(_work, _func) \ do { \ (_work)->func = (_func); \ - (_work)->data = (_data); \ } while (0) -#define PREPARE_DELAYED_WORK(_work, _func, _data) \ - PREPARE_WORK(&(_work)->work, (_func), (_data)) +#define PREPARE_DELAYED_WORK(_work, _func) \ + PREPARE_WORK(&(_work)->work, (_func)) /* * initialize all of a work item in one go */ -#define INIT_WORK(_work, _func, _data) \ +#define INIT_WORK(_work, _func) \ do { \ - INIT_LIST_HEAD(&(_work)->entry); \ (_work)->management = 0; \ - PREPARE_WORK((_work), (_func), (_data)); \ + INIT_LIST_HEAD(&(_work)->entry); \ + PREPARE_WORK((_work), (_func)); \ + } while (0) + +#define INIT_WORK_NAR(_work, _func) \ + do { \ + (_work)->management = (1 << WORK_STRUCT_NOAUTOREL); \ + INIT_LIST_HEAD(&(_work)->entry); \ + PREPARE_WORK((_work), (_func)); \ + } while (0) + +#define INIT_DELAYED_WORK(_work, _func) \ + do { \ + INIT_WORK(&(_work)->work, (_func)); \ + init_timer(&(_work)->timer); \ } while (0) -#define INIT_DELAYED_WORK(_work, _func, _data) \ +#define INIT_DELAYED_WORK_NAR(_work, _func) \ do { \ - INIT_WORK(&(_work)->work, (_func), (_data)); \ + INIT_WORK_NAR(&(_work)->work, (_func)); \ init_timer(&(_work)->timer); \ } while (0) @@ -94,6 +124,27 @@ struct execute_work { #define delayed_work_pending(work) \ test_bit(WORK_STRUCT_PENDING, &(work)->work.management) +/** + * 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. + */ +#define work_release(work) \ + clear_bit(WORK_STRUCT_PENDING, &(work)->management) + extern struct workqueue_struct *__create_workqueue(const char *name, int singlethread); @@ -112,7 +163,7 @@ extern int FASTCALL(schedule_work(struct work_struct *work)); extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay)); extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay); -extern int schedule_on_each_cpu(work_func_t func, void *info); +extern int schedule_on_each_cpu(work_func_t func); extern void flush_scheduled_work(void); extern int current_is_keventd(void); extern int keventd_up(void); @@ -121,7 +172,7 @@ extern void init_workqueues(void); void cancel_rearming_delayed_work(struct delayed_work *work); void cancel_rearming_delayed_workqueue(struct workqueue_struct *, struct delayed_work *); -int execute_in_process_context(work_func_t fn, void *, struct execute_work *); +int execute_in_process_context(work_func_t fn, struct execute_work *); /* * Kill off a pending schedule_delayed_work(). Note that the work callback diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index 5f48748fe01..f7be1ac7360 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -84,7 +84,7 @@ struct inet_timewait_death_row { }; extern void inet_twdr_hangman(unsigned long data); -extern void inet_twdr_twkill_work(void *data); +extern void inet_twdr_twkill_work(struct work_struct *work); extern void inet_twdr_twcal_tick(unsigned long data); #if (BITS_PER_LONG == 64) -- cgit v1.2.3 From c4028958b6ecad064b1a6303a6a5906d4fe48d73 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 22 Nov 2006 14:57:56 +0000 Subject: WorkStruct: make allyesconfig Fix up for make allyesconfig. Signed-Off-By: David Howells --- include/linux/connector.h | 4 ++-- include/linux/i2o.h | 2 +- include/linux/mmc/host.h | 2 +- include/linux/ncp_fs_sb.h | 8 ++++---- include/linux/reiserfs_fs_sb.h | 3 ++- include/linux/relay.h | 2 +- include/linux/usb.h | 2 +- include/net/ieee80211softmac.h | 4 ++-- include/net/sctp/structs.h | 2 +- include/scsi/libsas.h | 23 +++++++++++++++++++---- include/scsi/scsi_transport_fc.h | 4 ++-- include/scsi/scsi_transport_iscsi.h | 2 +- include/sound/ac97_codec.h | 2 +- include/sound/ak4114.h | 2 +- 14 files changed, 39 insertions(+), 23 deletions(-) (limited to 'include') diff --git a/include/linux/connector.h b/include/linux/connector.h index 4c02119c6ab..3ea1cd58de9 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -133,7 +133,7 @@ struct cn_callback_data { struct cn_callback_entry { struct list_head callback_entry; struct cn_callback *cb; - struct work_struct work; + struct delayed_work work; struct cn_queue_dev *pdev; struct cn_callback_id id; @@ -170,7 +170,7 @@ void cn_queue_free_dev(struct cn_queue_dev *dev); int cn_cb_equal(struct cb_id *, struct cb_id *); -void cn_queue_wrapper(void *data); +void cn_queue_wrapper(struct work_struct *work); extern int cn_already_initialized; diff --git a/include/linux/i2o.h b/include/linux/i2o.h index c115e9e840b..1fb02e17f6f 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -461,7 +461,7 @@ struct i2o_driver { int (*reply) (struct i2o_controller *, u32, struct i2o_message *); /* Event handler */ - void (*event) (struct i2o_event *); + work_func_t event; struct workqueue_struct *event_queue; /* Event queue */ diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 587264a58d5..8b08ef3820f 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -110,7 +110,7 @@ struct mmc_host { struct mmc_card *card_busy; /* the MMC card claiming host */ struct mmc_card *card_selected; /* the selected MMC card */ - struct work_struct detect; + struct delayed_work detect; unsigned long private[0] ____cacheline_aligned; }; diff --git a/include/linux/ncp_fs_sb.h b/include/linux/ncp_fs_sb.h index b089d950628..a503052138b 100644 --- a/include/linux/ncp_fs_sb.h +++ b/include/linux/ncp_fs_sb.h @@ -127,10 +127,10 @@ struct ncp_server { } unexpected_packet; }; -extern void ncp_tcp_rcv_proc(void *server); -extern void ncp_tcp_tx_proc(void *server); -extern void ncpdgram_rcv_proc(void *server); -extern void ncpdgram_timeout_proc(void *server); +extern void ncp_tcp_rcv_proc(struct work_struct *work); +extern void ncp_tcp_tx_proc(struct work_struct *work); +extern void ncpdgram_rcv_proc(struct work_struct *work); +extern void ncpdgram_timeout_proc(struct work_struct *work); extern void ncpdgram_timeout_call(unsigned long server); extern void ncp_tcp_data_ready(struct sock* sk, int len); extern void ncp_tcp_write_space(struct sock* sk); diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index 73e0becec08..6610103f23e 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h @@ -249,7 +249,8 @@ struct reiserfs_journal { int j_errno; /* when flushing ordered buffers, throttle new ordered writers */ - struct work_struct j_work; + struct delayed_work j_work; + struct super_block *j_work_sb; atomic_t j_async_throttle; }; diff --git a/include/linux/relay.h b/include/linux/relay.h index 24accb48384..0e3d91b7699 100644 --- a/include/linux/relay.h +++ b/include/linux/relay.h @@ -38,7 +38,7 @@ struct rchan_buf size_t subbufs_consumed; /* count of sub-buffers consumed */ struct rchan *chan; /* associated channel */ wait_queue_head_t read_wait; /* reader wait queue */ - struct work_struct wake_readers; /* reader wake-up work struct */ + struct delayed_work wake_readers; /* reader wake-up work struct */ struct dentry *dentry; /* channel file dentry */ struct kref kref; /* channel buffer refcount */ struct page **page_array; /* array of current buffer pages */ diff --git a/include/linux/usb.h b/include/linux/usb.h index 5482bfb3303..06ce7a62604 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -382,7 +382,7 @@ struct usb_device { int pm_usage_cnt; /* usage counter for autosuspend */ #ifdef CONFIG_PM - struct work_struct autosuspend; /* for delayed autosuspends */ + struct delayed_work autosuspend; /* for delayed autosuspends */ struct mutex pm_mutex; /* protects PM operations */ unsigned auto_pm:1; /* autosuspend/resume in progress */ diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h index 617b672b113..89119277553 100644 --- a/include/net/ieee80211softmac.h +++ b/include/net/ieee80211softmac.h @@ -108,8 +108,8 @@ struct ieee80211softmac_assoc_info { /* Scan retries remaining */ int scan_retry; - struct work_struct work; - struct work_struct timeout; + struct delayed_work work; + struct delayed_work timeout; }; struct ieee80211softmac_bss_info { diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index c6d93bb0dcd..60b684470db 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1030,7 +1030,7 @@ void sctp_inq_init(struct sctp_inq *); void sctp_inq_free(struct sctp_inq *); void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet); struct sctp_chunk *sctp_inq_pop(struct sctp_inq *); -void sctp_inq_set_th_handler(struct sctp_inq *, void (*)(void *), void *); +void sctp_inq_set_th_handler(struct sctp_inq *, work_func_t); /* This is the structure we use to hold outbound chunks. You push * chunks in and they automatically pop out the other end as bundled diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index 9582e840166..9ccc0365aa8 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -200,9 +200,14 @@ struct domain_device { void *lldd_dev; }; +struct sas_discovery_event { + struct work_struct work; + struct asd_sas_port *port; +}; + struct sas_discovery { spinlock_t disc_event_lock; - struct work_struct disc_work[DISC_NUM_EVENTS]; + struct sas_discovery_event disc_work[DISC_NUM_EVENTS]; unsigned long pending; u8 fanout_sas_addr[8]; u8 eeds_a[8]; @@ -248,14 +253,19 @@ struct asd_sas_port { void *lldd_port; /* not touched by the sas class code */ }; +struct asd_sas_event { + struct work_struct work; + struct asd_sas_phy *phy; +}; + /* The phy pretty much is controlled by the LLDD. * The class only reads those fields. */ struct asd_sas_phy { /* private: */ /* protected by ha->event_lock */ - struct work_struct port_events[PORT_NUM_EVENTS]; - struct work_struct phy_events[PHY_NUM_EVENTS]; + struct asd_sas_event port_events[PORT_NUM_EVENTS]; + struct asd_sas_event phy_events[PHY_NUM_EVENTS]; unsigned long port_events_pending; unsigned long phy_events_pending; @@ -307,10 +317,15 @@ struct scsi_core { int queue_thread_kill; }; +struct sas_ha_event { + struct work_struct work; + struct sas_ha_struct *ha; +}; + struct sas_ha_struct { /* private: */ spinlock_t event_lock; - struct work_struct ha_events[HA_NUM_EVENTS]; + struct sas_ha_event ha_events[HA_NUM_EVENTS]; unsigned long pending; struct scsi_core core; diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index fd352323378..798f7c7ee42 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -206,9 +206,9 @@ struct fc_rport { /* aka fc_starget_attrs */ u8 flags; struct list_head peers; struct device dev; - struct work_struct dev_loss_work; + struct delayed_work dev_loss_work; struct work_struct scan_work; - struct work_struct fail_io_work; + struct delayed_work fail_io_work; struct work_struct stgt_delete_work; struct work_struct rport_delete_work; } __attribute__((aligned(sizeof(unsigned long)))); diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 4b95c89c95c..d5c218ddc52 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -176,7 +176,7 @@ struct iscsi_cls_session { /* recovery fields */ int recovery_tmo; - struct work_struct recovery_work; + struct delayed_work recovery_work; int target_id; diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h index 4c43521cc49..33720397a90 100644 --- a/include/sound/ac97_codec.h +++ b/include/sound/ac97_codec.h @@ -511,7 +511,7 @@ struct snd_ac97 { #ifdef CONFIG_SND_AC97_POWER_SAVE unsigned int power_up; /* power states */ struct workqueue_struct *power_workq; - struct work_struct power_work; + struct delayed_work power_work; #endif struct device dev; }; diff --git a/include/sound/ak4114.h b/include/sound/ak4114.h index 11702aa0bea..2ee061625fd 100644 --- a/include/sound/ak4114.h +++ b/include/sound/ak4114.h @@ -182,7 +182,7 @@ struct ak4114 { unsigned char rcs0; unsigned char rcs1; struct workqueue_struct *workqueue; - struct work_struct work; + struct delayed_work work; void *change_callback_private; void (*change_callback)(struct ak4114 *ak4114, unsigned char c0, unsigned char c1); }; -- cgit v1.2.3 From 6d5aefb8eaa38e44b5b8cf60c812aceafc02d924 Mon Sep 17 00:00:00 2001 From: David Howells Date: Tue, 5 Dec 2006 19:36:26 +0000 Subject: WorkQueue: Fix up arch-specific work items where possible Fix up arch-specific work items where possible to use the new work_struct and delayed_work structs. Three places that enqueue bits of their stack and then return have been marked with #error as this is not permitted. Signed-Off-By: David Howells --- include/asm-arm/arch-omap/irda.h | 2 +- include/linux/netpoll.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-arm/arch-omap/irda.h b/include/asm-arm/arch-omap/irda.h index 805ae3575e4..345a649ec83 100644 --- a/include/asm-arm/arch-omap/irda.h +++ b/include/asm-arm/arch-omap/irda.h @@ -24,7 +24,7 @@ struct omap_irda_config { /* Very specific to the needs of some platforms (h3,h4) * having calls which can sleep in irda_set_speed. */ - struct work_struct gpio_expa; + struct delayed_work gpio_expa; int rx_channel; int tx_channel; unsigned long dest_start; diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 2cc9867b162..29930b71a9a 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -32,7 +32,7 @@ struct netpoll_info { struct netpoll *rx_np; /* netpoll that registered an rx_hook */ struct sk_buff_head arp_tx; /* list of arp requests to reply to */ struct sk_buff_head txq; - struct work_struct tx_work; + struct delayed_work tx_work; }; void netpoll_poll(struct netpoll *np); -- cgit v1.2.3 From 06328b4f7919e9d2169d45cadc5a37b828a78eda Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 6 Dec 2006 15:02:26 +0000 Subject: Actually update the fixed up compile failures. Signed-Off-By: David Howells --- include/scsi/libsas.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index b09bdd8c339..9233ed5de66 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h @@ -646,6 +646,6 @@ void sas_unregister_dev(struct domain_device *); void sas_init_dev(struct domain_device *); -void sas_task_abort(struct sas_task *task); +void sas_task_abort(struct work_struct *); #endif /* _SASLIB_H_ */ -- cgit v1.2.3