summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-12-07 15:48:15 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-12-07 15:48:15 -0500
commit34161db6b14d984fb9b06c735b7b42f8803f6851 (patch)
tree99656278b6697f1cde5b05894b7c0ee22c63a00e /include/linux
parent5847e1f4d058677c5e46dc6c3e3c70e8855ea3ba (diff)
parent620034c84d1d939717bdfbe02c51a3fee43541c3 (diff)
downloadlwn-34161db6b14d984fb9b06c735b7b42f8803f6851.tar.gz
lwn-34161db6b14d984fb9b06c735b7b42f8803f6851.zip
Merge branch 'master' of /home/trondmy/kernel/linux-2.6/ into merge_linus
Conflicts: include/linux/sunrpc/xprt.h net/sunrpc/xprtsock.c Fix up conflicts with the workqueue changes.
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/aio.h2
-rw-r--r--include/linux/connector.h4
-rw-r--r--include/linux/i2o.h2
-rw-r--r--include/linux/kbd_kern.h2
-rw-r--r--include/linux/libata.h7
-rw-r--r--include/linux/mmc/host.h2
-rw-r--r--include/linux/ncp_fs_sb.h8
-rw-r--r--include/linux/netpoll.h2
-rw-r--r--include/linux/nfs_fs_sb.h2
-rw-r--r--include/linux/reiserfs_fs_sb.h3
-rw-r--r--include/linux/relay.h2
-rw-r--r--include/linux/sunrpc/rpc_pipe_fs.h2
-rw-r--r--include/linux/tty.h2
-rw-r--r--include/linux/usb.h2
-rw-r--r--include/linux/workqueue.h145
15 files changed, 140 insertions, 47 deletions
diff --git a/include/linux/aio.h b/include/linux/aio.h
index 0d71c0041f13..9e350fd44d77 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/connector.h b/include/linux/connector.h
index 4c02119c6ab9..3ea1cd58de97 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 c115e9e840b4..1fb02e17f6f6 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/kbd_kern.h b/include/linux/kbd_kern.h
index efe0ee4cc80b..06c58c423fe1 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 202283b5df96..ab2754830322 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -575,8 +575,9 @@ struct ata_port {
struct ata_host *host;
struct device *dev;
- struct work_struct port_task;
- struct work_struct hotplug_task;
+ void *port_task_data;
+ struct delayed_work port_task;
+ struct delayed_work hotplug_task;
struct work_struct scsi_rescan_task;
unsigned int hsm_task_state;
@@ -755,7 +756,7 @@ extern void ata_host_resume(struct ata_host *host);
extern int ata_ratelimit(void);
extern 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/mmc/host.h b/include/linux/mmc/host.h
index 528e7d3fecb1..c15ae1986b98 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 b089d9506283..a503052138bd 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/netpoll.h b/include/linux/netpoll.h
index 2cc9867b1626..29930b71a9aa 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);
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index 7ccfc7ef0a83..95796e6924f1 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/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h
index 62a7169aed8b..3a28742d86f9 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 24accb483849..0e3d91b76996 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/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index a2eb9b4a9de3..4a68125b6de6 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/tty.h b/include/linux/tty.h
index 65321f911c1e..f717f0898238 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/usb.h b/include/linux/usb.h
index 0cd73edeef13..aab5b1b72021 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -388,7 +388,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/linux/workqueue.h b/include/linux/workqueue.h
index 9bca3539a1e5..4a3ea83c6d16 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -11,12 +11,23 @@
struct workqueue_struct;
+struct work_struct;
+typedef void (*work_func_t)(struct work_struct *work);
+
struct work_struct {
- unsigned long pending;
+ /* 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;
- void (*func)(void *);
- void *data;
- void *wq_data;
+ work_func_t func;
+};
+
+struct delayed_work {
+ struct work_struct work;
struct timer_list timer;
};
@@ -24,36 +35,117 @@ 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), \
+ }
+
+#define __WORK_INITIALIZER_NAR(n, f) { \
+ .management = (1 << WORK_STRUCT_NOAUTOREL), \
.entry = { &(n).entry, &(n).entry }, \
.func = (f), \
- .data = (d), \
+ }
+
+#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) \
+ 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-struct's func 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; \
+ (_work)->func = (_func); \
} while (0)
+#define PREPARE_DELAYED_WORK(_work, _func) \
+ PREPARE_WORK(&(_work)->work, (_func))
+
/*
- * initialize all of a work-struct:
+ * initialize all of a work item in one go
*/
-#define INIT_WORK(_work, _func, _data) \
+#define INIT_WORK(_work, _func) \
do { \
+ (_work)->management = 0; \
INIT_LIST_HEAD(&(_work)->entry); \
- (_work)->pending = 0; \
- PREPARE_WORK((_work), (_func), (_data)); \
+ 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_NAR(_work, _func) \
+ do { \
+ INIT_WORK_NAR(&(_work)->work, (_func)); \
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)
+
+/**
+ * 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);
#define create_workqueue(name) __create_workqueue((name), 0)
@@ -62,39 +154,38 @@ 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_on_each_cpu(void (*func)(void *info), void *info);
+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);
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 *);
-int execute_in_process_context(void (*fn)(void *), void *,
- struct execute_work *);
+ struct delayed_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
* 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(WORK_STRUCT_PENDING, &work->work.management);
return ret;
}