diff options
| author | David Howells <dhowells@redhat.com> | 2006-11-22 09:54:01 -0500 |
|---|---|---|
| committer | David Howells <dhowells@redhat.com> | 2006-11-22 09:54:01 -0500 |
| commit | 52bad64d95bd89e08c49ec5a071fa6dcbe5a1a9c (patch) | |
| tree | 5849b4e3c17daa70a7e81cfdeaddac9ac8a0e953 /include/linux | |
| parent | 0f9005a6f7a82f4aacbd72f7b92322a8ca1c3f97 (diff) | |
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 <dhowells@redhat.com>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/aio.h | 2 | ||||
| -rw-r--r-- | include/linux/kbd_kern.h | 2 | ||||
| -rw-r--r-- | include/linux/libata.h | 4 | ||||
| -rw-r--r-- | include/linux/nfs_fs_sb.h | 2 | ||||
| -rw-r--r-- | include/linux/sunrpc/rpc_pipe_fs.h | 2 | ||||
| -rw-r--r-- | include/linux/sunrpc/xprt.h | 2 | ||||
| -rw-r--r-- | include/linux/tty.h | 2 | ||||
| -rw-r--r-- | include/linux/workqueue.h | 44 |
8 files changed, 40 insertions, 20 deletions
diff --git a/include/linux/aio.h b/include/linux/aio.h index 0d71c0041f..9e350fd44d 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h | |||
| @@ -194,7 +194,7 @@ struct kioctx { | |||
| 194 | 194 | ||
| 195 | struct aio_ring_info ring_info; | 195 | struct aio_ring_info ring_info; |
| 196 | 196 | ||
| 197 | struct work_struct wq; | 197 | struct delayed_work wq; |
| 198 | }; | 198 | }; |
| 199 | 199 | ||
| 200 | /* prototypes */ | 200 | /* prototypes */ |
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index efe0ee4cc8..06c58c423f 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) | |||
| 158 | if (t->buf.tail != NULL) | 158 | if (t->buf.tail != NULL) |
| 159 | t->buf.tail->commit = t->buf.tail->used; | 159 | t->buf.tail->commit = t->buf.tail->used; |
| 160 | spin_unlock_irqrestore(&t->buf.lock, flags); | 160 | spin_unlock_irqrestore(&t->buf.lock, flags); |
| 161 | schedule_work(&t->buf.work); | 161 | schedule_delayed_work(&t->buf.work, 0); |
| 162 | } | 162 | } |
| 163 | 163 | ||
| 164 | #endif | 164 | #endif |
diff --git a/include/linux/libata.h b/include/linux/libata.h index abd2debebc..5f04006e8d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -568,8 +568,8 @@ struct ata_port { | |||
| 568 | struct ata_host *host; | 568 | struct ata_host *host; |
| 569 | struct device *dev; | 569 | struct device *dev; |
| 570 | 570 | ||
| 571 | struct work_struct port_task; | 571 | struct delayed_work port_task; |
| 572 | struct work_struct hotplug_task; | 572 | struct delayed_work hotplug_task; |
| 573 | struct work_struct scsi_rescan_task; | 573 | struct work_struct scsi_rescan_task; |
| 574 | 574 | ||
| 575 | unsigned int hsm_task_state; | 575 | unsigned int hsm_task_state; |
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 7ccfc7ef0a..95796e6924 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h | |||
| @@ -51,7 +51,7 @@ struct nfs_client { | |||
| 51 | 51 | ||
| 52 | unsigned long cl_lease_time; | 52 | unsigned long cl_lease_time; |
| 53 | unsigned long cl_last_renewal; | 53 | unsigned long cl_last_renewal; |
| 54 | struct work_struct cl_renewd; | 54 | struct delayed_work cl_renewd; |
| 55 | 55 | ||
| 56 | struct rpc_wait_queue cl_rpcwaitq; | 56 | struct rpc_wait_queue cl_rpcwaitq; |
| 57 | 57 | ||
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h index a2eb9b4a9d..4a68125b6d 100644 --- a/include/linux/sunrpc/rpc_pipe_fs.h +++ b/include/linux/sunrpc/rpc_pipe_fs.h | |||
| @@ -30,7 +30,7 @@ struct rpc_inode { | |||
| 30 | #define RPC_PIPE_WAIT_FOR_OPEN 1 | 30 | #define RPC_PIPE_WAIT_FOR_OPEN 1 |
| 31 | int flags; | 31 | int flags; |
| 32 | struct rpc_pipe_ops *ops; | 32 | struct rpc_pipe_ops *ops; |
| 33 | struct work_struct queue_timeout; | 33 | struct delayed_work queue_timeout; |
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | static inline struct rpc_inode * | 36 | static inline struct rpc_inode * |
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 60394fbc4c..3e04c1512f 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
| @@ -177,7 +177,7 @@ struct rpc_xprt { | |||
| 177 | unsigned long connect_timeout, | 177 | unsigned long connect_timeout, |
| 178 | bind_timeout, | 178 | bind_timeout, |
| 179 | reestablish_timeout; | 179 | reestablish_timeout; |
| 180 | struct work_struct connect_worker; | 180 | struct delayed_work connect_worker; |
| 181 | unsigned short port; | 181 | unsigned short port; |
| 182 | 182 | ||
| 183 | /* | 183 | /* |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 44091c0db0..c1f7164461 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -53,7 +53,7 @@ struct tty_buffer { | |||
| 53 | }; | 53 | }; |
| 54 | 54 | ||
| 55 | struct tty_bufhead { | 55 | struct tty_bufhead { |
| 56 | struct work_struct work; | 56 | struct delayed_work work; |
| 57 | struct semaphore pty_sem; | 57 | struct semaphore pty_sem; |
| 58 | spinlock_t lock; | 58 | spinlock_t lock; |
| 59 | struct tty_buffer *head; /* Queue head */ | 59 | struct tty_buffer *head; /* Queue head */ |
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 9bca3539a1..9faaccae57 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
| @@ -17,6 +17,10 @@ struct work_struct { | |||
| 17 | void (*func)(void *); | 17 | void (*func)(void *); |
| 18 | void *data; | 18 | void *data; |
| 19 | void *wq_data; | 19 | void *wq_data; |
| 20 | }; | ||
| 21 | |||
| 22 | struct delayed_work { | ||
| 23 | struct work_struct work; | ||
| 20 | struct timer_list timer; | 24 | struct timer_list timer; |
| 21 | }; | 25 | }; |
| 22 | 26 | ||
| @@ -28,32 +32,48 @@ struct execute_work { | |||
| 28 | .entry = { &(n).entry, &(n).entry }, \ | 32 | .entry = { &(n).entry, &(n).entry }, \ |
| 29 | .func = (f), \ | 33 | .func = (f), \ |
| 30 | .data = (d), \ | 34 | .data = (d), \ |
| 35 | } | ||
| 36 | |||
| 37 | #define __DELAYED_WORK_INITIALIZER(n, f, d) { \ | ||
| 38 | .work = __WORK_INITIALIZER((n).work, (f), (d)), \ | ||
| 31 | .timer = TIMER_INITIALIZER(NULL, 0, 0), \ | 39 | .timer = TIMER_INITIALIZER(NULL, 0, 0), \ |
| 32 | } | 40 | } |
| 33 | 41 | ||
| 34 | #define DECLARE_WORK(n, f, d) \ | 42 | #define DECLARE_WORK(n, f, d) \ |
| 35 | struct work_struct n = __WORK_INITIALIZER(n, f, d) | 43 | struct work_struct n = __WORK_INITIALIZER(n, f, d) |
| 36 | 44 | ||
| 45 | #define DECLARE_DELAYED_WORK(n, f, d) \ | ||
| 46 | struct delayed_work n = __DELAYED_WORK_INITIALIZER(n, f, d) | ||
| 47 | |||
| 37 | /* | 48 | /* |
| 38 | * initialize a work-struct's func and data pointers: | 49 | * initialize a work item's function and data pointers |
| 39 | */ | 50 | */ |
| 40 | #define PREPARE_WORK(_work, _func, _data) \ | 51 | #define PREPARE_WORK(_work, _func, _data) \ |
| 41 | do { \ | 52 | do { \ |
| 42 | (_work)->func = _func; \ | 53 | (_work)->func = (_func); \ |
| 43 | (_work)->data = _data; \ | 54 | (_work)->data = (_data); \ |
| 44 | } while (0) | 55 | } while (0) |
| 45 | 56 | ||
| 57 | #define PREPARE_DELAYED_WORK(_work, _func, _data) \ | ||
| 58 | PREPARE_WORK(&(_work)->work, (_func), (_data)) | ||
| 59 | |||
| 46 | /* | 60 | /* |
| 47 | * initialize all of a work-struct: | 61 | * initialize all of a work item in one go |
| 48 | */ | 62 | */ |
| 49 | #define INIT_WORK(_work, _func, _data) \ | 63 | #define INIT_WORK(_work, _func, _data) \ |
| 50 | do { \ | 64 | do { \ |
| 51 | INIT_LIST_HEAD(&(_work)->entry); \ | 65 | INIT_LIST_HEAD(&(_work)->entry); \ |
| 52 | (_work)->pending = 0; \ | 66 | (_work)->pending = 0; \ |
| 53 | PREPARE_WORK((_work), (_func), (_data)); \ | 67 | PREPARE_WORK((_work), (_func), (_data)); \ |
| 68 | } while (0) | ||
| 69 | |||
| 70 | #define INIT_DELAYED_WORK(_work, _func, _data) \ | ||
| 71 | do { \ | ||
| 72 | INIT_WORK(&(_work)->work, (_func), (_data)); \ | ||
| 54 | init_timer(&(_work)->timer); \ | 73 | init_timer(&(_work)->timer); \ |
| 55 | } while (0) | 74 | } while (0) |
| 56 | 75 | ||
| 76 | |||
| 57 | extern struct workqueue_struct *__create_workqueue(const char *name, | 77 | extern struct workqueue_struct *__create_workqueue(const char *name, |
| 58 | int singlethread); | 78 | int singlethread); |
| 59 | #define create_workqueue(name) __create_workqueue((name), 0) | 79 | #define create_workqueue(name) __create_workqueue((name), 0) |
| @@ -62,24 +82,24 @@ extern struct workqueue_struct *__create_workqueue(const char *name, | |||
| 62 | extern void destroy_workqueue(struct workqueue_struct *wq); | 82 | extern void destroy_workqueue(struct workqueue_struct *wq); |
| 63 | 83 | ||
| 64 | extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work)); | 84 | extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work)); |
| 65 | extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct work_struct *work, unsigned long delay)); | 85 | extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *work, unsigned long delay)); |
| 66 | extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, | 86 | extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, |
| 67 | struct work_struct *work, unsigned long delay); | 87 | struct delayed_work *work, unsigned long delay); |
| 68 | extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq)); | 88 | extern void FASTCALL(flush_workqueue(struct workqueue_struct *wq)); |
| 69 | 89 | ||
| 70 | extern int FASTCALL(schedule_work(struct work_struct *work)); | 90 | extern int FASTCALL(schedule_work(struct work_struct *work)); |
| 71 | extern int FASTCALL(schedule_delayed_work(struct work_struct *work, unsigned long delay)); | 91 | extern int FASTCALL(schedule_delayed_work(struct delayed_work *work, unsigned long delay)); |
| 72 | 92 | ||
| 73 | extern int schedule_delayed_work_on(int cpu, struct work_struct *work, unsigned long delay); | 93 | extern int schedule_delayed_work_on(int cpu, struct delayed_work *work, unsigned long delay); |
| 74 | extern int schedule_on_each_cpu(void (*func)(void *info), void *info); | 94 | extern int schedule_on_each_cpu(void (*func)(void *info), void *info); |
| 75 | extern void flush_scheduled_work(void); | 95 | extern void flush_scheduled_work(void); |
| 76 | extern int current_is_keventd(void); | 96 | extern int current_is_keventd(void); |
| 77 | extern int keventd_up(void); | 97 | extern int keventd_up(void); |
| 78 | 98 | ||
| 79 | extern void init_workqueues(void); | 99 | extern void init_workqueues(void); |
| 80 | void cancel_rearming_delayed_work(struct work_struct *work); | 100 | void cancel_rearming_delayed_work(struct delayed_work *work); |
| 81 | void cancel_rearming_delayed_workqueue(struct workqueue_struct *, | 101 | void cancel_rearming_delayed_workqueue(struct workqueue_struct *, |
| 82 | struct work_struct *); | 102 | struct delayed_work *); |
| 83 | int execute_in_process_context(void (*fn)(void *), void *, | 103 | int execute_in_process_context(void (*fn)(void *), void *, |
| 84 | struct execute_work *); | 104 | struct execute_work *); |
| 85 | 105 | ||
| @@ -88,13 +108,13 @@ int execute_in_process_context(void (*fn)(void *), void *, | |||
| 88 | * function may still be running on return from cancel_delayed_work(). Run | 108 | * function may still be running on return from cancel_delayed_work(). Run |
| 89 | * flush_scheduled_work() to wait on it. | 109 | * flush_scheduled_work() to wait on it. |
| 90 | */ | 110 | */ |
| 91 | static inline int cancel_delayed_work(struct work_struct *work) | 111 | static inline int cancel_delayed_work(struct delayed_work *work) |
| 92 | { | 112 | { |
| 93 | int ret; | 113 | int ret; |
| 94 | 114 | ||
| 95 | ret = del_timer_sync(&work->timer); | 115 | ret = del_timer_sync(&work->timer); |
| 96 | if (ret) | 116 | if (ret) |
| 97 | clear_bit(0, &work->pending); | 117 | clear_bit(0, &work->work.pending); |
| 98 | return ret; | 118 | return ret; |
| 99 | } | 119 | } |
| 100 | 120 | ||
