--- linux/fs/proc/array.c.orig Mon May 10 22:04:29 1999 +++ linux/fs/proc/array.c Tue May 11 12:37:45 1999 @@ -302,6 +302,14 @@ kstat.context_swtch, xtime.tv_sec - jiffies / HZ, total_forks); +#define OUT(x) \ + do { extern int x; len += \ + sprintf(buffer + len, #x ": %ld\n", (long)x); x = 0; } while (0) + + OUT(wakeup_calls); + OUT(wakeup_normal_processes); + OUT(wakeup_exclusive_processes); +#undef OUT return len; } --- linux/fs/proc/kmsg.c.orig Tue Nov 24 11:41:28 1998 +++ linux/fs/proc/kmsg.c Mon May 10 22:04:40 1999 @@ -15,7 +15,7 @@ #include extern unsigned long log_size; -extern struct wait_queue * log_wait; +extern wait_queue_head_t log_wait; extern int do_syslog(int type, char * bug, int count); --- linux/fs/isofs/inode.c.orig Fri Jan 8 13:31:30 1999 +++ linux/fs/isofs/inode.c Mon May 10 22:04:40 1999 @@ -423,6 +423,7 @@ */ mm_segment_t old_fs=get_fs(); inode_fake.i_rdev=dev; + init_waitqueue_head(&inode_fake.i_wait); ms_info.addr_format=CDROM_LBA; set_fs(KERNEL_DS); i=get_blkfops(MAJOR(dev))->ioctl(&inode_fake, --- linux/fs/nfs/dir.c.orig Mon May 10 22:04:29 1999 +++ linux/fs/nfs/dir.c Mon May 10 22:04:40 1999 @@ -45,7 +45,7 @@ unsigned int size; /* # of entries */ unsigned long age; /* last used */ unsigned long mtime; /* last attr stamp */ - struct wait_queue * wait; + wait_queue_head_t wait; __u32 * entry; /* three __u32's per entry */ }; @@ -124,8 +124,8 @@ { struct dentry *dentry = filp->f_dentry; struct inode *inode = dentry->d_inode; - static struct wait_queue *readdir_wait = NULL; - struct wait_queue **waitp = NULL; + static DECLARE_WAIT_QUEUE_HEAD(readdir_wait); + wait_queue_head_t *waitp = NULL; struct nfs_dirent *cache, *free; unsigned long age, dead; u32 cookie; @@ -231,6 +231,7 @@ cache->valid = 0; cache->dev = inode->i_dev; cache->ino = inode->i_ino; + init_waitqueue_head(&cache->wait); if (!cache->entry) { result = -ENOMEM; cache->entry = (__u32 *) get_free_page(GFP_KERNEL); --- linux/fs/nfs/write.c.orig Tue Mar 9 10:03:41 1999 +++ linux/fs/nfs/write.c Mon May 10 22:04:40 1999 @@ -292,6 +292,7 @@ wreq->wb_file = file; wreq->wb_pid = current->pid; wreq->wb_page = page; + init_waitqueue_head(&wreq->wb_wait); wreq->wb_offset = offset; wreq->wb_bytes = bytes; wreq->wb_count = 2; /* One for the IO, one for us */ @@ -363,7 +364,7 @@ struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; struct rpc_clnt *clnt = NFS_CLIENT(inode); - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); sigset_t oldmask; int retval; --- linux/fs/lockd/clntlock.c.orig Fri Jan 8 13:31:57 1999 +++ linux/fs/lockd/clntlock.c Mon May 10 22:04:40 1999 @@ -34,7 +34,7 @@ */ struct nlm_wait { struct nlm_wait * b_next; /* linked list */ - struct wait_queue * b_wait; /* where to wait on */ + wait_queue_head_t b_wait; /* where to wait on */ struct nlm_host * b_host; struct file_lock * b_lock; /* local file lock */ unsigned short b_reclaim; /* got to reclaim lock */ @@ -55,7 +55,7 @@ block.b_host = host; block.b_lock = fl; - block.b_wait = NULL; + init_waitqueue_head(&block.b_wait); block.b_status = NLM_LCK_BLOCKED; block.b_next = nlm_blocked; nlm_blocked = █ --- linux/fs/lockd/host.c.orig Tue Mar 9 10:03:41 1999 +++ linux/fs/lockd/host.c Mon May 10 22:04:40 1999 @@ -30,7 +30,7 @@ static struct nlm_host * nlm_hosts[NLM_HOST_NRHASH]; static unsigned long next_gc = 0; static int nrhosts = 0; -static struct semaphore nlm_host_sema = MUTEX; +static DECLARE_MUTEX(nlm_host_sema); static void nlm_gc_hosts(void); @@ -136,7 +136,7 @@ host->h_proto = proto; host->h_authflavor = RPC_AUTH_UNIX; host->h_rpcclnt = NULL; - host->h_sema = MUTEX; + init_MUTEX(&host->h_sema); host->h_nextrebind = jiffies + NLM_HOST_REBIND; host->h_expires = jiffies + NLM_HOST_EXPIRE; host->h_count = 1; --- linux/fs/lockd/svcsubs.c.orig Tue Apr 6 14:35:10 1999 +++ linux/fs/lockd/svcsubs.c Mon May 10 22:04:40 1999 @@ -26,7 +26,7 @@ #define FILE_NRHASH 32 #define FILE_HASH_BITS 5 static struct nlm_file * nlm_files[FILE_NRHASH]; -static struct semaphore nlm_file_sema = MUTEX; +static DECLARE_MUTEX(nlm_file_sema); static unsigned int file_hash(dev_t dev, ino_t ino) { @@ -76,7 +76,7 @@ memset(file, 0, sizeof(*file)); file->f_handle = *fh; - file->f_sema = MUTEX; + init_MUTEX(&file->f_sema); /* Open the file. Note that this must not sleep for too long, else * we would lock up lockd:-) So no NFS re-exports, folks. --- linux/fs/lockd/svc.c.orig Tue Mar 9 10:03:39 1999 +++ linux/fs/lockd/svc.c Mon May 10 22:04:40 1999 @@ -40,14 +40,14 @@ extern struct svc_program nlmsvc_program; struct nlmsvc_binding * nlmsvc_ops = NULL; -static struct semaphore nlmsvc_sema = MUTEX; +static DECLARE_MUTEX(nlmsvc_sema); static unsigned int nlmsvc_users = 0; static pid_t nlmsvc_pid = 0; unsigned long nlmsvc_grace_period = 0; unsigned long nlmsvc_timeout = 0; -static struct semaphore lockd_start = MUTEX_LOCKED; -static struct wait_queue * lockd_exit = NULL; +static DECLARE_MUTEX_LOCKED(lockd_start); +static DECLARE_WAIT_QUEUE_HEAD(lockd_exit); /* * Currently the following can be set only at insmod time. @@ -319,7 +319,7 @@ init_module(void) { /* Init the static variables */ - nlmsvc_sema = MUTEX; + init_MUTEX(&nlmsvc_sema); nlmsvc_users = 0; nlmsvc_pid = 0; lockd_exit = NULL; --- linux/fs/inode.c.orig Mon May 10 22:04:29 1999 +++ linux/fs/inode.c Mon May 10 22:04:40 1999 @@ -99,7 +99,7 @@ static void __wait_on_inode(struct inode * inode) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); add_wait_queue(&inode->i_wait, &wait); repeat: @@ -126,7 +126,7 @@ static inline void init_once(struct inode * inode) { memset(inode, 0, sizeof(*inode)); - init_waitqueue(&inode->i_wait); + init_waitqueue_head(&inode->i_wait); INIT_LIST_HEAD(&inode->i_hash); INIT_LIST_HEAD(&inode->i_dentry); sema_init(&inode->i_sem, 1); --- linux/fs/buffer.c.orig Mon May 10 22:04:25 1999 +++ linux/fs/buffer.c Mon May 10 22:04:40 1999 @@ -70,7 +70,7 @@ static struct buffer_head * unused_list = NULL; static struct buffer_head * reuse_list = NULL; -static struct wait_queue * buffer_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(buffer_wait); static int nr_buffers = 0; static int nr_buffers_type[NR_LIST] = {0,}; @@ -129,10 +129,9 @@ void __wait_on_buffer(struct buffer_head * bh) { struct task_struct *tsk = current; - struct wait_queue wait; + DECLARE_WAITQUEUE(wait, tsk); bh->b_count++; - wait.task = tsk; add_wait_queue(&bh->b_wait, &wait); repeat: tsk->state = TASK_UNINTERRUPTIBLE; @@ -928,6 +927,7 @@ } memset(bh,0,sizeof(*bh)); + init_waitqueue_head(&bh->b_wait); nr_unused_buffer_heads++; bh->b_next_free = unused_list; unused_list = bh; @@ -985,6 +985,7 @@ */ if((bh = kmem_cache_alloc(bh_cachep, SLAB_BUFFER)) != NULL) { memset(bh, 0, sizeof(*bh)); + init_waitqueue_head(&bh->b_wait); nr_buffer_heads++; return bh; } @@ -1009,6 +1010,7 @@ if(!async && (bh = kmem_cache_alloc(bh_cachep, SLAB_KERNEL)) != NULL) { memset(bh, 0, sizeof(*bh)); + init_waitqueue_head(&bh->b_wait); nr_buffer_heads++; return bh; } @@ -1029,7 +1031,7 @@ static struct buffer_head * create_buffers(unsigned long page, unsigned long size, int async) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); struct buffer_head *bh, *head; long offset; @@ -1553,8 +1555,8 @@ * response to dirty buffers. Once this process is activated, we write back * a limited number of buffers to the disks and then go back to sleep again. */ -static struct wait_queue * bdflush_wait = NULL; -static struct wait_queue * bdflush_done = NULL; +static DECLARE_WAIT_QUEUE_HEAD(bdflush_wait); +static DECLARE_WAIT_QUEUE_HEAD(bdflush_done); struct task_struct *bdflush_tsk = 0; void wakeup_bdflush(int wait) --- linux/fs/super.c.orig Mon May 10 22:04:29 1999 +++ linux/fs/super.c Mon May 10 22:04:40 1999 @@ -42,7 +42,7 @@ * unmounting a filesystem and re-mounting it (or something * else). */ -static struct semaphore mount_sem = MUTEX; +static DECLARE_MUTEX(mount_sem); extern void wait_for_keypress(void); extern struct file_operations * get_blkfops(unsigned int major); @@ -413,7 +413,7 @@ void __wait_on_super(struct super_block * sb) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); add_wait_queue(&sb->s_wait, &wait); repeat: @@ -530,6 +530,7 @@ memset(s, 0, sizeof(struct super_block)); INIT_LIST_HEAD(&s->s_dirty); list_add (&s->s_list, super_blocks.prev); + init_waitqueue_head(&s->s_wait); } return s; } --- linux/fs/pipe.c.orig Tue Nov 24 11:41:28 1998 +++ linux/fs/pipe.c Mon May 10 22:04:40 1999 @@ -414,7 +414,7 @@ } else { PIPE_BASE(*inode) = (char *) page; inode->i_op = &pipe_inode_operations; - PIPE_WAIT(*inode) = NULL; + init_waitqueue_head(&PIPE_WAIT(*inode)); PIPE_START(*inode) = PIPE_LEN(*inode) = 0; PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0; PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1; --- linux/fs/fifo.c.orig Tue Nov 24 11:41:28 1998 +++ linux/fs/fifo.c Mon May 10 22:04:40 1999 @@ -155,6 +155,6 @@ PIPE_BASE(*inode) = NULL; PIPE_START(*inode) = PIPE_LEN(*inode) = 0; PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0; - PIPE_WAIT(*inode) = NULL; + init_waitqueue_head(&PIPE_WAIT(*inode)); PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0; } --- linux/fs/select.c.orig Tue Jan 26 09:47:12 1999 +++ linux/fs/select.c Mon May 10 22:04:40 1999 @@ -58,7 +58,7 @@ } } -void __pollwait(struct file * filp, struct wait_queue ** wait_address, poll_table *p) +void __pollwait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) { for (;;) { if (p->nr < __MAX_POLL_TABLE_ENTRIES) { @@ -68,8 +68,7 @@ entry->filp = filp; filp->f_count++; entry->wait_address = wait_address; - entry->wait.task = current; - entry->wait.next = NULL; + init_waitqueue_entry(&entry->wait, current); add_wait_queue(wait_address,&entry->wait); p->nr++; return; --- linux/fs/locks.c.orig Tue Apr 6 14:35:08 1999 +++ linux/fs/locks.c Mon May 10 22:04:40 1999 @@ -595,6 +595,7 @@ tfl.fl_flags = FL_POSIX | FL_ACCESS; tfl.fl_owner = current->files; tfl.fl_pid = current->pid; + init_waitqueue_head(&tfl.fl_wait); tfl.fl_type = (read_write == FLOCK_VERIFY_WRITE) ? F_WRLCK : F_RDLCK; tfl.fl_start = offset; tfl.fl_end = offset + count - 1; @@ -644,6 +645,7 @@ memset(fl, 0, sizeof(*fl)); + init_waitqueue_head(&fl->fl_wait); fl->fl_flags = FL_POSIX; switch (l->l_type) { @@ -691,6 +693,7 @@ { memset(fl, 0, sizeof(*fl)); + init_waitqueue_head(&fl->fl_wait); if (!filp->f_dentry) /* just in case */ return (0); @@ -1109,6 +1112,7 @@ memset(new, 0, sizeof(*new)); new->fl_owner = fl->fl_owner; new->fl_pid = fl->fl_pid; + init_waitqueue_head(&new->fl_wait); new->fl_file = fl->fl_file; new->fl_flags = fl->fl_flags; new->fl_type = fl->fl_type; --- linux/kernel/sched.c.orig Mon May 10 22:04:29 1999 +++ linux/kernel/sched.c Mon May 10 22:15:37 1999 @@ -866,52 +866,63 @@ return; } -rwlock_t waitqueue_lock = RW_LOCK_UNLOCKED; +int wakeup_calls = 0; +int wakeup_normal_processes = 0; +int wakeup_exclusive_processes = 0; -/* - * wake_up doesn't wake up stopped processes - they have to be awakened - * with signals or similar. - * - * Note that we only need a read lock for the wait queue (and thus do not - * have to protect against interrupts), as the actual removal from the - * queue is handled by the process itself. - */ -void __wake_up(struct wait_queue **q, unsigned int mode) +void __wake_up(wait_queue_head_t *q, unsigned int mode) { + struct list_head *tmp, *head; + wait_queue_t *curr; struct task_struct *p; - struct wait_queue *head, *next; + unsigned long flags; if (!q) goto out; - /* - * this is safe to be done before the check because it - * means no deference, just pointer operations. - */ - head = WAIT_QUEUE_HEAD(q); - - read_lock(&waitqueue_lock); - next = *q; - if (!next) - goto out_unlock; - - while (next != head) { - p = next->task; - next = next->next; + + wakeup_calls++; + wq_write_lock_irqsave(&q->lock, flags); + +#if WAITQUEUE_DEBUG + CHECK_MAGIC_WQHEAD(q); +#endif + + head = &q->task_list; +#if WAITQUEUE_DEBUG + if (!head->next || !head->prev) + WQ_BUG(); +#endif + tmp = head->next; + while (tmp != head) { + curr = list_entry(tmp, wait_queue_t, task_list); + + tmp = tmp->next; + +#if WAITQUEUE_DEBUG + CHECK_MAGIC(curr->__magic); +#endif + p = curr->task; if (p->state & mode) { - /* - * We can drop the read-lock early if this - * is the only/last process. - */ - if (next == head) { - read_unlock(&waitqueue_lock); + if (p->state & TASK_EXCLUSIVE) { + __remove_wait_queue(q, curr); + wq_write_unlock_irqrestore(&q->lock, flags); + + wakeup_exclusive_processes++; + curr->task_list.next = NULL; + curr->__waker = 0; wake_up_process(p); goto out; } +#if WAITQUEUE_DEBUG + curr->__waker = (int)__builtin_return_address(0); +#endif + wakeup_normal_processes++; wake_up_process(p); } + if (p->state & TASK_EXCLUSIVE) + break; } -out_unlock: - read_unlock(&waitqueue_lock); + wq_write_unlock_irqrestore(&q->lock, flags); out: return; } @@ -972,7 +983,8 @@ #define DOWN_VAR \ struct task_struct *tsk = current; \ - struct wait_queue wait = { tsk, NULL }; + wait_queue_t wait; \ + init_waitqueue_entry(&wait, tsk); #define DOWN_HEAD(task_state) \ \ @@ -1015,8 +1027,8 @@ int __down_interruptible(struct semaphore * sem) { - DOWN_VAR int ret = 0; + DOWN_VAR DOWN_HEAD(TASK_INTERRUPTIBLE) ret = waking_non_zero_interruptible(sem, tsk); @@ -1039,20 +1051,20 @@ #define SLEEP_ON_VAR \ unsigned long flags; \ - struct wait_queue wait; + wait_queue_t wait; \ + init_waitqueue_entry(&wait, current); #define SLEEP_ON_HEAD \ - wait.task = current; \ - write_lock_irqsave(&waitqueue_lock,flags); \ - __add_wait_queue(p, &wait); \ - write_unlock(&waitqueue_lock); + wq_write_lock_irqsave(&q->lock,flags); \ + __add_wait_queue(q, &wait); \ + wq_write_unlock(&q->lock); #define SLEEP_ON_TAIL \ - write_lock_irq(&waitqueue_lock); \ - __remove_wait_queue(p, &wait); \ - write_unlock_irqrestore(&waitqueue_lock,flags); + wq_write_lock_irq(&q->lock); \ + __remove_wait_queue(q, &wait); \ + wq_write_unlock_irqrestore(&q->lock,flags); -void interruptible_sleep_on(struct wait_queue **p) +void interruptible_sleep_on(wait_queue_head_t *q) { SLEEP_ON_VAR @@ -1063,7 +1075,7 @@ SLEEP_ON_TAIL } -long interruptible_sleep_on_timeout(struct wait_queue **p, long timeout) +long interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout) { SLEEP_ON_VAR @@ -1076,7 +1088,7 @@ return timeout; } -void sleep_on(struct wait_queue **p) +void sleep_on(wait_queue_head_t *q) { SLEEP_ON_VAR @@ -1087,7 +1099,7 @@ SLEEP_ON_TAIL } -long sleep_on_timeout(struct wait_queue **p, long timeout) +long sleep_on_timeout(wait_queue_head_t *q, long timeout) { SLEEP_ON_VAR @@ -1199,8 +1211,8 @@ read_lock(&tasklist_lock); for_each_task(p) { if ((p->state == TASK_RUNNING || - p->state == TASK_UNINTERRUPTIBLE || - p->state == TASK_SWAPPING)) + (p->state & TASK_UNINTERRUPTIBLE) || + (p->state & TASK_SWAPPING))) nr += FIXED_1; } read_unlock(&tasklist_lock); --- linux/kernel/exit.c.orig Mon May 10 22:04:29 1999 +++ linux/kernel/exit.c Mon May 10 22:04:40 1999 @@ -406,7 +406,7 @@ asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru) { int flag, retval; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); struct task_struct *p; if (options & ~(WNOHANG|WUNTRACED|__WCLONE)) --- linux/kernel/fork.c.orig Mon May 10 22:04:22 1999 +++ linux/kernel/fork.c Mon May 10 22:04:40 1999 @@ -303,7 +303,7 @@ atomic_set(&mm->count, 1); mm->map_count = 0; mm->def_flags = 0; - mm->mmap_sem = MUTEX_LOCKED; + init_MUTEX_LOCKED(&mm->mmap_sem); /* * Leave mm->pgd set to the parent's pgd * so that pgd_offset() is always valid. @@ -536,7 +536,7 @@ int nr; int retval = -ENOMEM; struct task_struct *p; - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); current->vfork_sem = &sem; @@ -589,7 +589,7 @@ p->p_pptr = p->p_opptr = current; p->p_cptr = NULL; - init_waitqueue(&p->wait_chldexit); + init_waitqueue_head(&p->wait_chldexit); p->vfork_sem = NULL; p->sigpending = 0; --- linux/kernel/signal.c.orig Mon May 10 22:04:29 1999 +++ linux/kernel/signal.c Mon May 10 22:04:40 1999 @@ -387,7 +387,7 @@ out: spin_unlock_irqrestore(&t->sigmask_lock, flags); - if (t->state == TASK_INTERRUPTIBLE && signal_pending(t)) + if ((t->state & TASK_INTERRUPTIBLE) && signal_pending(t)) wake_up_process(t); out_nolock: --- linux/kernel/printk.c.orig Tue Mar 9 10:03:41 1999 +++ linux/kernel/printk.c Mon May 10 22:13:31 1999 @@ -32,7 +32,7 @@ #define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */ unsigned long log_size = 0; -struct wait_queue * log_wait = NULL; +DECLARE_WAIT_QUEUE_HEAD(log_wait); /* Keep together for sysctl support */ int console_loglevel = DEFAULT_CONSOLE_LOGLEVEL; --- linux/kernel/sys.c.orig Tue Dec 1 11:34:28 1998 +++ linux/kernel/sys.c Mon May 10 22:04:40 1999 @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -812,7 +813,7 @@ * rather than a semaphore. Anybody want to implement * one? */ -struct semaphore uts_sem = MUTEX; +DECLARE_MUTEX(uts_sem); asmlinkage int sys_newuname(struct new_utsname * name) { --- linux/kernel/ksyms.c.orig Tue Apr 6 14:35:09 1999 +++ linux/kernel/ksyms.c Mon May 10 22:04:40 1999 @@ -282,7 +282,6 @@ #ifdef __SMP__ /* Various random spinlocks we want to export */ EXPORT_SYMBOL(tqueue_lock); -EXPORT_SYMBOL(waitqueue_lock); #endif /* autoirq from drivers/net/auto_irq.c */ --- linux/mm/page_alloc.c.orig Mon May 10 22:04:29 1999 +++ linux/mm/page_alloc.c Mon May 10 22:04:40 1999 @@ -323,6 +323,7 @@ --p; atomic_set(&p->count, 0); p->flags = (1 << PG_DMA) | (1 << PG_reserved); + init_waitqueue_head(&p->wait); } while (p > mem_map); for (i = 0 ; i < NR_MEM_LISTS ; i++) { --- linux/mm/filemap.c.orig Mon May 10 22:04:29 1999 +++ linux/mm/filemap.c Mon May 10 22:04:40 1999 @@ -48,7 +48,7 @@ }; static struct pio_request *pio_first = NULL, **pio_last = &pio_first; static kmem_cache_t *pio_request_cache; -static struct wait_queue *pio_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(pio_wait); static inline void make_pio_request(struct file *, unsigned long, unsigned long); @@ -300,9 +300,8 @@ void __wait_on_page(struct page *page) { struct task_struct *tsk = current; - struct wait_queue wait; + DECLARE_WAITQUEUE(wait, tsk); - wait.task = tsk; add_wait_queue(&page->wait, &wait); repeat: tsk->state = TASK_UNINTERRUPTIBLE; @@ -1677,7 +1676,7 @@ int kpiod(void * unused) { struct task_struct *tsk = current; - struct wait_queue wait = { tsk, }; + DECLARE_WAITQUEUE(wait, tsk); struct inode * inode; struct dentry * dentry; struct pio_request * p; @@ -1686,7 +1685,6 @@ tsk->pgrp = 1; strcpy(tsk->comm, "kpiod"); sigfillset(&tsk->blocked); - init_waitqueue(&pio_wait); /* * Mark this task as a memory allocator - we don't want to get caught * up in the regular mm freeing frenzy if we have to allocate memory --- linux/mm/page_io.c.orig Tue Dec 29 15:37:08 1998 +++ linux/mm/page_io.c Mon May 10 22:04:40 1999 @@ -18,7 +18,7 @@ #include -static struct wait_queue * lock_queue = NULL; +static DECLARE_WAIT_QUEUE_HEAD(lock_queue); /* * Reads or writes a swap page. --- linux/mm/slab.c.orig Tue Dec 1 11:34:28 1998 +++ linux/mm/slab.c Mon May 10 22:04:40 1999 @@ -428,7 +428,7 @@ #undef kmem_slab_offset #undef kmem_slab_diff - cache_chain_sem = MUTEX; + init_MUTEX(&cache_chain_sem); size = cache_cache.c_offset + sizeof(kmem_bufctl_t); size += (L1_CACHE_BYTES-1); --- linux/include/linux/lockd/lockd.h.orig Tue Mar 9 10:03:39 1999 +++ linux/include/linux/lockd/lockd.h Mon May 10 22:05:49 1999 @@ -44,7 +44,7 @@ unsigned short h_reclaiming : 1, h_inuse : 1, h_monitored : 1; - struct wait_queue * h_gracewait; /* wait while reclaiming */ + wait_queue_head_t h_gracewait; /* wait while reclaiming */ u32 h_state; /* pseudo-state counter */ u32 h_nsmstate; /* true remote NSM state */ unsigned int h_count; /* reference count */ --- linux/include/linux/sunrpc/sched.h.orig Fri Jan 15 00:01:46 1999 +++ linux/include/linux/sunrpc/sched.h Mon May 10 22:05:42 1999 @@ -12,6 +12,7 @@ #include #include #include +#include /* * Define this if you want to test the fast scheduler for async calls. @@ -63,7 +64,7 @@ * you have a pathological interest in kernel oopses. */ struct timer_list tk_timer; /* kernel timer */ - struct wait_queue * tk_wait; /* sync: sleep on this q */ + wait_queue_head_t tk_wait; /* sync: sleep on this q */ unsigned long tk_timeout; /* timeout for rpc_sleep() */ unsigned short tk_flags; /* misc flags */ #ifdef RPC_DEBUG --- linux/include/linux/sunrpc/svc.h.orig Fri Jan 8 13:31:30 1999 +++ linux/include/linux/sunrpc/svc.h Mon May 10 22:05:47 1999 @@ -116,7 +116,7 @@ struct svc_client * rq_client; /* RPC peer info */ struct svc_cacherep * rq_cacherep; /* cache info */ - struct wait_queue * rq_wait; /* synchronozation */ + wait_queue_head_t rq_wait; /* synchronozation */ }; /* --- linux/include/linux/sched.h.orig Mon May 10 22:04:29 1999 +++ linux/include/linux/sched.h Mon May 10 22:17:57 1999 @@ -79,6 +79,13 @@ #define TASK_ZOMBIE 4 #define TASK_STOPPED 8 #define TASK_SWAPPING 16 +/* + * 'exclusive' tasks are the ones that expect 'wake-one' behavior + * on __wake_up(). They are special because __wake_up() removes + * them from the waitqueue immediately, this way we have O(1) addition, + * scheduling and removal from waitqueues, no matter how long they are. + */ +#define TASK_EXCLUSIVE 32 /* * Scheduling policies @@ -184,11 +191,11 @@ void * segments; }; -#define INIT_MM { \ +#define INIT_MM(name) { \ &init_mmap, NULL, NULL, \ swapper_pg_dir, \ ATOMIC_INIT(1), 1, \ - MUTEX, \ + __MUTEX_INITIALIZER(name.mmap_sem), \ 0, \ 0, 0, 0, 0, \ 0, 0, 0, \ @@ -267,7 +274,7 @@ /* Pointer to task[] array linkage. */ struct task_struct **tarray_ptr; - struct wait_queue *wait_chldexit; /* for wait4() */ + wait_queue_head_t wait_chldexit; /* for wait4() */ struct semaphore *vfork_sem; /* for vfork() */ unsigned long policy, rt_priority; unsigned long it_real_value, it_prof_value, it_virt_value; @@ -345,7 +352,7 @@ * INIT_TASK is used to set up the first task table, touch at * your own risk!. Base=0, limit=0x1fffff (=2MB) */ -#define INIT_TASK \ +#define INIT_TASK(name) \ /* state etc */ { 0,0,0,KERNEL_DS,&default_exec_domain,0, \ /* counter */ DEF_PRIORITY,DEF_PRIORITY,0, \ /* SMP */ 0,0,0,-1, \ @@ -356,7 +363,7 @@ /* proc links*/ &init_task,&init_task,NULL,NULL,NULL, \ /* pidhash */ NULL, NULL, \ /* tarray */ &task[0], \ -/* chld wait */ NULL, NULL, \ +/* chld wait */ __WAIT_QUEUE_HEAD_INITIALIZER(name.wait_chldexit), NULL, \ /* timeout */ SCHED_OTHER,0,0,0,0,0,0,0, \ /* timer */ { NULL, NULL, 0, 0, it_real_fn }, \ /* utime */ {0,0,0,0},0, \ @@ -464,12 +471,12 @@ #define CURRENT_TIME (xtime.tv_sec) -extern void FASTCALL(__wake_up(struct wait_queue ** p, unsigned int mode)); -extern void FASTCALL(sleep_on(struct wait_queue ** p)); -extern long FASTCALL(sleep_on_timeout(struct wait_queue ** p, +extern void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode)); +extern void FASTCALL(sleep_on(wait_queue_head_t *q)); +extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q, signed long timeout)); -extern void FASTCALL(interruptible_sleep_on(struct wait_queue ** p)); -extern long FASTCALL(interruptible_sleep_on_timeout(struct wait_queue ** p, +extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q)); +extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q, signed long timeout)); extern void FASTCALL(wake_up_process(struct task_struct * tsk)); @@ -630,54 +637,39 @@ extern int do_execve(char *, char **, char **, struct pt_regs *); extern int do_fork(unsigned long, unsigned long, struct pt_regs *); -/* - * The wait-queues are circular lists, and you have to be *very* sure - * to keep them correct. Use only these two functions to add/remove - * entries in the queues. - */ -extern inline void __add_wait_queue(struct wait_queue ** p, struct wait_queue * wait) -{ - wait->next = *p ? : WAIT_QUEUE_HEAD(p); - *p = wait; -} - -extern rwlock_t waitqueue_lock; - -extern inline void add_wait_queue(struct wait_queue ** p, struct wait_queue * wait) +extern inline void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait) { unsigned long flags; - write_lock_irqsave(&waitqueue_lock, flags); - __add_wait_queue(p, wait); - write_unlock_irqrestore(&waitqueue_lock, flags); + wq_write_lock_irqsave(&q->lock, flags); + __add_wait_queue(q, wait); + wq_write_unlock_irqrestore(&q->lock, flags); } -extern inline void __remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait) +extern inline void add_wait_queue_exclusive(wait_queue_head_t *q, + wait_queue_t * wait) { - struct wait_queue * next = wait->next; - struct wait_queue * head = next; - struct wait_queue * tmp; + unsigned long flags; - while ((tmp = head->next) != wait) { - head = tmp; - } - head->next = next; + wq_write_lock_irqsave(&q->lock, flags); + __add_wait_queue_tail(q, wait); + wq_write_unlock_irqrestore(&q->lock, flags); } -extern inline void remove_wait_queue(struct wait_queue ** p, struct wait_queue * wait) +extern inline void remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait) { unsigned long flags; - write_lock_irqsave(&waitqueue_lock, flags); - __remove_wait_queue(p, wait); - write_unlock_irqrestore(&waitqueue_lock, flags); + wq_write_lock_irqsave(&q->lock, flags); + __remove_wait_queue(q, wait); + wq_write_unlock_irqrestore(&q->lock, flags); } #define __wait_event(wq, condition) \ do { \ - struct wait_queue __wait; \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ \ - __wait.task = current; \ add_wait_queue(&wq, &__wait); \ for (;;) { \ current->state = TASK_UNINTERRUPTIBLE; \ @@ -698,9 +690,9 @@ #define __wait_event_interruptible(wq, condition, ret) \ do { \ - struct wait_queue __wait; \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ \ - __wait.task = current; \ add_wait_queue(&wq, &__wait); \ for (;;) { \ current->state = TASK_INTERRUPTIBLE; \ --- linux/include/linux/tty.h.orig Fri Jan 15 00:02:22 1999 +++ linux/include/linux/tty.h Mon May 10 22:05:29 1999 @@ -272,8 +272,8 @@ struct tty_flip_buffer flip; int max_flip_cnt; int alt_speed; /* For magic substitution of 38400 bps */ - struct wait_queue *write_wait; - struct wait_queue *read_wait; + wait_queue_head_t write_wait; + wait_queue_head_t read_wait; struct tq_struct tq_hangup; void *disc_data; void *driver_data; --- linux/include/linux/fs.h.orig Mon May 10 22:04:29 1999 +++ linux/include/linux/fs.h Mon May 10 22:05:29 1999 @@ -213,7 +213,7 @@ unsigned int b_list; /* List that this buffer appears */ unsigned long b_flushtime; /* Time when this (dirty) buffer * should be written */ - struct wait_queue * b_wait; + wait_queue_head_t b_wait; struct buffer_head ** b_pprev; /* doubly linked list of hash-queue */ struct buffer_head * b_prev_free; /* doubly linked list of buffers */ struct buffer_head * b_reqnext; /* request queue */ @@ -353,7 +353,7 @@ struct semaphore i_atomic_write; struct inode_operations *i_op; struct super_block *i_sb; - struct wait_queue *i_wait; + wait_queue_head_t i_wait; struct file_lock *i_flock; struct vm_area_struct *i_mmap; struct page *i_pages; @@ -453,7 +453,7 @@ struct file_lock *fl_prevblock; fl_owner_t fl_owner; unsigned int fl_pid; - struct wait_queue *fl_wait; + wait_queue_head_t fl_wait; struct file *fl_file; unsigned char fl_flags; unsigned char fl_type; @@ -529,7 +529,7 @@ unsigned long s_magic; unsigned long s_time; struct dentry *s_root; - struct wait_queue *s_wait; + wait_queue_head_t s_wait; struct inode *s_ibasket; short int s_ibasket_count; --- linux/include/linux/mm.h.orig Tue Mar 9 10:03:41 1999 +++ linux/include/linux/mm.h Mon May 10 22:18:06 1999 @@ -126,7 +126,7 @@ struct page *next_hash; atomic_t count; unsigned long flags; /* atomic flags, some possibly updated asynchronously */ - struct wait_queue *wait; + wait_queue_head_t wait; struct page **pprev_hash; struct buffer_head * buffers; } mem_map_t; --- linux/include/linux/wait.h.orig Thu Apr 9 01:06:07 1998 +++ linux/include/linux/wait.h Mon May 10 22:04:40 1999 @@ -9,23 +9,189 @@ #ifdef __KERNEL__ #include +#include +#include +#include -struct wait_queue { +/* + * Temporary debugging help until all code is converted to the new + * waitqueue usage. + */ +#define WAITQUEUE_DEBUG 1 + +#if WAITQUEUE_DEBUG +extern int printk(const char *fmt, ...); +#define WQ_BUG() do { \ + printk("wq bug, forcing oops.\n"); \ + *(int*)0 = 0; \ +} while (0) + +#define CHECK_MAGIC(x) if (x != (int)&(x)) \ + { printk("bad magic %08x (should be %08x), ", x, (int)&(x)); WQ_BUG(); } + +#define CHECK_MAGIC_WQHEAD(x) do { \ + if (x->__magic != (int)&(x->__magic)) { \ + printk("bad magic %08x (should be %08x, creator %08x), ", \ + x->__magic, (int)&(x->__magic), x->__creator); \ + WQ_BUG(); \ + } \ +} while (0) +#endif + +struct __wait_queue { struct task_struct * task; - struct wait_queue * next; + struct list_head task_list; +#if WAITQUEUE_DEBUG + int __magic; + int __waker; +#endif }; +typedef struct __wait_queue wait_queue_t; + +/* + * 'dual' spinlock architecture. Can be switched between spinlock_t and + * rwlock_t locks via changing this define. Since waitqueues are quite + * decoupled in the new architecture, lightweight 'simple' spinlocks give + * us slightly better latencies and smaller waitqueue structure size. + */ +#define USE_RW_WAIT_QUEUE_SPINLOCK 0 + +#if USE_RW_WAIT_QUEUE_SPINLOCK +# define wq_lock_t rwlock_t +# define WAITQUEUE_RW_LOCK_UNLOCKED RW_LOCK_UNLOCKED + +# define wq_read_lock read_lock +# define wq_read_lock_irqsave read_lock_irqsave +# define wq_read_unlock_irqrestore read_unlock_irqrestore +# define wq_read_unlock read_unlock +# define wq_write_lock_irq write_lock_irq +# define wq_write_lock_irqsave write_lock_irqsave +# define wq_write_unlock_irqrestore write_unlock_irqrestore +# define wq_write_unlock write_unlock +#else +# define wq_lock_t spinlock_t +# define WAITQUEUE_RW_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED + +# define wq_read_lock spin_lock +# define wq_read_lock_irqsave spin_lock_irqsave +# define wq_read_unlock spin_unlock +# define wq_read_unlock_irqrestore spin_unlock_irqrestore +# define wq_write_lock_irq spin_lock_irq +# define wq_write_lock_irqsave spin_lock_irqsave +# define wq_write_unlock_irqrestore spin_unlock_irqrestore +# define wq_write_unlock spin_unlock +#endif + +struct __wait_queue_head { + wq_lock_t lock; + struct list_head task_list; +#if WAITQUEUE_DEBUG + int __magic; + int __creator; +#endif +}; +typedef struct __wait_queue_head wait_queue_head_t; + +#if WAITQUEUE_DEBUG +# define __WAITQUEUE_DEBUG_INIT(name) \ + , (int)&(name).__magic, 0 +# define __WAITQUEUE_HEAD_DEBUG_INIT(name) \ + , (int)&(name).__magic, (int)&(name).__magic +#else +# define __WAITQUEUE_DEBUG_INIT(name) +# define __WAITQUEUE_HEAD_DEBUG_INIT(name) +#endif + +#define __WAITQUEUE_INITIALIZER(name,task) \ + { task, { NULL, NULL } __WAITQUEUE_DEBUG_INIT(name)} +#define DECLARE_WAITQUEUE(name,task) \ + wait_queue_t name = __WAITQUEUE_INITIALIZER(name,task) + +#define __WAIT_QUEUE_HEAD_INITIALIZER(name) \ +{ WAITQUEUE_RW_LOCK_UNLOCKED, { &(name).task_list, &(name).task_list } \ + __WAITQUEUE_HEAD_DEBUG_INIT(name)} -#define WAIT_QUEUE_HEAD(x) ((struct wait_queue *)((x)-1)) +#define DECLARE_WAIT_QUEUE_HEAD(name) \ + wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) + +static inline void init_waitqueue_head(wait_queue_head_t *q) +{ +#if WAITQUEUE_DEBUG + __label__ __x; + if (!q) + WQ_BUG(); +#endif + q->lock = WAITQUEUE_RW_LOCK_UNLOCKED; + INIT_LIST_HEAD(&q->task_list); +#if WAITQUEUE_DEBUG + q->__magic = (int)&q->__magic; + __x: q->__creator = (int)&&__x; +#endif +} + +static inline void init_waitqueue_entry(wait_queue_t *q, + struct task_struct *p) +{ +#if WAITQUEUE_DEBUG + if (!q || !p) + WQ_BUG(); +#endif + q->task = p; +#if WAITQUEUE_DEBUG + q->__magic = (int)&q->__magic; +#endif +} + +static inline int waitqueue_active(wait_queue_head_t *q) +{ +#if WAITQUEUE_DEBUG + if (!q) + WQ_BUG(); + CHECK_MAGIC_WQHEAD(q); +#endif + + return !list_empty(&q->task_list); +} + +extern inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new) +{ +#if WAITQUEUE_DEBUG + if (!head || !new) + WQ_BUG(); + CHECK_MAGIC_WQHEAD(head); + CHECK_MAGIC(new->__magic); + if (!head->task_list.next || !head->task_list.prev) + WQ_BUG(); +#endif + list_add(&new->task_list, &head->task_list); +} -static inline void init_waitqueue(struct wait_queue **q) +/* + * Used for wake-one threads: + */ +extern inline void __add_wait_queue_tail(wait_queue_head_t *head, + wait_queue_t *new) { - *q = WAIT_QUEUE_HEAD(q); +#if WAITQUEUE_DEBUG + if (!head || !new) + WQ_BUG(); + CHECK_MAGIC_WQHEAD(head); + CHECK_MAGIC(new->__magic); + if (!head->task_list.next || !head->task_list.prev) + WQ_BUG(); +#endif + list_add(&new->task_list, head->task_list.prev); } -static inline int waitqueue_active(struct wait_queue **q) +extern inline void __remove_wait_queue(wait_queue_head_t *head, + wait_queue_t *old) { - struct wait_queue *head = *q; - return head && head != WAIT_QUEUE_HEAD(q); +#if WAITQUEUE_DEBUG + if (!old) + WQ_BUG(); + CHECK_MAGIC(old->__magic); +#endif + list_del(&old->task_list); } #endif /* __KERNEL__ */ --- linux/include/linux/pipe_fs_i.h.orig Wed Jul 16 17:26:21 1997 +++ linux/include/linux/pipe_fs_i.h Mon May 10 22:04:40 1999 @@ -2,7 +2,7 @@ #define _LINUX_PIPE_FS_I_H struct pipe_inode_info { - struct wait_queue * wait; + wait_queue_head_t wait; char * base; unsigned int start; unsigned int lock; --- linux/include/linux/keyboard.h.orig Thu Aug 6 10:02:19 1998 +++ linux/include/linux/keyboard.h Mon May 10 22:04:40 1999 @@ -1,6 +1,8 @@ #ifndef __LINUX_KEYBOARD_H #define __LINUX_KEYBOARD_H +#include + #define KG_SHIFT 0 #define KG_CTRL 2 #define KG_ALT 3 @@ -24,7 +26,7 @@ extern const int max_vals[]; extern unsigned short *key_maps[MAX_NR_KEYMAPS]; extern unsigned short plain_map[NR_KEYS]; -extern struct wait_queue * keypress_wait; +extern wait_queue_head_t keypress_wait; extern unsigned char keyboard_type; #endif --- linux/include/linux/nfs_fs.h.orig Mon May 10 22:04:29 1999 +++ linux/include/linux/nfs_fs.h Mon May 10 22:18:25 1999 @@ -100,7 +100,7 @@ struct rpc_task wb_task; /* RPC task */ struct file * wb_file; /* dentry referenced */ struct page * wb_page; /* page to be written */ - struct wait_queue * wb_wait; /* wait for completion */ + wait_queue_head_t wb_wait; /* wait for completion */ unsigned int wb_offset; /* offset within page */ unsigned int wb_bytes; /* dirty range */ unsigned int wb_count; /* user count */ --- linux/include/linux/net.h.orig Mon Jan 11 04:08:03 1999 +++ linux/include/linux/net.h Mon May 10 22:04:40 1999 @@ -19,6 +19,7 @@ #define _LINUX_NET_H #include +#include struct poll_table_struct; @@ -68,7 +69,7 @@ struct fasync_struct *fasync_list; /* Asynchronous wake up list */ struct file *file; /* File back pointer for gc */ struct sock *sk; - struct wait_queue *wait; + wait_queue_head_t wait; short type; unsigned char passcred; --- linux/include/linux/sem.h.orig Mon Jan 11 04:08:03 1999 +++ linux/include/linux/sem.h Mon May 10 22:04:40 1999 @@ -85,7 +85,7 @@ struct sem_queue { struct sem_queue * next; /* next entry in the queue */ struct sem_queue ** prev; /* previous entry in the queue, *(q->prev) == q */ - struct wait_queue * sleeper; /* sleeping process */ + wait_queue_head_t sleeper; /* sleeping process */ struct sem_undo * undo; /* undo structure */ int pid; /* process id of requesting process */ int status; /* completion status of operation */ --- linux/include/linux/msg.h.orig Mon Jan 11 04:08:45 1999 +++ linux/include/linux/msg.h Mon May 10 22:04:40 1999 @@ -19,8 +19,8 @@ __kernel_time_t msg_stime; /* last msgsnd time */ __kernel_time_t msg_rtime; /* last msgrcv time */ __kernel_time_t msg_ctime; /* last change time */ - struct wait_queue *wwait; - struct wait_queue *rwait; + wait_queue_head_t wwait; + wait_queue_head_t rwait; unsigned short msg_cbytes; /* current number of bytes on queue */ unsigned short msg_qnum; /* number of messages in queue */ unsigned short msg_qbytes; /* max number of bytes on queue */ --- linux/include/linux/poll.h.orig Tue Jan 26 09:47:12 1999 +++ linux/include/linux/poll.h Mon May 10 22:18:23 1999 @@ -13,8 +13,8 @@ struct poll_table_entry { struct file * filp; - struct wait_queue wait; - struct wait_queue ** wait_address; + wait_queue_t wait; + wait_queue_head_t * wait_address; }; typedef struct poll_table_struct { @@ -25,9 +25,9 @@ #define __MAX_POLL_TABLE_ENTRIES ((PAGE_SIZE - sizeof (poll_table)) / sizeof (struct poll_table_entry)) -extern void __pollwait(struct file * filp, struct wait_queue ** wait_address, poll_table *p); +extern void __pollwait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p); -extern inline void poll_wait(struct file * filp, struct wait_queue ** wait_address, poll_table *p) +extern inline void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p) { if (p && wait_address) __pollwait(filp, wait_address, p); --- linux/include/linux/blkdev.h.orig Fri Jan 15 00:02:22 1999 +++ linux/include/linux/blkdev.h Mon May 10 22:18:06 1999 @@ -55,7 +55,7 @@ extern struct sec_size * blk_sec[MAX_BLKDEV]; extern struct blk_dev_struct blk_dev[MAX_BLKDEV]; -extern struct wait_queue * wait_for_request; +extern wait_queue_head_t wait_for_request; extern void resetup_one_dev(struct gendisk *dev, int drive); extern void unplug_device(void * data); extern void make_request(int major,int rw, struct buffer_head * bh); --- linux/include/linux/vt_kern.h.orig Mon Jan 11 04:08:04 1999 +++ linux/include/linux/vt_kern.h Mon May 10 22:04:40 1999 @@ -27,7 +27,7 @@ struct vt_mode vt_mode; int vt_pid; int vt_newvt; - struct wait_queue *paste_wait; + wait_queue_head_t paste_wait; } *vt_cons[MAX_NR_CONSOLES]; void (*kd_mksound)(unsigned int hz, unsigned int ticks); --- linux/include/linux/rtnetlink.h.orig Tue Apr 6 14:35:09 1999 +++ linux/include/linux/rtnetlink.h Mon May 10 22:04:40 1999 @@ -511,7 +511,7 @@ #ifdef __KERNEL__ extern atomic_t rtnl_rlockct; -extern struct wait_queue *rtnl_wait; +extern wait_queue_head_t rtnl_wait; extern __inline__ int rtattr_strcmp(struct rtattr *rta, char *str) { --- linux/include/linux/serialP.h.orig Fri Jan 15 00:02:22 1999 +++ linux/include/linux/serialP.h Mon May 10 22:05:29 1999 @@ -80,9 +80,9 @@ int xmit_tail; int xmit_cnt; struct tq_struct tqueue; - struct wait_queue *open_wait; - struct wait_queue *close_wait; - struct wait_queue *delta_msr_wait; + wait_queue_head_t open_wait; + wait_queue_head_t close_wait; + wait_queue_head_t delta_msr_wait; struct async_struct *next_port; /* For the linked list */ struct async_struct *prev_port; }; --- linux/include/linux/hfs_sysdep.h.orig Fri Jan 15 00:04:14 1999 +++ linux/include/linux/hfs_sysdep.h Mon May 10 22:19:21 1999 @@ -93,10 +93,10 @@ /* * hfs_wait_queue */ -typedef struct wait_queue *hfs_wait_queue; +typedef wait_queue_head_t hfs_wait_queue; extern inline void hfs_init_waitqueue(hfs_wait_queue *queue) { - init_waitqueue(queue); + init_waitqueue_head(queue); } extern inline void hfs_sleep_on(hfs_wait_queue *queue) { --- linux/include/asm-i386/semaphore.h.orig Tue Mar 9 10:03:39 1999 +++ linux/include/asm-i386/semaphore.h Mon May 10 22:04:40 1999 @@ -27,15 +27,62 @@ #include #include #include +#include struct semaphore { atomic_t count; int waking; - struct wait_queue * wait; + wait_queue_head_t wait; +#if WAITQUEUE_DEBUG + int __magic; +#endif }; -#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), 0, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), 0, NULL }) +#if WAITQUEUE_DEBUG +# define __SEM_DEBUG_INIT(name) \ + , (int)&(name).__magic +#else +# define __SEM_DEBUG_INIT(name) +#endif + +#define __SEMAPHORE_INITIALIZER(name,count) \ +{ ATOMIC_INIT(count), 0, __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ + __SEM_DEBUG_INIT(name) } + +#define __MUTEX_INITIALIZER(name) \ + __SEMAPHORE_INITIALIZER(name,1) + +#define __DECLARE_SEMAPHORE_GENERIC(name,count) \ + struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) + +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) +#define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) + +extern inline void sema_init (struct semaphore *sem, int val) +{ +/* + * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val); + * + * i'd rather use the more flexible initialization above, but sadly + * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well. + */ + atomic_set(&sem->count, val); + sem->waking = 0; + init_waitqueue_head(&sem->wait); +#if WAITQUEUE_DEBUG + sem->__magic = (int)&sem->__magic; +#endif +} + +static inline void init_MUTEX (struct semaphore *sem) +{ + sema_init(sem, 1); +} + +static inline void init_MUTEX_LOCKED (struct semaphore *sem) +{ + sema_init(sem, 0); +} asmlinkage void __down_failed(void /* special register calling convention */); asmlinkage int __down_failed_interruptible(void /* params in registers */); @@ -49,8 +96,6 @@ extern spinlock_t semaphore_wake_lock; -#define sema_init(sem, val) atomic_set(&((sem)->count), (val)) - /* * This is ugly, but we want the default case to fall through. * "down_failed" is a special asm handler that calls the C @@ -58,6 +103,10 @@ */ extern inline void down(struct semaphore * sem) { +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + __asm__ __volatile__( "# atomic down operation\n\t" #ifdef __SMP__ @@ -79,6 +128,10 @@ { int result; +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + __asm__ __volatile__( "# atomic interruptible down operation\n\t" #ifdef __SMP__ @@ -102,6 +155,10 @@ { int result; +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif + __asm__ __volatile__( "# atomic interruptible down operation\n\t" #ifdef __SMP__ @@ -129,6 +186,9 @@ */ extern inline void up(struct semaphore * sem) { +#if WAITQUEUE_DEBUG + CHECK_MAGIC(sem->__magic); +#endif __asm__ __volatile__( "# atomic up operation\n\t" #ifdef __SMP__ --- linux/include/net/sock.h.orig Mon May 10 22:04:25 1999 +++ linux/include/net/sock.h Mon May 10 22:18:24 1999 @@ -384,7 +384,7 @@ atomic_t sock_readers; /* User count */ int rcvbuf; /* Size of receive buffer in bytes */ - struct wait_queue **sleep; /* Sock wait queue */ + wait_queue_head_t *sleep; /* Sock wait queue */ struct dst_entry *dst_cache; /* Destination cache */ atomic_t rmem_alloc; /* Receive queue bytes committed */ struct sk_buff_head receive_queue; /* Incoming packets */ --- linux/net/unix/af_unix.c.orig Mon May 10 22:04:29 1999 +++ linux/net/unix/af_unix.c Mon May 10 22:04:40 1999 @@ -114,8 +114,8 @@ unix_socket *unix_socket_table[UNIX_HASH_SIZE+1]; static atomic_t unix_nr_socks = ATOMIC_INIT(0); -static struct wait_queue * unix_ack_wqueue = NULL; -static struct wait_queue * unix_dgram_wqueue = NULL; +static DECLARE_WAIT_QUEUE_HEAD(unix_ack_wqueue); +static DECLARE_WAIT_QUEUE_HEAD(unix_dgram_wqueue); #define unix_sockets_unbound (unix_socket_table[UNIX_HASH_SIZE]) @@ -433,7 +433,7 @@ sk->destruct = unix_destruct_addr; sk->protinfo.af_unix.family=PF_UNIX; sk->protinfo.af_unix.dentry=NULL; - sk->protinfo.af_unix.readsem=MUTEX; /* single task reading lock */ + init_MUTEX(&sk->protinfo.af_unix.readsem);/* single task reading lock */ sk->protinfo.af_unix.list=&unix_sockets_unbound; unix_insert_socket(sk); --- linux/net/core/datagram.c.orig Thu Oct 29 23:17:48 1998 +++ linux/net/core/datagram.c Mon May 10 22:04:40 1999 @@ -54,7 +54,7 @@ static inline void wait_for_packet(struct sock * sk) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); add_wait_queue(sk->sleep, &wait); current->state = TASK_INTERRUPTIBLE; --- linux/net/core/sock.c.orig Mon May 10 22:04:29 1999 +++ linux/net/core/sock.c Mon May 10 22:04:40 1999 @@ -650,7 +650,7 @@ */ static void sock_wait_for_wmem(struct sock * sk) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); sk->socket->flags &= ~SO_NOSPACE; add_wait_queue(sk->sleep, &wait); @@ -1036,7 +1036,8 @@ sk->type = sock->type; sk->sleep = &sock->wait; sock->sk = sk; - } + } else + sk->sleep = NULL; sk->state_change = sock_def_wakeup; sk->data_ready = sock_def_readable; --- linux/net/core/rtnetlink.c.orig Tue Apr 6 14:35:09 1999 +++ linux/net/core/rtnetlink.c Mon May 10 22:04:40 1999 @@ -51,7 +51,7 @@ #include atomic_t rtnl_rlockct; -struct wait_queue *rtnl_wait; +DECLARE_WAIT_QUEUE_HEAD(rtnl_wait); void rtnl_lock() --- linux/net/ipv4/af_inet.c.orig Mon May 10 22:04:25 1999 +++ linux/net/ipv4/af_inet.c Mon May 10 22:04:40 1999 @@ -578,7 +578,7 @@ static void inet_wait_for_connect(struct sock *sk) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); add_wait_queue(sk->sleep, &wait); current->state = TASK_INTERRUPTIBLE; --- linux/net/ipv4/icmp.c.orig Tue Apr 6 14:35:09 1999 +++ linux/net/ipv4/icmp.c Mon May 10 22:04:40 1999 @@ -1142,6 +1142,8 @@ icmp_inode.i_sock = 1; icmp_inode.i_uid = 0; icmp_inode.i_gid = 0; + init_waitqueue_head(&icmp_inode.i_wait); + init_waitqueue_head(&icmp_inode.u.socket_i.wait); icmp_socket->inode = &icmp_inode; icmp_socket->state = SS_UNCONNECTED; --- linux/net/ipv4/tcp.c.orig Mon May 10 22:04:25 1999 +++ linux/net/ipv4/tcp.c Tue May 11 12:47:49 1999 @@ -660,7 +660,7 @@ static int wait_for_tcp_connect(struct sock * sk, int flags) { struct task_struct *tsk = current; - struct wait_queue wait = { tsk, NULL }; + DECLARE_WAITQUEUE(wait, tsk); while((1 << sk->state) & ~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT)) { if(sk->err) @@ -703,7 +703,7 @@ { release_sock(sk); if (!tcp_memory_free(sk)) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); sk->socket->flags &= ~SO_NOSPACE; add_wait_queue(sk->sleep, &wait); @@ -1117,7 +1117,7 @@ int len, int nonblock, int flags, int *addr_len) { struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); int copied = 0; u32 peek_seq; volatile u32 *seq; /* So gcc doesn't overoptimise */ @@ -1534,7 +1534,7 @@ if (timeout) { struct task_struct *tsk = current; - struct wait_queue wait = { tsk, NULL }; + DECLARE_WAITQUEUE(wait, current); add_wait_queue(sk->sleep, &wait); release_sock(sk); @@ -1570,12 +1570,18 @@ static struct open_request * wait_for_connect(struct sock * sk, struct open_request **pprev) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); struct open_request *req; - add_wait_queue(sk->sleep, &wait); + /* + * True wake-one mechanism for incoming connections: only + * one process gets woken up, not the 'whole herd'. + * Since we do not 'race & poll' for established sockets + * anymore, the common case will execute the loop only once. + */ for (;;) { - current->state = TASK_INTERRUPTIBLE; + add_wait_queue_exclusive(sk->sleep, &wait); + current->state = TASK_EXCLUSIVE | TASK_INTERRUPTIBLE; release_sock(sk); schedule(); lock_sock(sk); @@ -1586,7 +1592,19 @@ break; } current->state = TASK_RUNNING; - remove_wait_queue(sk->sleep, &wait); +#if WAITQUEUE_DEBUG + /* + * hm, gotta do something about 'mixed mode' waitqueues. Eg. + * if we get a signal above then we are not removed from the + * waitqueue... Maybe wake_up_process() could leave the + * TASK_EXCLUSIVE flag intact if it was a true wake-one? + */ + if (wait.task_list.next) { + if (wait.__waker) + printk("<%08x>", wait.__waker); + remove_wait_queue(sk->sleep, &wait); + } +#endif return req; } --- linux/net/ipv4/tcp_ipv4.c.orig Mon May 10 22:55:16 1999 +++ linux/net/ipv4/tcp_ipv4.c Mon May 10 22:55:37 1999 @@ -1944,6 +1944,8 @@ tcp_inode.i_sock = 1; tcp_inode.i_uid = 0; tcp_inode.i_gid = 0; + init_waitqueue_head(&tcp_inode.i_wait); + init_waitqueue_head(&tcp_inode.u.socket_i.wait); tcp_socket->inode = &tcp_inode; tcp_socket->state = SS_UNCONNECTED; --- linux/net/sunrpc/clnt.c.orig Thu Oct 29 23:18:02 1998 +++ linux/net/sunrpc/clnt.c Mon May 10 22:04:40 1999 @@ -39,7 +39,7 @@ # define RPCDBG_FACILITY RPCDBG_CALL #endif -static struct wait_queue * destroy_wait = NULL; +static DECLARE_WAIT_QUEUE_HEAD(destroy_wait); static void call_bind(struct rpc_task *task); --- linux/net/sunrpc/svcsock.c.orig Mon May 10 22:04:29 1999 +++ linux/net/sunrpc/svcsock.c Mon May 10 22:04:40 1999 @@ -738,7 +738,7 @@ { struct svc_sock *svsk; int len; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); dprintk("svc: server %p waiting for data (to = %ld)\n", rqstp, timeout); --- linux/net/sunrpc/sched.c.orig Mon May 10 22:04:29 1999 +++ linux/net/sunrpc/sched.c Mon May 10 22:04:40 1999 @@ -60,9 +60,9 @@ /* * rpciod-related stuff */ -static struct wait_queue * rpciod_idle = NULL; -static struct wait_queue * rpciod_killer = NULL; -static struct semaphore rpciod_sema = MUTEX; +static DECLARE_WAIT_QUEUE_HEAD(rpciod_idle); +static DECLARE_WAIT_QUEUE_HEAD(rpciod_killer); +static DECLARE_MUTEX(rpciod_sema); static unsigned int rpciod_users = 0; static pid_t rpciod_pid = 0; static int rpc_inhibit = 0; @@ -616,6 +616,7 @@ task->tk_client = clnt; task->tk_flags = RPC_TASK_RUNNING | flags; task->tk_exit = callback; + init_waitqueue_head(&task->tk_wait); if (current->uid != current->fsuid || current->gid != current->fsgid) task->tk_flags |= RPC_TASK_SETUID; @@ -800,7 +801,7 @@ rpc_inhibit--; } -static struct semaphore rpciod_running = MUTEX_LOCKED; +static DECLARE_MUTEX_LOCKED(rpciod_running); /* * This is the rpciod kernel thread @@ -808,7 +809,7 @@ static int rpciod(void *ptr) { - struct wait_queue **assassin = (struct wait_queue **) ptr; + wait_queue_head_t *assassin = (wait_queue_head_t*) ptr; unsigned long oldflags; int rounds = 0; --- linux/net/socket.c.orig Mon May 10 22:04:26 1999 +++ linux/net/socket.c Mon May 10 22:04:40 1999 @@ -283,7 +283,7 @@ inode->i_gid = current->fsgid; sock->inode = inode; - init_waitqueue(&sock->wait); + init_waitqueue_head(&sock->wait); sock->fasync_list = NULL; sock->state = SS_UNCONNECTED; sock->flags = 0; --- linux/ipc/msg.c.orig Tue Dec 1 11:34:28 1998 +++ linux/ipc/msg.c Mon May 10 22:04:40 1999 @@ -30,7 +30,7 @@ static unsigned short msg_seq = 0; static int used_queues = 0; static int max_msqid = 0; -static struct wait_queue *msg_lock = NULL; +static DECLARE_WAIT_QUEUE_HEAD(msg_lock); void __init msg_init (void) { @@ -39,7 +39,7 @@ for (id = 0; id < MSGMNI; id++) msgque[id] = (struct msqid_ds *) IPC_UNUSED; msgbytes = msghdrs = msg_seq = max_msqid = used_queues = 0; - msg_lock = NULL; + init_waitqueue_head(&msg_lock); return; } @@ -284,7 +284,8 @@ ipcp->gid = ipcp->cgid = current->egid; msq->msg_perm.seq = msg_seq; msq->msg_first = msq->msg_last = NULL; - msq->rwait = msq->wwait = NULL; + init_waitqueue_head(&msq->wwait); + init_waitqueue_head(&msq->rwait); msq->msg_cbytes = msq->msg_qnum = 0; msq->msg_lspid = msq->msg_lrpid = 0; msq->msg_stime = msq->msg_rtime = 0; --- linux/ipc/sem.c.orig Thu Jan 14 13:38:55 1999 +++ linux/ipc/sem.c Mon May 10 22:04:40 1999 @@ -63,7 +63,7 @@ static struct semid_ds *semary[SEMMNI]; static int used_sems = 0, used_semids = 0; -static struct wait_queue *sem_lock = NULL; +static DECLARE_WAIT_QUEUE_HEAD(sem_lock); static int max_semid = 0; static unsigned short sem_seq = 0; @@ -72,7 +72,7 @@ { int i; - sem_lock = NULL; + init_waitqueue_head(&sem_lock); used_sems = used_semids = max_semid = sem_seq = 0; for (i = 0; i < SEMMNI; i++) semary[i] = (struct semid_ds *) IPC_UNUSED; @@ -690,7 +690,7 @@ for (;;) { queue.status = -EINTR; - queue.sleeper = NULL; + init_waitqueue_head(&queue.sleeper); interruptible_sleep_on(&queue.sleeper); /* --- linux/ipc/shm.c.orig Mon May 10 22:04:29 1999 +++ linux/ipc/shm.c Mon May 10 22:04:40 1999 @@ -31,7 +31,7 @@ static int shm_rss = 0; /* number of shared memory pages that are in memory */ static int shm_swp = 0; /* number of shared memory pages that are in swap */ static int max_shmid = 0; /* every used id is <= max_shmid */ -static struct wait_queue *shm_lock = NULL; /* calling findkey() may need to wait */ +static DECLARE_WAIT_QUEUE_HEAD(shm_lock); /* calling findkey() may need to wait */ static struct shmid_kernel *shm_segs[SHMMNI]; static unsigned short shm_seq = 0; /* incremented, for recognizing stale ids */ @@ -48,7 +48,7 @@ for (id = 0; id < SHMMNI; id++) shm_segs[id] = (struct shmid_kernel *) IPC_UNUSED; shm_tot = shm_rss = shm_seq = max_shmid = used_segs = 0; - shm_lock = NULL; + init_waitqueue_head(&shm_lock); return; } --- linux/drivers/block/ll_rw_blk.c.orig Tue Apr 6 14:35:07 1999 +++ linux/drivers/block/ll_rw_blk.c Mon May 10 22:04:40 1999 @@ -53,7 +53,7 @@ /* * used to wait on when there are no free requests */ -struct wait_queue * wait_for_request = NULL; +DECLARE_WAIT_QUEUE_HEAD(wait_for_request); /* This specifies how many sectors to read ahead on the disk. */ @@ -208,7 +208,7 @@ static struct request * __get_request_wait(int n, kdev_t dev) { register struct request *req; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long flags; add_wait_queue(&wait_for_request, &wait); --- linux/drivers/block/rd.c.orig Mon May 10 22:04:27 1999 +++ linux/drivers/block/rd.c Mon May 10 22:04:40 1999 @@ -482,6 +482,7 @@ memset(&inode, 0, sizeof(inode)); memset(&in_dentry, 0, sizeof(in_dentry)); inode.i_rdev = device; + init_waitqueue_head(&inode.i_wait); infile.f_mode = 1; /* read only */ infile.f_dentry = &in_dentry; in_dentry.d_inode = &inode; @@ -490,6 +491,7 @@ memset(&out_inode, 0, sizeof(out_inode)); memset(&out_dentry, 0, sizeof(out_dentry)); out_inode.i_rdev = ram_device; + init_waitqueue_head(&out_inode.i_wait); outfile.f_mode = 3; /* read/write */ outfile.f_dentry = &out_dentry; out_dentry.d_inode = &out_inode; --- linux/drivers/char/keyboard.c.orig Mon May 10 22:04:23 1999 +++ linux/drivers/char/keyboard.c Mon May 10 22:04:40 1999 @@ -64,7 +64,7 @@ extern void ctrl_alt_del(void); -struct wait_queue * keypress_wait = NULL; +DECLARE_WAIT_QUEUE_HEAD(keypress_wait); struct console; int keyboard_wait_for_keypress(struct console *co) --- linux/drivers/char/console.c.orig Tue Apr 6 14:35:07 1999 +++ linux/drivers/char/console.c Mon May 10 22:04:40 1999 @@ -2269,7 +2269,7 @@ def_color = 0x07; /* white */ ulcolor = 0x0f; /* bold white */ halfcolor = 0x08; /* grey */ - vt_cons[currcons]->paste_wait = 0; + init_waitqueue_head(&vt_cons[currcons]->paste_wait); reset_terminal(currcons, do_clear); } --- linux/drivers/char/tty_ioctl.c.orig Tue Jan 26 09:47:12 1999 +++ linux/drivers/char/tty_ioctl.c Mon May 10 22:04:40 1999 @@ -42,7 +42,7 @@ void tty_wait_until_sent(struct tty_struct * tty, long timeout) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); #ifdef TTY_DEBUG_WAIT_UNTIL_SENT char buf[64]; --- linux/drivers/char/tty_io.c.orig Tue Apr 6 14:35:07 1999 +++ linux/drivers/char/tty_io.c Mon May 10 22:04:40 1999 @@ -729,7 +729,7 @@ } /* Semaphore to protect creating and releasing a tty */ -static struct semaphore tty_sem = MUTEX; +static DECLARE_MUTEX(tty_sem); static void down_tty_sem(int index) { @@ -1930,7 +1930,9 @@ tty->flip.flag_buf_ptr = tty->flip.flag_buf; tty->flip.tqueue.routine = flush_to_ldisc; tty->flip.tqueue.data = tty; - tty->flip.pty_sem = MUTEX; + init_MUTEX(&tty->flip.pty_sem); + init_waitqueue_head(&tty->write_wait); + init_waitqueue_head(&tty->read_wait); tty->tq_hangup.routine = do_tty_hangup; tty->tq_hangup.data = tty; sema_init(&tty->atomic_read, 1); --- linux/drivers/char/pty.c.orig Tue Mar 9 10:03:39 1999 +++ linux/drivers/char/pty.c Tue May 11 09:10:31 1999 @@ -30,7 +30,7 @@ struct pty_struct { int magic; - struct wait_queue * open_wait; + wait_queue_head_t open_wait; }; #define PTY_MAGIC 0x5001 @@ -336,13 +336,13 @@ __initfunc(int pty_init(void)) { -#ifdef CONFIG_UNIX98_PTYS int i; -#endif /* Traditional BSD devices */ memset(&pty_state, 0, sizeof(pty_state)); + for (i = 0; i < NR_PTYS; i++) + init_waitqueue_head(&pty_state[i].open_wait); memset(&pty_driver, 0, sizeof(struct tty_driver)); pty_driver.magic = TTY_DRIVER_MAGIC; pty_driver.driver_name = "pty_master"; --- linux/drivers/char/vt.c.orig Tue Mar 9 10:03:39 1999 +++ linux/drivers/char/vt.c Mon May 10 22:04:40 1999 @@ -1099,7 +1099,7 @@ * while those not ready go back to sleep. Seems overkill to add a wait * to each vt just for this - usually this does nothing! */ -static struct wait_queue *vt_activate_queue = NULL; +static DECLARE_WAIT_QUEUE_HEAD(vt_activate_queue); /* * Sleeps until a vt is activated, or the task is interrupted. Returns @@ -1108,7 +1108,7 @@ int vt_waitactive(int vt) { int retval; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); add_wait_queue(&vt_activate_queue, &wait); for (;;) { --- linux/drivers/char/serial.c.orig Tue Apr 6 14:35:07 1999 +++ linux/drivers/char/serial.c Mon May 10 22:04:40 1999 @@ -225,7 +225,7 @@ * memory if large numbers of serial ports are open. */ static unsigned char *tmp_buf; -static struct semaphore tmp_buf_sem = MUTEX; +static DECLARE_MUTEX(tmp_buf_sem); static inline int serial_paranoia_check(struct async_struct *info, kdev_t device, const char *routine) @@ -2422,7 +2422,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, struct async_struct *info) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); struct serial_state *state = info->state; int retval; int do_clocal = 0, extra_count = 0; --- linux/drivers/char/n_tty.c.orig Mon May 10 22:04:23 1999 +++ linux/drivers/char/n_tty.c Mon May 10 22:04:40 1999 @@ -605,7 +605,7 @@ tty->canon_data++; if (tty->fasync) kill_fasync(tty->fasync, SIGIO); - if (tty->read_wait) + if (waitqueue_active(&tty->read_wait)) wake_up_interruptible(&tty->read_wait); return; } @@ -707,7 +707,7 @@ if (!tty->icanon && (tty->read_cnt >= tty->minimum_to_wake)) { if (tty->fasync) kill_fasync(tty->fasync, SIGIO); - if (tty->read_wait) + if (waitqueue_active(&tty->read_wait)) wake_up_interruptible(&tty->read_wait); } @@ -868,7 +868,7 @@ unsigned char *buf, size_t nr) { unsigned char *b = buf; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); int c; int minimum, time; ssize_t retval = 0; @@ -1058,7 +1058,7 @@ const unsigned char * buf, size_t nr) { const unsigned char *b = buf; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); int c; ssize_t retval = 0; --- linux/drivers/char/selection.c.orig Thu Oct 29 23:17:43 1998 +++ linux/drivers/char/selection.c Mon May 10 22:04:40 1999 @@ -296,7 +296,7 @@ { struct vt_struct *vt = (struct vt_struct *) tty->driver_data; int pasted = 0, count; - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); poke_blanked_console(); add_wait_queue(&vt->paste_wait, &wait); --- linux/drivers/char/random.c.orig Fri Jan 8 13:31:32 1999 +++ linux/drivers/char/random.c Mon May 10 22:04:40 1999 @@ -424,8 +424,8 @@ static struct timer_rand_state extract_timer_state; static struct timer_rand_state *irq_timer_state[NR_IRQS]; static struct timer_rand_state *blkdev_timer_state[MAX_BLKDEV]; -static struct wait_queue *random_read_wait; -static struct wait_queue *random_write_wait; +static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); +static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); static ssize_t random_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos); @@ -555,8 +555,6 @@ initialize_benchmark(&timer_benchmark, "timer", 0); #endif extract_timer_state.dont_count_entropy = 1; - random_read_wait = NULL; - random_write_wait = NULL; } void rand_initialize_irq(int irq) @@ -1303,7 +1301,7 @@ static ssize_t random_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); ssize_t n, retval = 0, count = 0; if (nbytes == 0) --- linux/drivers/char/rtc.c.orig Tue Jan 26 09:47:09 1999 +++ linux/drivers/char/rtc.c Mon May 10 22:04:40 1999 @@ -69,7 +69,7 @@ * ioctls. */ -static struct wait_queue *rtc_wait; +static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); static struct timer_list rtc_irq_timer; @@ -150,7 +150,7 @@ static ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); unsigned long data; ssize_t retval; @@ -567,7 +567,6 @@ #endif init_timer(&rtc_irq_timer); rtc_irq_timer.function = rtc_dropped_irq; - rtc_wait = NULL; save_flags(flags); cli(); /* Initialize periodic freq. to CMOS reset default, which is 1024Hz */ --- linux/drivers/char/pc_keyb.c.orig Mon May 10 22:04:23 1999 +++ linux/drivers/char/pc_keyb.c Mon May 10 22:04:40 1999 @@ -864,7 +864,7 @@ static ssize_t read_aux(struct file * file, char * buffer, size_t count, loff_t *ppos) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); ssize_t i = count; unsigned char c; @@ -964,7 +964,7 @@ queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL); memset(queue, 0, sizeof(*queue)); queue->head = queue->tail = 0; - queue->proc_list = NULL; + init_waitqueue_head(&queue->proc_list); #ifdef INITIALIZE_MOUSE kbd_write(KBD_CNTL_REG, KBD_CCMD_MOUSE_ENABLE); /* Enable Aux. */ --- linux/drivers/char/pc_keyb.h.orig Tue Mar 9 10:03:39 1999 +++ linux/drivers/char/pc_keyb.h Mon May 10 22:04:40 1999 @@ -124,7 +124,7 @@ struct aux_queue { unsigned long head; unsigned long tail; - struct wait_queue *proc_list; + wait_queue_head_t proc_list; struct fasync_struct *fasync; unsigned char buf[AUX_BUF_SIZE]; }; --- linux/drivers/char/qpmouse.c.orig Tue Nov 24 11:41:06 1998 +++ linux/drivers/char/qpmouse.c Mon May 10 22:04:40 1999 @@ -55,7 +55,7 @@ struct qp_queue { unsigned long head; unsigned long tail; - struct wait_queue *proc_list; + wait_queue_head_t proc_list; struct fasync_struct *fasync; unsigned char buf[QP_BUF_SIZE]; }; @@ -258,7 +258,7 @@ static ssize_t read_qp(struct file * file, char * buffer, size_t count, loff_t *ppos) { - struct wait_queue wait = { current, NULL }; + DECLARE_WAITQUEUE(wait, current); ssize_t i = count; unsigned char c; @@ -354,7 +354,7 @@ queue = (struct qp_queue *) kmalloc(sizeof(*queue), GFP_KERNEL); memset(queue, 0, sizeof(*queue)); queue->head = queue->tail = 0; - queue->proc_list = NULL; + init_waitqueue_head(&queue->proc_list); return 0; } --- linux/drivers/scsi/hosts.c.orig Mon May 10 22:04:20 1999 +++ linux/drivers/scsi/hosts.c Mon May 10 22:04:40 1999 @@ -665,7 +665,7 @@ retval->host_no = max_scsi_hosts++; /* never reuse host_no (DB) */ next_scsi_host++; retval->host_queue = NULL; - retval->host_wait = NULL; + init_waitqueue_head(&retval->host_wait); retval->resetting = 0; retval->last_reset = 0; retval->irq = 0; @@ -738,7 +738,7 @@ */ static void launch_error_handler_thread(struct Scsi_Host * shpnt) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); shpnt->eh_notify = &sem; --- linux/drivers/scsi/hosts.h.orig Fri Jan 15 00:03:46 1999 +++ linux/drivers/scsi/hosts.h Mon May 10 22:18:28 1999 @@ -313,7 +313,7 @@ host. */ unsigned int eh_active:1; /* Indicates the eh thread is awake and active if this is true. */ - struct wait_queue * host_wait; + wait_queue_head_t host_wait; Scsi_Host_Template * hostt; atomic_t host_active; /* commands checked out */ volatile unsigned short host_busy; /* commands actually active on low-level */ --- linux/drivers/scsi/scsi.h.orig Tue Apr 6 14:35:08 1999 +++ linux/drivers/scsi/scsi.h Mon May 10 22:18:29 1999 @@ -417,7 +417,7 @@ */ struct scsi_device * next; /* Used for linked list */ struct scsi_device * prev; /* Used for linked list */ - struct wait_queue * device_wait;/* Used to wait if + wait_queue_head_t device_wait;/* Used to wait if device is busy */ struct Scsi_Host * host; volatile unsigned short device_busy; /* commands actually active on low-level */ @@ -711,7 +711,7 @@ #define SCSI_SLEEP(QUEUE, CONDITION) { \ if (CONDITION) { \ - struct wait_queue wait = { current, NULL}; \ + DECLARE_WAITQUEUE(wait, current); \ add_wait_queue(QUEUE, &wait); \ for(;;) { \ current->state = TASK_UNINTERRUPTIBLE; \ --- linux/drivers/scsi/scsi_ioctl.c.orig Mon May 10 22:04:29 1999 +++ linux/drivers/scsi/scsi_ioctl.c Mon May 10 22:04:40 1999 @@ -113,7 +113,7 @@ SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", cmd[0])); SCpnt = scsi_allocate_device(NULL, dev, 1); { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; scsi_do_cmd(SCpnt, cmd, NULL, 0, scsi_ioctl_done, timeout, retries); spin_unlock_irqrestore(&io_request_lock, flags); @@ -289,7 +289,7 @@ SCpnt = scsi_allocate_device(NULL, dev, 1); { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; scsi_do_cmd(SCpnt, cmd, buf, needed, scsi_ioctl_done, timeout, retries); --- linux/drivers/scsi/sd.c.orig Mon May 10 22:04:29 1999 +++ linux/drivers/scsi/sd.c Mon May 10 22:04:40 1999 @@ -1183,7 +1183,7 @@ SCpnt->sense_buffer[2] = 0; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); /* Mark as really busy again */ SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = &sem; @@ -1221,7 +1221,7 @@ SCpnt->sense_buffer[2] = 0; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); /* Mark as really busy again */ SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = &sem; @@ -1263,7 +1263,7 @@ SCpnt->sense_buffer[2] = 0; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); /* Mark as really busy again */ SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = &sem; @@ -1444,7 +1444,7 @@ /* same code as READCAPA !! */ { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.rq_status = RQ_SCSI_BUSY; /* Mark as really busy again */ SCpnt->request.sem = &sem; scsi_do_cmd (SCpnt, --- linux/drivers/scsi/sr.c.orig Tue Jan 26 09:47:10 1999 +++ linux/drivers/scsi/sr.c Mon May 10 22:04:40 1999 @@ -895,7 +895,7 @@ /* Do the command and wait.. */ { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; spin_lock_irqsave(&io_request_lock, flags); scsi_do_cmd (SCpnt, --- linux/drivers/scsi/sr_ioctl.c.orig Tue Mar 9 10:03:41 1999 +++ linux/drivers/scsi/sr_ioctl.c Mon May 10 22:04:40 1999 @@ -64,7 +64,7 @@ if( !scsi_block_when_processing_errors(SDev) ) return -ENODEV; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; spin_lock_irqsave(&io_request_lock, flags); scsi_do_cmd(SCpnt, --- linux/drivers/scsi/st.c.orig Tue Mar 9 10:03:41 1999 +++ linux/drivers/scsi/st.c Mon May 10 22:04:40 1999 @@ -279,7 +279,7 @@ } cmd[1] |= (SCpnt->lun << 5) & 0xe0; - STp->sem = MUTEX_LOCKED; + init_MUTEX_LOCKED(&STp->sem); SCpnt->use_sg = (bytes > (STp->buffer)->sg[0].length) ? (STp->buffer)->use_sg : 0; if (SCpnt->use_sg) { --- linux/drivers/scsi/sg.c.orig Mon May 10 22:04:29 1999 +++ linux/drivers/scsi/sg.c Mon May 10 22:04:40 1999 @@ -135,7 +135,7 @@ { struct sg_fd * nextfp; /* NULL when last opened fd on this device */ struct sg_device * parentdp; /* owning device */ - struct wait_queue * read_wait; /* queue read until command done */ + wait_queue_head_t read_wait; /* queue read until command done */ int timeout; /* defaults to SG_DEFAULT_TIMEOUT */ char * fst_buf; /* try to grab SG_SCATTER_SZ sized buffer on open */ int fb_size; /* actual size of allocated fst_buf */ @@ -153,7 +153,7 @@ typedef struct sg_device /* holds the state of each scsi generic device */ { Scsi_Device * device; - struct wait_queue * generic_wait;/* queue open if O_EXCL on prev. open */ + wait_queue_head_t generic_wait;/* queue open if O_EXCL on prev. open */ int sg_tablesize; /* adapter's max scatter-gather table size */ Sg_fd * headfp; /* first open fd belonging to this device */ kdev_t i_rdev; /* holds device major+minor number */ @@ -988,7 +988,7 @@ SCSI_LOG_TIMEOUT(3, printk("sg_attach: dev=%d \n", k)); sdp->device = scsidp; - sdp->generic_wait = NULL; + init_waitqueue_head(&sdp->generic_wait); sdp->headfp= NULL; sdp->exclude = 0; sdp->merge_fd = 0; /* Cope with SG_DEF_MERGE_FD on open */ --- linux/drivers/scsi/scsi.c.orig Mon May 10 22:04:29 1999 +++ linux/drivers/scsi/scsi.c Mon May 10 22:04:40 1999 @@ -473,6 +473,8 @@ SDpnt->host = shpnt; SDpnt->online = TRUE; + init_waitqueue_head(&SDpnt->device_wait); + /* * Next, hook the device to the host in question. */ @@ -660,7 +662,7 @@ SCpnt->lun = SDpnt->lun; SCpnt->channel = SDpnt->channel; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; SCpnt->request.rq_status = RQ_SCSI_BUSY; spin_lock_irq(&io_request_lock); @@ -703,7 +705,7 @@ scsi_cmd[5] = 0; SCpnt->cmd_len = 0; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.sem = &sem; SCpnt->request.rq_status = RQ_SCSI_BUSY; spin_lock_irq(&io_request_lock); @@ -849,7 +851,7 @@ scsi_cmd[5] = 0; SCpnt->cmd_len = 0; { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.sem = &sem; spin_lock_irq(&io_request_lock); @@ -890,6 +892,8 @@ SDpnt->device_queue = SCpnt; SDpnt->online = TRUE; + init_waitqueue_head(&SDpnt->device_wait); + /* * Since we just found one device, there had damn well better be one in the list * already. @@ -2639,7 +2643,7 @@ { if( shpnt->hostt == tpnt && shpnt->hostt->use_new_eh_code ) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); shpnt->eh_notify = &sem; kernel_thread((int (*)(void *))scsi_error_handler, @@ -2876,7 +2880,7 @@ && shpnt->hostt->use_new_eh_code && shpnt->ehandler != NULL ) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); shpnt->eh_notify = &sem; send_sig(SIGKILL, shpnt->ehandler, 1); --- linux/drivers/scsi/scsi_error.c.orig Tue Mar 9 10:03:41 1999 +++ linux/drivers/scsi/scsi_error.c Mon May 10 22:04:40 1999 @@ -560,7 +560,7 @@ void scsi_sleep (int timeout) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); struct timer_list timer; init_timer(&timer); @@ -603,7 +603,7 @@ if (host->can_queue) { - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); SCpnt->eh_state = SCSI_STATE_QUEUED; @@ -1924,7 +1924,7 @@ { struct Scsi_Host * host = (struct Scsi_Host *) data; int rtn; - struct semaphore sem = MUTEX_LOCKED; + DECLARE_MUTEX_LOCKED(sem); unsigned long flags; lock_kernel(); --- linux/arch/i386/kernel/init_task.c.orig Thu Oct 29 23:17:39 1998 +++ linux/arch/i386/kernel/init_task.c Mon May 10 22:04:40 1999 @@ -10,7 +10,7 @@ static struct file * init_fd_array[NR_OPEN] = { NULL, }; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS; -struct mm_struct init_mm = INIT_MM; +struct mm_struct init_mm = INIT_MM(init_mm); /* * Initial task structure. @@ -20,5 +20,6 @@ * "init_task" linker map entry.. */ union task_union init_task_union - __attribute__((__section__(".data.init_task"))) = { INIT_TASK }; + __attribute__((__section__(".data.init_task"))) = + { INIT_TASK(init_task_union.task) }; --- linux/Makefile.orig Mon May 10 22:04:27 1999 +++ linux/Makefile Tue May 11 09:07:39 1999 @@ -22,7 +22,7 @@ AS =$(CROSS_COMPILE)as LD =$(CROSS_COMPILE)ld -CC =$(CROSS_COMPILE)gcc -D__KERNEL__ -I$(HPATH) +CC =$(CROSS_COMPILE)gcc -D__KERNEL__ -I$(HPATH) -g CPP =$(CC) -E AR =$(CROSS_COMPILE)ar NM =$(CROSS_COMPILE)nm