Messages in this thread Patch in this message | | | Date | Mon, 8 Dec 2003 10:25:00 -0800 | From | William Lee Irwin III <> | Subject | Re: PROBLEM: possible proceses leak |
| |
On Mon, Dec 08, 2003 at 09:01:40PM +0300, Andrew Volkov wrote: > In all kernels (up to 2.6-test11) next sequence of code > in __down/__down_interruptible function > (arch/i386/kernel/semaphore.c) may cause processes or threads leaking.
Something like this?
-- wli
===== arch/alpha/kernel/semaphore.c 1.5 vs edited ===== --- 1.5/arch/alpha/kernel/semaphore.c Thu Apr 3 14:49:57 2003 +++ edited/arch/alpha/kernel/semaphore.c Mon Dec 8 10:19:08 2003 @@ -62,9 +62,9 @@ current->comm, current->pid, sem); #endif + add_wait_queue_exclusive(&sem->wait, &wait); current->state = TASK_UNINTERRUPTIBLE; wmb(); - add_wait_queue_exclusive(&sem->wait, &wait); /* At this point we know that sem->count is negative. In order to avoid racing with __up, we must check for wakeup before @@ -94,8 +94,8 @@ set_task_state(current, TASK_UNINTERRUPTIBLE); } - remove_wait_queue(&sem->wait, &wait); current->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); #ifdef CONFIG_DEBUG_SEMAPHORE printk("%s(%d): down acquired(%p)\n", @@ -114,9 +114,9 @@ current->comm, current->pid, sem); #endif + add_wait_queue_exclusive(&sem->wait, &wait); current->state = TASK_INTERRUPTIBLE; wmb(); - add_wait_queue_exclusive(&sem->wait, &wait); while (1) { long tmp, tmp2, tmp3; @@ -181,8 +181,8 @@ set_task_state(current, TASK_INTERRUPTIBLE); } - remove_wait_queue(&sem->wait, &wait); current->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); wake_up(&sem->wait); #ifdef CONFIG_DEBUG_SEMAPHORE ===== arch/arm/kernel/semaphore.c 1.8 vs edited ===== --- 1.8/arch/arm/kernel/semaphore.c Sat Sep 20 02:38:17 2003 +++ edited/arch/arm/kernel/semaphore.c Mon Dec 8 10:19:27 2003 @@ -58,8 +58,8 @@ { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_UNINTERRUPTIBLE; spin_lock_irq(&semaphore_lock); sem->sleepers++; @@ -82,8 +82,8 @@ spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); - remove_wait_queue(&sem->wait, &wait); tsk->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); wake_up(&sem->wait); } @@ -92,8 +92,8 @@ int retval = 0; struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_INTERRUPTIBLE; spin_lock_irq(&semaphore_lock); sem->sleepers ++; ===== arch/arm26/kernel/semaphore.c 1.1 vs edited ===== --- 1.1/arch/arm26/kernel/semaphore.c Wed Jun 4 04:15:45 2003 +++ edited/arch/arm26/kernel/semaphore.c Mon Dec 8 10:19:41 2003 @@ -60,8 +60,8 @@ { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_UNINTERRUPTIBLE; spin_lock_irq(&semaphore_lock); sem->sleepers++; @@ -84,8 +84,8 @@ spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); - remove_wait_queue(&sem->wait, &wait); tsk->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); wake_up(&sem->wait); } @@ -94,8 +94,8 @@ int retval = 0; struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_INTERRUPTIBLE; spin_lock_irq(&semaphore_lock); sem->sleepers ++; ===== arch/cris/kernel/semaphore.c 1.2 vs edited ===== --- 1.2/arch/cris/kernel/semaphore.c Mon Feb 4 23:39:23 2002 +++ edited/arch/cris/kernel/semaphore.c Mon Dec 8 10:17:51 2003 @@ -68,8 +68,8 @@ #define DOWN_HEAD(task_state) \ \ \ - tsk->state = (task_state); \ add_wait_queue(&sem->wait, &wait); \ + tsk->state = (task_state); \ \ /* \ * Ok, we're set up. sem->count is known to be less than zero \ @@ -91,8 +91,8 @@ #define DOWN_TAIL(task_state) \ tsk->state = (task_state); \ } \ - tsk->state = TASK_RUNNING; \ remove_wait_queue(&sem->wait, &wait); + tsk->state = TASK_RUNNING; \ void __down(struct semaphore * sem) { ===== arch/h8300/kernel/semaphore.c 1.1 vs edited ===== --- 1.1/arch/h8300/kernel/semaphore.c Sun Feb 16 16:01:58 2003 +++ edited/arch/h8300/kernel/semaphore.c Mon Dec 8 10:18:07 2003 @@ -69,8 +69,8 @@ #define DOWN_HEAD(task_state) \ \ \ - current->state = (task_state); \ add_wait_queue(&sem->wait, &wait); \ + current->state = (task_state); \ \ /* \ * Ok, we're set up. sem->count is known to be less than zero \ ===== arch/i386/kernel/semaphore.c 1.8 vs edited ===== --- 1.8/arch/i386/kernel/semaphore.c Thu Nov 21 09:55:02 2002 +++ edited/arch/i386/kernel/semaphore.c Mon Dec 8 10:18:43 2003 @@ -59,9 +59,9 @@ DECLARE_WAITQUEUE(wait, tsk); unsigned long flags; - tsk->state = TASK_UNINTERRUPTIBLE; spin_lock_irqsave(&sem->wait.lock, flags); add_wait_queue_exclusive_locked(&sem->wait, &wait); + tsk->state = TASK_UNINTERRUPTIBLE; sem->sleepers++; for (;;) { @@ -84,10 +84,10 @@ spin_lock_irqsave(&sem->wait.lock, flags); tsk->state = TASK_UNINTERRUPTIBLE; } + tsk->state = TASK_RUNNING; remove_wait_queue_locked(&sem->wait, &wait); wake_up_locked(&sem->wait); spin_unlock_irqrestore(&sem->wait.lock, flags); - tsk->state = TASK_RUNNING; } int __down_interruptible(struct semaphore * sem) @@ -97,9 +97,9 @@ DECLARE_WAITQUEUE(wait, tsk); unsigned long flags; - tsk->state = TASK_INTERRUPTIBLE; spin_lock_irqsave(&sem->wait.lock, flags); add_wait_queue_exclusive_locked(&sem->wait, &wait); + tsk->state = TASK_INTERRUPTIBLE; sem->sleepers++; for (;;) { @@ -137,11 +137,11 @@ spin_lock_irqsave(&sem->wait.lock, flags); tsk->state = TASK_INTERRUPTIBLE; } + tsk->state = TASK_RUNNING; remove_wait_queue_locked(&sem->wait, &wait); wake_up_locked(&sem->wait); spin_unlock_irqrestore(&sem->wait.lock, flags); - tsk->state = TASK_RUNNING; return retval; } ===== arch/ia64/kernel/semaphore.c 1.4 vs edited ===== --- 1.4/arch/ia64/kernel/semaphore.c Sat Aug 31 06:16:01 2002 +++ edited/arch/ia64/kernel/semaphore.c Mon Dec 8 10:20:25 2003 @@ -51,9 +51,9 @@ DECLARE_WAITQUEUE(wait, tsk); unsigned long flags; - tsk->state = TASK_UNINTERRUPTIBLE; spin_lock_irqsave(&sem->wait.lock, flags); add_wait_queue_exclusive_locked(&sem->wait, &wait); + tsk->state = TASK_UNINTERRUPTIBLE; sem->sleepers++; for (;;) { @@ -76,10 +76,10 @@ spin_lock_irqsave(&sem->wait.lock, flags); tsk->state = TASK_UNINTERRUPTIBLE; } + tsk->state = TASK_RUNNING; remove_wait_queue_locked(&sem->wait, &wait); wake_up_locked(&sem->wait); spin_unlock_irqrestore(&sem->wait.lock, flags); - tsk->state = TASK_RUNNING; } int @@ -90,9 +90,9 @@ DECLARE_WAITQUEUE(wait, tsk); unsigned long flags; - tsk->state = TASK_INTERRUPTIBLE; spin_lock_irqsave(&sem->wait.lock, flags); add_wait_queue_exclusive_locked(&sem->wait, &wait); + tsk->state = TASK_INTERRUPTIBLE; sem->sleepers ++; for (;;) { @@ -130,11 +130,11 @@ spin_lock_irqsave(&sem->wait.lock, flags); tsk->state = TASK_INTERRUPTIBLE; } + tsk->state = TASK_RUNNING; remove_wait_queue_locked(&sem->wait, &wait); wake_up_locked(&sem->wait); spin_unlock_irqrestore(&sem->wait.lock, flags); - tsk->state = TASK_RUNNING; return retval; } ===== arch/m68k/kernel/semaphore.c 1.2 vs edited ===== --- 1.2/arch/m68k/kernel/semaphore.c Mon Feb 4 23:39:24 2002 +++ edited/arch/m68k/kernel/semaphore.c Mon Dec 8 10:21:00 2003 @@ -69,8 +69,8 @@ #define DOWN_HEAD(task_state) \ \ \ - current->state = (task_state); \ add_wait_queue(&sem->wait, &wait); \ + current->state = (task_state); \ \ /* \ * Ok, we're set up. sem->count is known to be less than zero \ ===== arch/m68knommu/kernel/semaphore.c 1.1 vs edited ===== --- 1.1/arch/m68knommu/kernel/semaphore.c Fri Nov 1 07:19:55 2002 +++ edited/arch/m68knommu/kernel/semaphore.c Mon Dec 8 10:21:10 2003 @@ -70,8 +70,8 @@ #define DOWN_HEAD(task_state) \ \ \ - current->state = (task_state); \ add_wait_queue(&sem->wait, &wait); \ + current->state = (task_state); \ \ /* \ * Ok, we're set up. sem->count is known to be less than zero \ ===== arch/mips/kernel/semaphore.c 1.2 vs edited ===== --- 1.2/arch/mips/kernel/semaphore.c Mon Feb 4 23:39:24 2002 +++ edited/arch/mips/kernel/semaphore.c Mon Dec 8 10:21:19 2003 @@ -68,8 +68,8 @@ #define DOWN_HEAD(task_state) \ \ \ - tsk->state = (task_state); \ add_wait_queue(&sem->wait, &wait); \ + tsk->state = (task_state); \ \ /* \ * Ok, we're set up. sem->count is known to be less than zero \ ===== arch/parisc/kernel/semaphore.c 1.3 vs edited ===== --- 1.3/arch/parisc/kernel/semaphore.c Sun Jul 21 14:20:31 2002 +++ edited/arch/parisc/kernel/semaphore.c Mon Dec 8 10:21:52 2003 @@ -49,8 +49,8 @@ spin_lock_irq(&sem->sentry); \ if (wakers(sem->count) == 0 && ret == 0) \ goto lost_race; /* Someone stole our wakeup */ \ - __remove_wait_queue(&sem->wait, &wait); \ current->state = TASK_RUNNING; \ + __remove_wait_queue(&sem->wait, &wait); \ if (!waitqueue_active(&sem->wait) && (sem->count < 0)) \ sem->count = wakers(sem->count); ===== arch/ppc/kernel/semaphore.c 1.7 vs edited ===== --- 1.7/arch/ppc/kernel/semaphore.c Sun Sep 15 21:51:59 2002 +++ edited/arch/ppc/kernel/semaphore.c Mon Dec 8 10:22:15 2003 @@ -74,8 +74,8 @@ struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_UNINTERRUPTIBLE; smp_wmb(); /* @@ -88,8 +88,8 @@ schedule(); tsk->state = TASK_UNINTERRUPTIBLE; } - remove_wait_queue(&sem->wait, &wait); tsk->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); /* * If there are any more sleepers, wake one of them up so @@ -105,8 +105,8 @@ struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_INTERRUPTIBLE; smp_wmb(); while (__sem_update_count(sem, -1) <= 0) { ===== arch/ppc64/kernel/semaphore.c 1.3 vs edited ===== --- 1.3/arch/ppc64/kernel/semaphore.c Wed Aug 27 21:23:26 2003 +++ edited/arch/ppc64/kernel/semaphore.c Mon Dec 8 10:22:33 2003 @@ -75,8 +75,8 @@ struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - __set_task_state(tsk, TASK_UNINTERRUPTIBLE); add_wait_queue_exclusive(&sem->wait, &wait); + __set_task_state(tsk, TASK_UNINTERRUPTIBLE); /* * Try to get the semaphore. If the count is > 0, then we've @@ -88,8 +88,8 @@ schedule(); set_task_state(tsk, TASK_UNINTERRUPTIBLE); } - remove_wait_queue(&sem->wait, &wait); __set_task_state(tsk, TASK_RUNNING); + remove_wait_queue(&sem->wait, &wait); /* * If there are any more sleepers, wake one of them up so @@ -105,8 +105,8 @@ struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - __set_task_state(tsk, TASK_INTERRUPTIBLE); add_wait_queue_exclusive(&sem->wait, &wait); + __set_task_state(tsk, TASK_INTERRUPTIBLE); while (__sem_update_count(sem, -1) <= 0) { if (signal_pending(current)) { @@ -122,8 +122,8 @@ schedule(); set_task_state(tsk, TASK_INTERRUPTIBLE); } - remove_wait_queue(&sem->wait, &wait); __set_task_state(tsk, TASK_RUNNING); + remove_wait_queue(&sem->wait, &wait); wake_up(&sem->wait); return retval; ===== arch/s390/kernel/semaphore.c 1.4 vs edited ===== --- 1.4/arch/s390/kernel/semaphore.c Wed Jun 5 10:43:26 2002 +++ edited/arch/s390/kernel/semaphore.c Mon Dec 8 10:22:46 2003 @@ -64,14 +64,14 @@ struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_UNINTERRUPTIBLE; while (__sem_update_count(sem, -1) <= 0) { schedule(); tsk->state = TASK_UNINTERRUPTIBLE; } - remove_wait_queue(&sem->wait, &wait); tsk->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); wake_up(&sem->wait); } @@ -87,8 +87,8 @@ struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_INTERRUPTIBLE; while (__sem_update_count(sem, -1) <= 0) { if (signal_pending(current)) { __sem_update_count(sem, 0); @@ -98,8 +98,8 @@ schedule(); tsk->state = TASK_INTERRUPTIBLE; } - remove_wait_queue(&sem->wait, &wait); tsk->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); wake_up(&sem->wait); return retval; } ===== arch/sh/kernel/semaphore.c 1.3 vs edited ===== --- 1.3/arch/sh/kernel/semaphore.c Wed Apr 10 00:09:38 2002 +++ edited/arch/sh/kernel/semaphore.c Mon Dec 8 10:22:54 2003 @@ -77,8 +77,8 @@ #define DOWN_HEAD(task_state) \ \ \ - tsk->state = (task_state); \ add_wait_queue(&sem->wait, &wait); \ + tsk->state = (task_state); \ \ /* \ * Ok, we're set up. sem->count is known to be less than zero \ ===== arch/sparc/kernel/semaphore.c 1.5 vs edited ===== --- 1.5/arch/sparc/kernel/semaphore.c Tue Jul 16 17:12:12 2002 +++ edited/arch/sparc/kernel/semaphore.c Mon Dec 8 10:23:11 2003 @@ -49,8 +49,8 @@ { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_UNINTERRUPTIBLE; spin_lock_irq(&semaphore_lock); sem->sleepers++; @@ -73,8 +73,8 @@ spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); - remove_wait_queue(&sem->wait, &wait); tsk->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); wake_up(&sem->wait); } ===== arch/sparc64/kernel/semaphore.c 1.7 vs edited ===== --- 1.7/arch/sparc64/kernel/semaphore.c Wed Sep 3 23:40:12 2003 +++ edited/arch/sparc64/kernel/semaphore.c Mon Dec 8 10:23:37 2003 @@ -95,15 +95,15 @@ struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_UNINTERRUPTIBLE; while (__sem_update_count(sem, -1) <= 0) { schedule(); tsk->state = TASK_UNINTERRUPTIBLE; } - remove_wait_queue(&sem->wait, &wait); tsk->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); wake_up(&sem->wait); } @@ -198,8 +198,8 @@ struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_INTERRUPTIBLE; while (__sem_update_count(sem, -1) <= 0) { if (signal_pending(current)) { ===== arch/v850/kernel/semaphore.c 1.2 vs edited ===== --- 1.2/arch/v850/kernel/semaphore.c Wed Dec 18 18:20:47 2002 +++ edited/arch/v850/kernel/semaphore.c Mon Dec 8 10:23:58 2003 @@ -60,8 +60,8 @@ { struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_UNINTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_UNINTERRUPTIBLE; spin_lock_irq(&semaphore_lock); sem->sleepers++; @@ -84,8 +84,8 @@ spin_lock_irq(&semaphore_lock); } spin_unlock_irq(&semaphore_lock); - remove_wait_queue(&sem->wait, &wait); tsk->state = TASK_RUNNING; + remove_wait_queue(&sem->wait, &wait); wake_up(&sem->wait); } @@ -94,8 +94,8 @@ int retval = 0; struct task_struct *tsk = current; DECLARE_WAITQUEUE(wait, tsk); - tsk->state = TASK_INTERRUPTIBLE; add_wait_queue_exclusive(&sem->wait, &wait); + tsk->state = TASK_INTERRUPTIBLE; spin_lock_irq(&semaphore_lock); sem->sleepers ++; ===== arch/x86_64/kernel/semaphore.c 1.3 vs edited ===== --- 1.3/arch/x86_64/kernel/semaphore.c Fri Oct 11 16:52:38 2002 +++ edited/arch/x86_64/kernel/semaphore.c Mon Dec 8 10:24:24 2003 @@ -60,9 +60,9 @@ DECLARE_WAITQUEUE(wait, tsk); unsigned long flags; - tsk->state = TASK_UNINTERRUPTIBLE; spin_lock_irqsave(&sem->wait.lock, flags); add_wait_queue_exclusive_locked(&sem->wait, &wait); + tsk->state = TASK_UNINTERRUPTIBLE; sem->sleepers++; for (;;) { @@ -85,10 +85,10 @@ spin_lock_irqsave(&sem->wait.lock, flags); tsk->state = TASK_UNINTERRUPTIBLE; } + tsk->state = TASK_RUNNING; remove_wait_queue_locked(&sem->wait, &wait); wake_up_locked(&sem->wait); spin_unlock_irqrestore(&sem->wait.lock, flags); - tsk->state = TASK_RUNNING; } int __down_interruptible(struct semaphore * sem) @@ -98,9 +98,9 @@ DECLARE_WAITQUEUE(wait, tsk); unsigned long flags; - tsk->state = TASK_INTERRUPTIBLE; spin_lock_irqsave(&sem->wait.lock, flags); add_wait_queue_exclusive_locked(&sem->wait, &wait); + tsk->state = TASK_INTERRUPTIBLE; sem->sleepers++; for (;;) { @@ -138,11 +138,11 @@ spin_lock_irqsave(&sem->wait.lock, flags); tsk->state = TASK_INTERRUPTIBLE; } + tsk->state = TASK_RUNNING; remove_wait_queue_locked(&sem->wait, &wait); wake_up_locked(&sem->wait); spin_unlock_irqrestore(&sem->wait.lock, flags); - tsk->state = TASK_RUNNING; return retval; } - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |