workqueue 2.5.74->2.4.21 backport
Subsystems (4)
PATCH 1/2 workqueue 2.5.74->2.4.21 backport
Hi again,
The last time I asked about this, Marc-Christian Petersen pointed me to <http://marc.theaimsgroup.com/?l=linux-kernel&m=103885818416173&w=2>
which was a backport of the 2.5.51 workqueue (to 2.4.20 I guess), by Christoph Hellwig.
Turns out it was missing a few minor glue pieces, which I was able to easily add. It also didn't test for a cpu's online-ness before creating a queue for it; this caused problems somewhere (I forget).
Here is that backport with the glue added. Next I will send a relative diff which incorporates updates as of 2.5.74.
I'm looking for any comments on the goodness of the patch. I'm not looking for it to be included in any 2.4 kernel, as there are no 2.4
users of it. But I have a local fork which backports the 2.5
NFS ... which does use the workqueue. So I'm looking for expert opinion on whether it looks problematic. The real meat is in the next patch, this one doesn't touch existing code in a significant way.
Thanks,
/fc
include/asm-i386/smp.h +2 -0
@@ -83,6 +83,8 @@ extern void smp_store_cpu_info(int id);#define smp_processor_id () (current->processor) +#define cpu_online (cpu) (cpu_online_map & (1<<(cpu))) +static __inlineint hard_smp_processor_id (void ) {/* we don't want to mark this access volatile - bad code generation */
include/linux/workqueue.h +75 -0
75 lines not on this page · raw message
init/main.c +2 -0
@@ -27,6 +27,7 @@#include <linux/iobuf.h> #include <linux/bootmem.h> #include <linux/tty.h> +#include <linux/workqueue.h> #include <asm/io.h> #include <asm/bugs.h>
@@ -527,6 +528,7 @@ static void __init do_basic_setup(void)sock_init ();start_context_thread (); +init_workqueues ();do_initcalls ();#ifdef CONFIG_IRDA
kernel/Makefile +3 -2
@@ -9,12 +9,13 @@ O_TARGET := kernel.o -export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o +export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \ + printk.o workqueue.o obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \ module.o exit.o itimer.o info.o time.o softirq.o resource.o \ sysctl.o acct.o capability.o ptrace.o timer.o user.o \ - signal.o sys.o kmod.o context.o + signal.o sys.o kmod.o context.o workqueue.o obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += ksyms.o
kernel/workqueue.c +369 -0
369 lines not on this page · raw message
PATCH 2/2 workqueue 2.5.74->2.4.21 backport
Quoted 2 lines · Frank Cusack
Here is that backport with the glue added. Next I will send a relative diff which incorporates updates as of 2.5.74.
And here is the diff which brings things up to 2.5.74. It's a tad inelegant in shed.c:__wake_up_common(), but from my perspective I wanted to keep the existing code there as simple as possible, to ease future (2.4.22+) porting.
Any comments/advice appreciated, thanks.
/fc
include/linux/wait.h +25 -1
@@ -28,17 +28,21 @@#define WAITQUEUE_DEBUG 0#endif +typedef struct __wait_queue wait_queue_t ; +typedef int (*wait_queue_func_t )(wait_queue_t *wait,unsigned mode,int sync); +extern int default_wake_function (wait_queue_t *wait,unsigned mode,int sync); +struct __wait_queue {unsigned int flags;#define WQ_FLAG_EXCLUSIVE 0x01struct task_struct * task; +wait_queue_func_t func;struct list_head task_list;#if WAITQUEUE_DEBUG long __magic;long __waker;#endif }; -typedef struct __wait_queue wait_queue_t ;/* * 'dual' spinlock architecture. Can be switched between spinlock_t and
@@ -174,6 +178,7 @@ static inline void init_waitqueue_entry(#endif q->flags =0 ; q->task = p; + q->func =NULL ;#if WAITQUEUE_DEBUG q->__magic = (long )&q->__magic;#endif
@@ -230,6 +235,25 @@ static inline void __remove_wait_queue(w#endif list_del(&old->task_list); } + +/* +* Waitqueues which are removed from the waitqueue_head at wakeup time +*/ +void FASTCALL (prepare_to_wait (wait_queue_head_t *q, +wait_queue_t *wait,int state)); +void FASTCALL (prepare_to_wait_exclusive (wait_queue_head_t *q, +wait_queue_t *wait,int state)); +void FASTCALL (finish_wait (wait_queue_head_t *q,wait_queue_t *wait)); +int autoremove_wake_function (wait_queue_t *wait,unsigned mode,int sync); + +#define DEFINE_WAIT (name) \ + wait_queue_t name = { \ + .task = current, \ + .func = autoremove_wake_function, \ + .task_list = { .next = &name.task_list, \ + .prev = &name.task_list, \ + }, \ + }#endif /* __KERNEL__ */
kernel/fork.c +46 -0
52 lines not on this page · raw message
kernel/ksyms.c +5 -0
@@ -378,6 +378,10 @@ EXPORT_SYMBOL(irq_stat);EXPORT_SYMBOL (add_wait_queue);EXPORT_SYMBOL (add_wait_queue_exclusive);EXPORT_SYMBOL (remove_wait_queue); +EXPORT_SYMBOL (prepare_to_wait); +EXPORT_SYMBOL (prepare_to_wait_exclusive); +EXPORT_SYMBOL (finish_wait); +EXPORT_SYMBOL (autoremove_wake_function);/* completion handling */ EXPORT_SYMBOL (wait_for_completion);
@@ -444,6 +448,7 @@ EXPORT_SYMBOL(iomem_resource);/* process management */ EXPORT_SYMBOL (complete_and_exit); +EXPORT_SYMBOL (default_wake_function);EXPORT_SYMBOL (__wake_up);EXPORT_SYMBOL (__wake_up_sync);EXPORT_SYMBOL (wake_up_process);
kernel/sched.c +16 -3
@@ -702,6 +702,12 @@ same_process:return ; } +int default_wake_function (wait_queue_t *curr,unsigned mode,int sync) +{ +struct task_struct *p = curr->task; +return try_to_wake_up (p, sync); +} +/* * The core wakeup function. Non-exclusive wakeups (nr_exclusive == 0) just wake everything * up. If it's an exclusive wakeup (nr_exclusive == small +ve number) then we wake all the
@@ -714,22 +720,29 @@ same_process:static inline void __wake_up_common (wait_queue_head_t *q,unsigned int mode,int nr_exclusive,const int sync) { -struct list_head *tmp; +struct list_head *tmp, *next;struct task_struct *p;CHECK_MAGIC_WQHEAD (q);WQ_CHECK_LIST_HEAD (&q->task_list); -list_for_each (tmp,&q->task_list) { +list_for_each_safe (tmp, next, &q->task_list) {unsigned int state; +unsigned flags;wait_queue_t *curr =list_entry (tmp, wait_queue_t, task_list);CHECK_MAGIC (curr->__magic); + flags = curr->flags; p = curr->task; state = p->state;if (state & mode) { +int r;WQ_NOTE_WAKER (curr); -if (try_to_wake_up (p, sync) && (curr->flags&WQ_FLAG_EXCLUSIVE ) && !--nr_exclusive) +if (curr->func) + r = curr->func (curr, mode, sync); +else + r =try_to_wake_up (p, sync); +if (r && (flags&WQ_FLAG_EXCLUSIVE ) && !--nr_exclusive)break ; } }
kernel/workqueue.c +86 -76
260 lines not on this page · raw message