Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[PATCH 1/19] MUTEX: Introduce simple mutex implementation

531 views
Skip to first unread message

David Howells

unread,
Dec 12, 2005, 7:00:25 PM12/12/05
to
The attached patch introduces a simple mutex implementation as an alternative
to the usual semaphore implementation where simple mutex functionality is all
that is required.

This is useful in two ways:

(1) A number of archs only provide very simple atomic instructions (such as
XCHG on i386, TAS on M68K, SWAP on FRV) which aren't sufficient to
implement full semaphore support directly. Instead spinlocks must be
employed to implement fuller functionality.

(2) This makes it obvious in what way the semaphore is being used: whether
it's being used as a mutex or being used as a counter.

This patch set does the following:

(1) Provides a simple xchg() based semaphore as a default for all
architectures that don't wish to override it and provide their own.

Overriding is possible by setting CONFIG_ARCH_IMPLEMENTS_MUTEX and
supplying asm/mutex.h

Partial overriding is possible by #defining mutex_grab(), mutex_release()
and is_mutex_locked() to perform the appropriate optimised functions.

(2) Provides linux/mutex.h as a common include for gaining access to mutex
semaphores.

(3) Provides linux/semaphore.h as a common include for gaining access to all
the different types of semaphore that may be used from within the kernel.

(4) Renames down*() to down_sem*() and up() to up_sem() for the traditional
semaphores, and removes init_MUTEX*() and DECLARE_MUTEX*() from
asm/semaphore.h

(5) Redirects the following to apply to the new mutexes rather than the
traditional semaphores:

down()
down_trylock()
down_interruptible()
up()
init_MUTEX()
init_MUTEX_LOCKED()
DECLARE_MUTEX()
DECLARE_MUTEX_LOCKED()

On the basis that most usages of semaphores are as mutexes, this makes
sense for in most cases it's just then a matter of changing the type from
struct semaphore to struct mutex. In some cases, sema_init() has to be
changed to init_MUTEX*() also.

(6) Generally include linux/semaphore.h in place of asm/semaphore.h.

(7) Provides a debugging config option CONFIG_DEBUG_MUTEX_OWNER by which the
mutex owner can be tracked and by which over-upping can be detected.

Signed-Off-By: David Howells <dhow...@redhat.com>
---
warthog>diffstat -p1 mutex-simple-2615rc5.diff
include/linux/mutex-simple.h | 194 +++++++++++++++++++++++++++++++++++++++++++
include/linux/mutex.h | 32 +++++++
include/linux/semaphore.h | 30 ++++++
lib/Kconfig.debug | 8 +
lib/Makefile | 4
lib/mutex-simple.c | 178 +++++++++++++++++++++++++++++++++++++++
lib/semaphore-sleepers.c | 8 -
7 files changed, 450 insertions(+), 4 deletions(-)

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/semaphore.h linux-2.6.15-rc5-mutex/include/linux/semaphore.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/semaphore.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/semaphore.h 2005-12-12 22:03:53.000000000 +0000
@@ -0,0 +1,30 @@
+/* semaphore.h: include the various types of semaphore in one package
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhow...@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_SEMAPHORE_H
+#define _LINUX_SEMAPHORE_H
+
+/*
+ * simple mutex semaphores
+ */
+#include <linux/mutex.h>
+
+/*
+ * multiple-count semaphores
+ */
+#include <asm/semaphore.h>
+
+/*
+ * read/write semaphores
+ */
+#include <linux/rwsem.h>
+
+#endif /* _LINUX_SEMAPHORE_H */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/mutex.h linux-2.6.15-rc5-mutex/include/linux/mutex.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/mutex.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/mutex.h 2005-12-12 22:13:30.000000000 +0000
@@ -0,0 +1,32 @@
+/* mutex.h: mutex semaphore implementation base
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhow...@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#ifndef _LINUX_MUTEX_H
+#define _LINUX_MUTEX_H
+
+#include <linux/config.h>
+
+#ifdef CONFIG_ARCH_IMPLEMENTS_MUTEX
+
+/*
+ * the arch wants to implement the whole mutex itself
+ */
+#include <asm/mutex.h>
+#else
+
+/*
+ * simple exchange-based mutex
+ * - the arch may override mutex_grab(), mutex_release() and is_mutex_locked()
+ * to use something other than xchg() by #defining mutex_grab
+ */
+#include <linux/mutex-simple.h>
+#endif
+
+#endif /* _LINUX_MUTEX_H */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/mutex-simple.h linux-2.6.15-rc5-mutex/include/linux/mutex-simple.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/mutex-simple.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/mutex-simple.h 2005-12-12 22:26:11.000000000 +0000
@@ -0,0 +1,194 @@
+/* mutex-simple.h: simple exchange-based mutexes
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhow...@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ *
+ * This doesn't require the arch to do anything for straightforward xchg()
+ * based mutexes
+ *
+ * If the sets CONFIG_ARCH_IMPLEMENTS_MUTEX then this implementation will not
+ * be used, and the arch should supply asm/mutex.h.
+ *
+ * If the arch defines mutex_grab(), mutex_release() and is_mutex_locked() for
+ * itself, then those will be used to provide the appropriate functionality
+ *
+ * See lib/mutex-simple.c for the slow-path implementation.
+ */
+#ifndef _LINUX_MUTEX_SIMPLE_H
+#define _LINUX_MUTEX_SIMPLE_H
+
+#ifndef _LINUX_MUTEX_H
+#error linux/mutex-xchg.h should not be included directly; use linux/mutex.h instead
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <linux/linkage.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <asm/system.h>
+
+/*
+ * the mutex semaphore definition
+ * - if state is 0, then the mutex is available
+ * - if state is non-zero, then the mutex is busy
+ * - if wait_list is not empty, then there are processes waiting for the mutex
+ */
+struct mutex {
+ int state;
+ spinlock_t wait_lock;
+ struct list_head wait_list;
+#ifdef CONFIG_DEBUG_MUTEX_OWNER
+ struct task_struct *__owner;
+#endif
+};
+
+#ifndef mutex_grab
+/*
+ * mutex_grab() attempts to grab the mutex and returns true if successful
+ */
+#define mutex_grab(mutex) (xchg(&(mutex)->state, 1) == 0)
+
+/*
+ * mutex_release() releases the mutex
+ */
+#define mutex_release(mutex) do { (mutex)->state = 0; } while(0)
+
+/*
+ * is_mutex_locked() returns non-zero if the mutex is locked
+ */
+#define is_mutex_locked(mutex) ((mutex)->state)
+#endif
+
+#ifdef CONFIG_DEBUG_MUTEX_OWNER
+# define __MUTEX_OWNER_INIT(owner) , .__owner = (owner)
+#else
+# define __MUTEX_OWNER_INIT(owner)
+#endif
+
+#define __MUTEX_INITIALISER(name,_state,owner) \
+{ \
+ .state = (_state), \
+ .wait_lock = SPIN_LOCK_UNLOCKED, \
+ .wait_list = LIST_HEAD_INIT((name).wait_list) \
+ __MUTEX_OWNER_INIT(owner) \
+}
+
+#define __DECLARE_MUTEX_GENERIC(name, owner, state) \
+ struct mutex name = __MUTEX_INITIALISER(name, owner, state)
+
+#define DECLARE_MUTEX(name) \
+ __DECLARE_MUTEX_GENERIC(name, 0, NULL)
+
+#define DECLARE_MUTEX_LOCKED(name, owner) \
+ __DECLARE_MUTEX_GENERIC(name, 1, (owner))
+
+static inline void mutex_init(struct mutex *mutex,
+ unsigned state,
+ struct task_struct *owner)
+{
+ mutex->state = state;
+ spin_lock_init(&mutex->wait_lock);
+ INIT_LIST_HEAD(&mutex->wait_list);
+#ifdef CONFIG_DEBUG_MUTEX_OWNER
+ mutex->__owner = owner;
+#endif
+}
+
+static inline void init_MUTEX(struct mutex *mutex)
+{
+ mutex_init(mutex, 0, NULL);
+}
+
+static inline void init_MUTEX_LOCKED (struct mutex *mutex)
+{
+ mutex_init(mutex, 1, current);
+}
+
+extern void __down(struct mutex *mutex);
+extern int __down_interruptible(struct mutex *mutex);
+extern void __up(struct mutex *mutex);
+
+#ifdef CONFIG_DEBUG_MUTEX_OWNER
+extern void __up_bad(struct mutex *mutex);
+#endif
+
+/*
+ * sleep until we get the mutex
+ */
+static inline void down(struct mutex *mutex)
+{
+ if (mutex_grab(mutex)) {
+#ifdef CONFIG_DEBUG_MUTEX_OWNER
+ mutex->__owner = current;
+#endif
+ }
+ else {
+ __down(mutex);
+ }
+}
+
+/*
+ * sleep interruptibly until we get the mutex
+ * - return 0 if successful, -EINTR if interrupted
+ */
+static inline int down_interruptible(struct mutex *mutex)
+{
+ if (mutex_grab(mutex)) {
+#ifdef CONFIG_DEBUG_MUTEX_OWNER
+ mutex->__owner = current;
+#endif
+ return 0;
+ }
+
+ return __down_interruptible(mutex);
+}
+
+/*
+ * attempt to grab the mutex without waiting for it to become available
+ * - returns zero if we acquired it
+ */
+static inline int down_trylock(struct mutex *mutex)
+{
+ if (mutex_grab(mutex)) {
+ /* success */
+#ifdef CONFIG_DEBUG_MUTEX_OWNER
+ mutex->__owner = current;
+#endif
+ return 0;
+ }
+
+ /* failure */
+ return 1;
+}
+
+/*
+ * release the mutex
+ */
+static inline void up(struct mutex *mutex)
+{
+ unsigned long flags;
+
+#ifdef CONFIG_DEBUG_MUTEX_OWNER
+ if (mutex->__owner != current)
+ __up_bad(mutex);
+ mutex->__owner = NULL;
+#endif
+
+ /* must prevent a race */
+ spin_lock_irqsave(&mutex->wait_lock, flags);
+ if (!list_empty(&mutex->wait_list))
+ __up(mutex);
+ else
+ mutex_release(mutex);
+ spin_unlock_irqrestore(&mutex->wait_lock, flags);
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* _LINUX_MUTEX_SIMPLE_H */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/lib/Kconfig.debug linux-2.6.15-rc5-mutex/lib/Kconfig.debug
--- /warthog/kernels/linux-2.6.15-rc5/lib/Kconfig.debug 2005-12-08 16:23:56.000000000 +0000
+++ linux-2.6.15-rc5-mutex/lib/Kconfig.debug 2005-12-12 16:59:35.000000000 +0000
@@ -111,6 +111,14 @@ config DEBUG_SPINLOCK_SLEEP
If you say Y here, various routines which may sleep will become very
noisy if they are called with a spinlock held.

+config DEBUG_MUTEX_OWNER
+ bool "Mutex owner tracking and checking"
+ depends on DEBUG_KERNEL
+ help
+ If you say Y here, the process currently owning a mutex will be
+ remembered, and a warning will be issued if anyone other than that
+ process releases it.
+
config DEBUG_KOBJECT
bool "kobject debugging"
depends on DEBUG_KERNEL
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/lib/Makefile linux-2.6.15-rc5-mutex/lib/Makefile
--- /warthog/kernels/linux-2.6.15-rc5/lib/Makefile 2005-12-08 16:23:56.000000000 +0000
+++ linux-2.6.15-rc5-mutex/lib/Makefile 2005-12-12 18:59:21.000000000 +0000
@@ -28,6 +28,10 @@ ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
lib-y += dec_and_lock.o
endif

+ifneq ($(CONFIG_ARCH_IMPLEMENTS_MUTEX),y)
+ lib-y += mutex-simple.o
+endif
+
obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o
obj-$(CONFIG_CRC16) += crc16.o
obj-$(CONFIG_CRC32) += crc32.o
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/lib/mutex-simple.c linux-2.6.15-rc5-mutex/lib/mutex-simple.c
--- /warthog/kernels/linux-2.6.15-rc5/lib/mutex-simple.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.15-rc5-mutex/lib/mutex-simple.c 2005-12-12 22:27:00.000000000 +0000
@@ -0,0 +1,178 @@
+/* mutex-simple.c: simple mutex slow paths
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhow...@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+
+struct mutex_waiter {
+ struct list_head list;
+ struct task_struct *task;
+};
+
+/*
+ * wait for a token to be granted from a mutex
+ */
+void __down(struct mutex *mutex)
+{
+ struct mutex_waiter waiter;
+ struct task_struct *tsk = current;
+ unsigned long flags;
+
+ /* set up my own style of waitqueue */
+ waiter.task = tsk;
+
+ spin_lock_irqsave(&mutex->wait_lock, flags);
+
+ if (mutex_grab(mutex)) {
+ /* we got the mutex anyway */
+ spin_unlock_irqrestore(&mutex->wait_lock, flags);
+ return;
+ }
+
+ /* need to sleep */
+ get_task_struct(tsk);
+ list_add_tail(&waiter.list, &mutex->wait_list);
+
+ /* we don't need to touch the mutex struct anymore */
+ spin_unlock_irqrestore(&mutex->wait_lock, flags);
+
+ /* wait to be given the mutex */
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+
+ for (;;) {
+ if (list_empty(&waiter.list))
+ break;
+ schedule();
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ }
+
+ tsk->state = TASK_RUNNING;
+}
+
+EXPORT_SYMBOL(__down);
+
+/*
+ * interruptibly wait for a token to be granted from a mutex
+ */
+int __down_interruptible(struct mutex *mutex)
+{
+ struct mutex_waiter waiter;
+ struct task_struct *tsk = current;
+ unsigned long flags;
+ int ret;
+
+ /* set up my own style of waitqueue */
+ waiter.task = tsk;
+
+ spin_lock_irqsave(&mutex->wait_lock, flags);
+
+ if (mutex_grab(mutex)) {
+ /* we got the mutex anyway */
+ spin_unlock_irqrestore(&mutex->wait_lock, flags);
+ return 0;
+ }
+
+ /* need to sleep */
+ get_task_struct(tsk);
+ list_add_tail(&waiter.list, &mutex->wait_list);
+
+ /* we don't need to touch the mutex struct anymore */
+ set_task_state(tsk, TASK_INTERRUPTIBLE);
+
+ spin_unlock_irqrestore(&mutex->wait_lock, flags);
+
+ /* wait to be given the mutex */
+ for (;;) {
+ if (list_empty(&waiter.list))
+ break;
+ if (unlikely(signal_pending(current)))
+ goto interrupted;
+ schedule();
+ set_task_state(tsk, TASK_INTERRUPTIBLE);
+ }
+
+ tsk->state = TASK_RUNNING;
+ return 0;
+
+interrupted:
+ spin_lock_irqsave(&mutex->wait_lock, flags);
+
+ /* we may still have been given the mutex */
+ ret = 0;
+ if (!list_empty(&waiter.list)) {
+ list_del(&waiter.list);
+ ret = -EINTR;
+ }
+
+ spin_unlock_irqrestore(&mutex->wait_lock, flags);
+ if (ret == -EINTR)
+ put_task_struct(current);
+ return ret;
+}
+
+EXPORT_SYMBOL(__down_interruptible);
+
+/*
+ * release a single token back to a mutex
+ * - entered with lock held and interrupts disabled
+ * - the queue will not be empty
+ */
+void __up(struct mutex *mutex)
+{
+ struct mutex_waiter *waiter;
+ struct task_struct *tsk;
+
+ /* grant the token to the process at the front of the queue */
+ waiter = list_entry(mutex->wait_list.next, struct mutex_waiter, list);
+
+ /* we must be careful not to touch 'waiter' after we set ->task = NULL.
+ * - it is an allocated on the waiter's stack and may become invalid at
+ * any time after that point (due to a wakeup from another source).
+ */
+ list_del_init(&waiter->list);
+ tsk = waiter->task;
+#ifdef CONFIG_DEBUG_MUTEX_OWNER
+ mutex->__owner = tsk;
+#endif
+ mb();
+ waiter->task = NULL;
+ wake_up_process(tsk);
+ put_task_struct(tsk);
+}
+
+EXPORT_SYMBOL(__up);
+
+/*
+ * report an up() that doesn't match a down()
+ */
+#ifdef CONFIG_DEBUG_MUTEX_OWNER
+void __up_bad(struct mutex *mutex)
+{
+ if (!mutex->__owner) {
+ printk(KERN_ERR
+ "BUG: process %d [%s] releasing unowned mutex\n",
+ current->pid,
+ current->comm);
+ }
+ else {
+ printk(KERN_ERR
+ "BUG: process %d [%s] releasing mutex owned by %d [%s]\n",
+ current->pid,
+ current->comm,
+ mutex->__owner->pid,
+ mutex->__owner->comm);
+ }
+}
+
+EXPORT_SYMBOL(__up_bad);
+#endif
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/lib/semaphore-sleepers.c linux-2.6.15-rc5-mutex/lib/semaphore-sleepers.c
--- /warthog/kernels/linux-2.6.15-rc5/lib/semaphore-sleepers.c 2005-11-01 13:19:22.000000000 +0000
+++ linux-2.6.15-rc5-mutex/lib/semaphore-sleepers.c 2005-12-12 17:58:35.000000000 +0000
@@ -49,12 +49,12 @@
* we cannot lose wakeup events.
*/

-fastcall void __up(struct semaphore *sem)
+fastcall void __up_sem(struct semaphore *sem)
{
wake_up(&sem->wait);
}

-fastcall void __sched __down(struct semaphore * sem)
+fastcall void __sched __down_sem(struct semaphore * sem)
{
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
@@ -91,7 +91,7 @@ fastcall void __sched __down(struct sema
tsk->state = TASK_RUNNING;
}

-fastcall int __sched __down_interruptible(struct semaphore * sem)
+fastcall int __sched __down_sem_interruptible(struct semaphore * sem)
{
int retval = 0;
struct task_struct *tsk = current;
@@ -154,7 +154,7 @@ fastcall int __sched __down_interruptibl
* single "cmpxchg" without failure cases,
* but then it wouldn't work on a 386.
*/
-fastcall int __down_trylock(struct semaphore * sem)
+fastcall int __down_sem_trylock(struct semaphore * sem)
{
int sleepers;
unsigned long flags;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

David Howells

unread,
Dec 12, 2005, 7:00:25 PM12/12/05
to
The attached patch modifies the first half of the include files to use the new
mutex functions.

Signed-Off-By: David Howells <dhow...@redhat.com>
---

warthog>diffstat -p1 mutex-include-1-2615rc5.diff
include/linux/agpgart.h | 2 +-
include/linux/audit.h | 2 +-
include/linux/backlight.h | 2 +-
include/linux/cpu.h | 2 +-
include/linux/cpufreq.h | 2 +-
include/linux/devfs_fs_kernel.h | 2 +-
include/linux/device.h | 6 +++---
include/linux/ext3_fs_i.h | 2 +-
include/linux/fs.h | 17 +++++++++--------
include/linux/gameport.h | 2 +-
include/linux/generic_serial.h | 2 +-
include/linux/hil_mlc.h | 8 ++++----
include/linux/hp_sdc.h | 2 +-
include/linux/i2c.h | 6 +++---
include/linux/i2o.h | 8 ++++----
include/linux/ide.h | 10 +++++-----
include/linux/if_pppox.h | 2 +-
include/linux/input.h | 2 +-
include/linux/isdn.h | 4 ++--
include/linux/jbd.h | 6 +++---
include/linux/jffs2_fs_i.h | 4 ++--
include/linux/jffs2_fs_sb.h | 6 +++---
include/linux/kernelcapi.h | 2 +-
include/linux/kobj_map.h | 4 ++--
include/linux/kthread.h | 5 +++--
include/linux/lcd.h | 2 +-
include/linux/libps2.h | 2 +-
include/linux/lockd/lockd.h | 4 ++--
include/linux/loop.h | 6 +++---
include/linux/lp.h | 4 ++--
include/linux/memory.h | 5 ++---
include/linux/msdos_fs.h | 2 +-
include/linux/mtd/blktrans.h | 4 ++--
include/linux/mtd/doc2000.h | 4 ++--
include/linux/nbd.h | 2 +-
include/linux/ncp_fs_i.h | 2 +-
include/linux/ncp_fs_sb.h | 4 ++--
include/linux/netfilter/nfnetlink.h | 2 +-
include/linux/parport.h | 4 ++--
include/linux/quota.h | 7 ++++---
include/linux/raid/md.h | 2 +-
include/linux/raid/md_k.h | 2 +-
include/linux/reiserfs_fs_sb.h | 6 +++---
include/linux/rtnetlink.h | 2 +-
44 files changed, 89 insertions(+), 87 deletions(-)

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/agpgart.h linux-2.6.15-rc5-mutex/include/linux/agpgart.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/agpgart.h 2005-03-02 12:08:56.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/agpgart.h 2005-12-12 19:30:17.000000000 +0000
@@ -201,7 +201,7 @@ struct agp_file_private {
};

struct agp_front_data {
- struct semaphore agp_mutex;
+ struct mutex agp_mutex;
struct agp_controller *current_controller;
struct agp_controller *controllers;
struct agp_file_private *file_priv_list;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/audit.h linux-2.6.15-rc5-mutex/include/linux/audit.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/audit.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/audit.h 2005-12-12 19:39:56.000000000 +0000
@@ -283,7 +283,7 @@ extern void audit_send_reply(int pi
int done, int multi,
void *payload, int size);
extern void audit_log_lost(const char *message);
-extern struct semaphore audit_netlink_sem;
+extern struct mutex audit_netlink_sem;
#else
#define audit_log(c,g,t,f,...) do { ; } while (0)
#define audit_log_start(c,g,t) ({ NULL; })
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/backlight.h linux-2.6.15-rc5-mutex/include/linux/backlight.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/backlight.h 2005-03-02 12:08:56.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/backlight.h 2005-12-12 19:44:11.000000000 +0000
@@ -39,7 +39,7 @@ struct backlight_device {
/* This protects the 'props' field. If 'props' is NULL, the driver that
registered this device has been unloaded, and if class_get_devdata()
points to something in the body of that driver, it is also invalid. */
- struct semaphore sem;
+ struct mutex sem;
/* If this is NULL, the backing module is unloaded */
struct backlight_properties *props;
/* The framebuffer notifier block */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/cpufreq.h linux-2.6.15-rc5-mutex/include/linux/cpufreq.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/cpufreq.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/cpufreq.h 2005-12-12 19:30:49.000000000 +0000
@@ -82,7 +82,7 @@ struct cpufreq_policy {
unsigned int policy; /* see above */
struct cpufreq_governor *governor; /* see below */

- struct semaphore lock; /* CPU ->setpolicy or ->target may
+ struct mutex lock; /* CPU ->setpolicy or ->target may
only be called once a time */

struct work_struct update; /* if update_policy() needs to be
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/cpu.h linux-2.6.15-rc5-mutex/include/linux/cpu.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/cpu.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/cpu.h 2005-12-12 22:12:49.000000000 +0000
@@ -23,7 +23,7 @@
#include <linux/node.h>
#include <linux/compiler.h>
#include <linux/cpumask.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

struct cpu {
int node_id; /* The node which contains the CPU */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/devfs_fs_kernel.h linux-2.6.15-rc5-mutex/include/linux/devfs_fs_kernel.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/devfs_fs_kernel.h 2004-06-18 13:42:16.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/devfs_fs_kernel.h 2005-12-12 22:12:49.000000000 +0000
@@ -6,7 +6,7 @@
#include <linux/spinlock.h>
#include <linux/types.h>

-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

#define DEVFS_SUPER_MAGIC 0x1373

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/device.h linux-2.6.15-rc5-mutex/include/linux/device.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/device.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/device.h 2005-12-12 22:12:49.000000000 +0000
@@ -19,7 +19,7 @@
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pm.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>
#include <asm/atomic.h>

#define DEVICE_NAME_SIZE 50
@@ -146,7 +146,7 @@ struct class {
struct subsystem subsys;
struct list_head children;
struct list_head interfaces;
- struct semaphore sem; /* locks both the children and interfaces lists */
+ struct mutex sem; /* locks both the children and interfaces lists */

struct class_attribute * class_attrs;
struct class_device_attribute * class_dev_attrs;
@@ -310,7 +310,7 @@ struct device {
char bus_id[BUS_ID_SIZE]; /* position on parent bus */
struct device_attribute uevent_attr;

- struct semaphore sem; /* semaphore to synchronize calls to
+ struct mutex sem; /* semaphore to synchronize calls to
* its driver.
*/

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/ext3_fs_i.h linux-2.6.15-rc5-mutex/include/linux/ext3_fs_i.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/ext3_fs_i.h 2005-06-22 13:52:32.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/ext3_fs_i.h 2005-12-12 17:34:02.000000000 +0000
@@ -131,7 +131,7 @@ struct ext3_inode_info {
* during recovery. Hence we must fix the get_block-vs-truncate race
* by other means, so we have truncate_sem.
*/
- struct semaphore truncate_sem;
+ struct mutex truncate_sem;
struct inode vfs_inode;
};

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/fs.h linux-2.6.15-rc5-mutex/include/linux/fs.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/fs.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/fs.h 2005-12-12 22:12:49.000000000 +0000
@@ -10,6 +10,7 @@
#include <linux/limits.h>
#include <linux/ioctl.h>
#include <linux/rcuref.h>
+#include <linux/semaphore.h>

/*
* It's silly to have NR_OPEN bigger than NR_FILE, but you can change
@@ -220,9 +221,9 @@ extern int dir_notify_enable;
#include <linux/prio_tree.h>
#include <linux/init.h>
#include <linux/sched.h>
+#include <linux/semaphore.h>

#include <asm/atomic.h>
-#include <asm/semaphore.h>
#include <asm/byteorder.h>

struct iovec;
@@ -368,8 +369,8 @@ struct block_device {
dev_t bd_dev; /* not a kdev_t - it's a search key */
struct inode * bd_inode; /* will die */
int bd_openers;
- struct semaphore bd_sem; /* open/close mutex */
- struct semaphore bd_mount_sem; /* mount mutex */
+ struct mutex bd_sem; /* open/close mutex */
+ struct mutex bd_mount_sem; /* mount mutex */
struct list_head bd_inodes;
void * bd_holder;
int bd_holders;
@@ -453,7 +454,7 @@ struct inode {
unsigned long i_blocks;
unsigned short i_bytes;
spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
- struct semaphore i_sem;
+ struct mutex i_sem;
struct rw_semaphore i_alloc_sem;
struct inode_operations *i_op;
struct file_operations *i_fop; /* former ->i_op->default_file_ops */
@@ -480,7 +481,7 @@ struct inode {

#ifdef CONFIG_INOTIFY
struct list_head inotify_watches; /* watches on this inode */
- struct semaphore inotify_sem; /* protects the watches list */
+ struct mutex inotify_sem; /* protects the watches list */
#endif

unsigned long i_state;
@@ -790,7 +791,7 @@ struct super_block {
unsigned long s_magic;
struct dentry *s_root;
struct rw_semaphore s_umount;
- struct semaphore s_lock;
+ struct mutex s_lock;
int s_count;
int s_syncing;
int s_need_sync_fs;
@@ -819,7 +820,7 @@ struct super_block {
* The next field is for VFS *only*. No filesystems have any business
* even looking at it. You had been warned.
*/
- struct semaphore s_vfs_rename_sem; /* Kludge */
+ struct mutex s_vfs_rename_sem; /* Kludge */

/* Granuality of c/m/atime in ns.
Cannot be worse than a second */
@@ -1496,7 +1497,7 @@ extern void destroy_inode(struct inode *
extern struct inode *new_inode(struct super_block *);
extern int remove_suid(struct dentry *);
extern void remove_dquot_ref(struct super_block *, int, struct list_head *);
-extern struct semaphore iprune_sem;
+extern struct mutex iprune_sem;

extern void __insert_inode_hash(struct inode *, unsigned long hashval);
extern void remove_inode_hash(struct inode *);
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/gameport.h linux-2.6.15-rc5-mutex/include/linux/gameport.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/gameport.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/gameport.h 2005-12-12 19:31:08.000000000 +0000
@@ -40,7 +40,7 @@ struct gameport {
struct gameport *parent, *child;

struct gameport_driver *drv;
- struct semaphore drv_sem; /* protects serio->drv so attributes can pin driver */
+ struct mutex drv_sem; /* protects serio->drv so attributes can pin driver */

struct device dev;
unsigned int registered; /* port has been fully registered with driver core */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/generic_serial.h linux-2.6.15-rc5-mutex/include/linux/generic_serial.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/generic_serial.h 2005-06-22 13:52:32.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/generic_serial.h 2005-12-12 19:31:20.000000000 +0000
@@ -34,7 +34,7 @@ struct gs_port {
int xmit_head;
int xmit_tail;
int xmit_cnt;
- struct semaphore port_write_sem;
+ struct mutex port_write_sem;
int flags;
wait_queue_head_t open_wait;
wait_queue_head_t close_wait;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/hil_mlc.h linux-2.6.15-rc5-mutex/include/linux/hil_mlc.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/hil_mlc.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/hil_mlc.h 2005-12-12 22:12:49.000000000 +0000
@@ -34,7 +34,7 @@
#include <linux/hil.h>
#include <linux/time.h>
#include <linux/interrupt.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>
#include <linux/serio.h>
#include <linux/list.h>

@@ -133,14 +133,14 @@ struct hil_mlc {
int istarted, ostarted;

hil_mlc_cts *cts;
- struct semaphore csem; /* Raised when loop idle */
+ struct mutex csem; /* Raised when loop idle */

hil_mlc_out *out;
- struct semaphore osem; /* Raised when outpacket dispatched */
+ struct mutex osem; /* Raised when outpacket dispatched */
hil_packet opacket;

hil_mlc_in *in;
- struct semaphore isem; /* Raised when a packet arrives */
+ struct mutex isem; /* Raised when a packet arrives */
hil_packet ipacket[16];
hil_packet imatch;
int icount;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/hp_sdc.h linux-2.6.15-rc5-mutex/include/linux/hp_sdc.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/hp_sdc.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/hp_sdc.h 2005-12-12 19:43:52.000000000 +0000
@@ -68,7 +68,7 @@ typedef struct {
uint8_t *seq; /* commands/data for the transaction */
union {
hp_sdc_irqhook *irqhook; /* Callback, isr or tasklet context */
- struct semaphore *semaphore; /* Semaphore to sleep on. */
+ struct mutex *semaphore; /* Semaphore to sleep on. */
} act;
} hp_sdc_transaction;
int hp_sdc_enqueue_transaction(hp_sdc_transaction *this);
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/i2c.h linux-2.6.15-rc5-mutex/include/linux/i2c.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/i2c.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/i2c.h 2005-12-12 22:12:49.000000000 +0000
@@ -32,7 +32,7 @@
#include <linux/mod_devicetable.h>
#include <linux/device.h> /* for struct device */
#include <linux/sched.h> /* for completion */
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

/* --- For i2c-isa ---------------------------------------------------- */

@@ -222,8 +222,8 @@ struct i2c_adapter {
int (*client_unregister)(struct i2c_client *);

/* data fields that are valid for all devices */
- struct semaphore bus_lock;
- struct semaphore clist_lock;
+ struct mutex bus_lock;
+ struct mutex clist_lock;

int timeout;
int retries;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/i2o.h linux-2.6.15-rc5-mutex/include/linux/i2o.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/i2o.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/i2o.h 2005-12-12 22:12:49.000000000 +0000
@@ -30,9 +30,9 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/workqueue.h> /* work_struct */
+#include <linux/semaphore.h>

#include <asm/io.h>
-#include <asm/semaphore.h> /* Needed for MUTEX init macros */

/* message queue empty */
#define I2O_QUEUE_EMPTY 0xffffffff
@@ -69,7 +69,7 @@ struct i2o_device {

struct device device;

- struct semaphore lock; /* device lock */
+ struct mutex lock; /* device lock */
};

/*
@@ -117,7 +117,7 @@ struct i2o_driver {
void (*notify_device_add) (struct i2o_device *);
void (*notify_device_remove) (struct i2o_device *);

- struct semaphore lock;
+ struct mutex lock;
};

/*
@@ -181,7 +181,7 @@ struct i2o_controller {
struct i2o_dma hrt; /* HW Resource Table */
i2o_lct *lct; /* Logical Config Table */
struct i2o_dma dlct; /* Temp LCT */
- struct semaphore lct_lock; /* Lock for LCT updates */
+ struct mutex lct_lock; /* Lock for LCT updates */
struct i2o_dma status_block; /* IOP status block */

struct i2o_io base; /* controller messaging unit */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/ide.h linux-2.6.15-rc5-mutex/include/linux/ide.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/ide.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/ide.h 2005-12-12 22:12:49.000000000 +0000
@@ -18,10 +18,10 @@
#include <linux/bio.h>
#include <linux/device.h>
#include <linux/pci.h>
+#include <linux/semaphore.h>
#include <asm/byteorder.h>
#include <asm/system.h>
#include <asm/io.h>
-#include <asm/semaphore.h>

/*
* This is the multiple IDE interface driver, as evolved from hd.c.
@@ -759,7 +759,7 @@ typedef struct ide_drive_s {
int crc_count; /* crc counter to reduce drive speed */
struct list_head list;
struct device gendev;
- struct semaphore gendev_rel_sem; /* to deal with device release() */
+ struct mutex gendev_rel_sem; /* to deal with device release() */
} ide_drive_t;

#define to_ide_device(dev)container_of(dev, ide_drive_t, gendev)
@@ -915,7 +915,7 @@ typedef struct hwif_s {
unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */

struct device gendev;
- struct semaphore gendev_rel_sem; /* To deal with device release() */
+ struct mutex gendev_rel_sem; /* To deal with device release() */

void *hwif_data; /* extra hwif data */

@@ -1000,7 +1000,7 @@ typedef struct ide_settings_s {
struct ide_settings_s *next;
} ide_settings_t;

-extern struct semaphore ide_setting_sem;
+extern struct mutex ide_setting_sem;
extern int ide_add_setting(ide_drive_t *drive, const char *name, int rw, int read_ioctl, int write_ioctl, int data_type, int min, int max, int mul_factor, int div_factor, void *data, ide_procset_t *set);
extern ide_settings_t *ide_find_setting_by_name(ide_drive_t *drive, char *name);
extern int ide_read_setting(ide_drive_t *t, ide_settings_t *setting);
@@ -1458,7 +1458,7 @@ extern const ide_pio_timings_t ide_pio_t


extern spinlock_t ide_lock;
-extern struct semaphore ide_cfg_sem;
+extern struct mutex ide_cfg_sem;
/*
* Structure locking:
*
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/if_pppox.h linux-2.6.15-rc5-mutex/include/linux/if_pppox.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/if_pppox.h 2005-06-22 13:52:32.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/if_pppox.h 2005-12-12 22:12:49.000000000 +0000
@@ -24,7 +24,7 @@
#include <linux/if_ether.h>
#include <linux/if.h>
#include <linux/netdevice.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>
#include <linux/ppp_channel.h>
#endif /* __KERNEL__ */

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/input.h linux-2.6.15-rc5-mutex/include/linux/input.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/input.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/input.h 2005-12-12 17:51:08.000000000 +0000
@@ -888,7 +888,7 @@ struct input_dev {

struct input_handle *grab;

- struct semaphore sem; /* serializes open and close operations */
+ struct mutex sem; /* serializes open and close operations */
unsigned int users;

struct class_device cdev;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/isdn.h linux-2.6.15-rc5-mutex/include/linux/isdn.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/isdn.h 2005-11-01 13:19:20.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/isdn.h 2005-12-12 19:32:14.000000000 +0000
@@ -515,7 +515,7 @@ typedef struct modem_info {
struct termios normal_termios; /* For saving termios structs */
struct termios callout_termios;
wait_queue_head_t open_wait, close_wait;
- struct semaphore write_sem;
+ struct mutex write_sem;
spinlock_t readlock;
} modem_info;

@@ -625,7 +625,7 @@ typedef struct isdn_devt {
int v110emu[ISDN_MAX_CHANNELS]; /* V.110 emulator-mode 0=none */
atomic_t v110use[ISDN_MAX_CHANNELS]; /* Usage-Semaphore for stream */
isdn_v110_stream *v110[ISDN_MAX_CHANNELS]; /* V.110 private data */
- struct semaphore sem; /* serialize list access*/
+ struct mutex sem; /* serialize list access*/
unsigned long global_features;
} isdn_dev;

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/jbd.h linux-2.6.15-rc5-mutex/include/linux/jbd.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/jbd.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/jbd.h 2005-12-12 22:12:49.000000000 +0000
@@ -27,7 +27,7 @@
#include <linux/journal-head.h>
#include <linux/stddef.h>
#include <linux/bit_spinlock.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>
#endif

#define journal_oom_retry 1
@@ -644,7 +644,7 @@ struct journal_s
int j_barrier_count;

/* The barrier lock itself */
- struct semaphore j_barrier;
+ struct mutex j_barrier;

/*
* Transactions: The current running transaction...
@@ -686,7 +686,7 @@ struct journal_s
wait_queue_head_t j_wait_updates;

/* Semaphore for locking against concurrent checkpoints */
- struct semaphore j_checkpoint_sem;
+ struct mutex j_checkpoint_sem;

/*
* Journal head: identifies the first unused block in the journal.
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/jffs2_fs_i.h linux-2.6.15-rc5-mutex/include/linux/jffs2_fs_i.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/jffs2_fs_i.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/jffs2_fs_i.h 2005-12-12 22:12:49.000000000 +0000
@@ -5,7 +5,7 @@

#include <linux/version.h>
#include <linux/rbtree.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

struct jffs2_inode_info {
/* We need an internal semaphore similar to inode->i_sem.
@@ -14,7 +14,7 @@ struct jffs2_inode_info {
before letting GC proceed. Or we'd have to put ugliness
into the GC code so it didn't attempt to obtain the i_sem
for the inode(s) which are already locked */
- struct semaphore sem;
+ struct mutex sem;

/* The highest (datanode) version number used for this ino */
uint32_t highest_version;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/jffs2_fs_sb.h linux-2.6.15-rc5-mutex/include/linux/jffs2_fs_sb.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/jffs2_fs_sb.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/jffs2_fs_sb.h 2005-12-12 22:12:49.000000000 +0000
@@ -7,7 +7,7 @@
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/completion.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>
#include <linux/timer.h>
#include <linux/wait.h>
#include <linux/list.h>
@@ -35,7 +35,7 @@ struct jffs2_sb_info {
struct completion gc_thread_start; /* GC thread start completion */
struct completion gc_thread_exit; /* GC thread exit completion port */

- struct semaphore alloc_sem; /* Used to protect all the following
+ struct mutex alloc_sem; /* Used to protect all the following
fields, and also to protect against
out-of-order writing of nodes. And GC. */
uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER
@@ -93,7 +93,7 @@ struct jffs2_sb_info {
/* Sem to allow jffs2_garbage_collect_deletion_dirent to
drop the erase_completion_lock while it's holding a pointer
to an obsoleted node. I don't like this. Alternatives welcomed. */
- struct semaphore erase_free_sem;
+ struct mutex erase_free_sem;

uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/kernelcapi.h linux-2.6.15-rc5-mutex/include/linux/kernelcapi.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/kernelcapi.h 2004-09-16 12:06:22.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/kernelcapi.h 2005-12-12 19:32:42.000000000 +0000
@@ -62,7 +62,7 @@ struct capi20_appl {
unsigned long nrecvdatapkt;
unsigned long nsentctlpkt;
unsigned long nsentdatapkt;
- struct semaphore recv_sem;
+ struct mutex recv_sem;
struct sk_buff_head recv_queue;
struct work_struct recv_work;
int release_in_progress;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/kobj_map.h linux-2.6.15-rc5-mutex/include/linux/kobj_map.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/kobj_map.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/kobj_map.h 2005-12-12 22:12:49.000000000 +0000
@@ -1,6 +1,6 @@
#ifdef __KERNEL__

-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

typedef struct kobject *kobj_probe_t(dev_t, int *, void *);
struct kobj_map;
@@ -9,6 +9,6 @@ int kobj_map(struct kobj_map *, dev_t, u
kobj_probe_t *, int (*)(dev_t, void *), void *);
void kobj_unmap(struct kobj_map *, dev_t, unsigned long);
struct kobject *kobj_lookup(struct kobj_map *, dev_t, int *);
-struct kobj_map *kobj_map_init(kobj_probe_t *, struct semaphore *);
+struct kobj_map *kobj_map_init(kobj_probe_t *, struct mutex *);

#endif
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/kthread.h linux-2.6.15-rc5-mutex/include/linux/kthread.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/kthread.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/kthread.h 2005-12-12 22:12:49.000000000 +0000
@@ -3,6 +3,7 @@
/* Simple interface for creating and stopping kernel threads without mess. */
#include <linux/err.h>
#include <linux/sched.h>
+#include <linux/semaphore.h>

/**
* kthread_create: create a kthread.
@@ -72,14 +73,14 @@ int kthread_stop(struct task_struct *k);
/**
* kthread_stop_sem: stop a thread created by kthread_create().
* @k: thread created by kthread_create().
- * @s: semaphore that @k waits on while idle.
+ * @s: mutex that @k waits on while idle.
*
* Does essentially the same thing as kthread_stop() above, but wakes
* @k by calling up(@s).
*
* Returns the result of threadfn(), or -EINTR if wake_up_process()
* was never called. */
-int kthread_stop_sem(struct task_struct *k, struct semaphore *s);
+int kthread_stop_sem(struct task_struct *k, struct mutex *s);

/**
* kthread_should_stop: should this kthread return now?
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/lcd.h linux-2.6.15-rc5-mutex/include/linux/lcd.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/lcd.h 2005-03-02 12:08:57.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/lcd.h 2005-12-12 19:32:48.000000000 +0000
@@ -38,7 +38,7 @@ struct lcd_device {
/* This protects the 'props' field. If 'props' is NULL, the driver that
registered this device has been unloaded, and if class_get_devdata()
points to something in the body of that driver, it is also invalid. */
- struct semaphore sem;
+ struct mutex sem;
/* If this is NULL, the backing module is unloaded */
struct lcd_properties *props;
/* The framebuffer notifier block */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/libps2.h linux-2.6.15-rc5-mutex/include/linux/libps2.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/libps2.h 2005-08-30 13:56:36.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/libps2.h 2005-12-12 18:02:54.000000000 +0000
@@ -28,7 +28,7 @@ struct ps2dev {
struct serio *serio;

/* Ensures that only one command is executing at a time */
- struct semaphore cmd_sem;
+ struct mutex cmd_sem;

/* Used to signal completion from interrupt handler */
wait_queue_head_t wait;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/lockd/lockd.h linux-2.6.15-rc5-mutex/include/linux/lockd/lockd.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/lockd/lockd.h 2005-08-30 13:56:36.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/lockd/lockd.h 2005-12-12 17:38:48.000000000 +0000
@@ -53,7 +53,7 @@ struct nlm_host {
u32 h_nsmstate; /* true remote NSM state */
u32 h_pidcount; /* Pseudopids */
atomic_t h_count; /* reference count */
- struct semaphore h_sema; /* mutex for pmap binding */
+ struct mutex h_sema; /* mutex for pmap binding */
unsigned long h_nextrebind; /* next portmap call */
unsigned long h_expires; /* eligible for GC */
struct list_head h_lockowners; /* Lockowners for the client */
@@ -99,7 +99,7 @@ struct nlm_file {
struct nlm_block * f_blocks; /* blocked locks */
unsigned int f_locks; /* guesstimate # of locks */
unsigned int f_count; /* reference count */
- struct semaphore f_sema; /* avoid concurrent access */
+ struct mutex f_sema; /* avoid concurrent access */
int f_hash; /* hash of f_handle */
};

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/loop.h linux-2.6.15-rc5-mutex/include/linux/loop.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/loop.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/loop.h 2005-12-12 17:45:34.000000000 +0000
@@ -58,9 +58,9 @@ struct loop_device {
struct bio *lo_bio;
struct bio *lo_biotail;
int lo_state;
- struct semaphore lo_sem;
- struct semaphore lo_ctl_mutex;
- struct semaphore lo_bh_mutex;
+ struct mutex lo_sem;
+ struct mutex lo_ctl_mutex;
+ struct mutex lo_bh_mutex;
int lo_pending;

request_queue_t *lo_queue;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/lp.h linux-2.6.15-rc5-mutex/include/linux/lp.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/lp.h 2005-03-02 12:08:57.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/lp.h 2005-12-12 22:12:49.000000000 +0000
@@ -99,7 +99,7 @@
#ifdef __KERNEL__

#include <linux/wait.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

/* Magic numbers for defining port-device mappings */
#define LP_PARPORT_UNSPEC -4
@@ -145,7 +145,7 @@ struct lp_struct {
#endif
wait_queue_head_t waitq;
unsigned int last_error;
- struct semaphore port_mutex;
+ struct mutex port_mutex;
wait_queue_head_t dataq;
long timeout;
unsigned int best_mode;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/memory.h linux-2.6.15-rc5-mutex/include/linux/memory.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/memory.h 2005-12-08 16:23:54.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/memory.h 2005-12-12 22:12:49.000000000 +0000
@@ -18,8 +18,7 @@
#include <linux/sysdev.h>
#include <linux/node.h>
#include <linux/compiler.h>
-
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

struct memory_block {
unsigned long phys_index;
@@ -30,7 +29,7 @@ struct memory_block {
* created long after the critical areas during
* initialization.
*/
- struct semaphore state_sem;
+ struct mutex state_sem;
int phys_device; /* to which fru does this belong? */
void *hw; /* optional pointer to fw/hw data */
int (*phys_callback)(struct memory_block *);
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/msdos_fs.h linux-2.6.15-rc5-mutex/include/linux/msdos_fs.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/msdos_fs.h 2005-12-08 16:23:55.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/msdos_fs.h 2005-12-12 17:34:19.000000000 +0000
@@ -226,7 +226,7 @@ struct msdos_sb_info {
unsigned long max_cluster; /* maximum cluster number */
unsigned long root_cluster; /* first cluster of the root directory */
unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
- struct semaphore fat_lock;
+ struct mutex fat_lock;
unsigned int prev_free; /* previously allocated cluster number */
unsigned int free_clusters; /* -1 if undefined */
struct fat_mount_options options;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/mtd/blktrans.h linux-2.6.15-rc5-mutex/include/linux/mtd/blktrans.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/mtd/blktrans.h 2005-12-08 16:23:55.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/mtd/blktrans.h 2005-12-12 22:12:49.000000000 +0000
@@ -10,7 +10,7 @@
#ifndef __MTD_TRANS_H__
#define __MTD_TRANS_H__

-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

struct hd_geometry;
struct mtd_info;
@@ -22,7 +22,7 @@ struct mtd_blktrans_dev {
struct mtd_blktrans_ops *tr;
struct list_head list;
struct mtd_info *mtd;
- struct semaphore sem;
+ struct mutex sem;
int devnum;
int blksize;
unsigned long size;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/mtd/doc2000.h linux-2.6.15-rc5-mutex/include/linux/mtd/doc2000.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/mtd/doc2000.h 2005-12-08 16:23:55.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/mtd/doc2000.h 2005-12-12 22:12:49.000000000 +0000
@@ -15,7 +15,7 @@
#define __MTD_DOC2000_H__

#include <linux/mtd/mtd.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

#define DoC_Sig1 0
#define DoC_Sig2 1
@@ -187,7 +187,7 @@ struct DiskOnChip {
int numchips;
struct Nand *chips;
struct mtd_info *nextdoc;
- struct semaphore lock;
+ struct mutex lock;
};

int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]);
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/nbd.h linux-2.6.15-rc5-mutex/include/linux/nbd.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/nbd.h 2004-06-18 13:42:16.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/nbd.h 2005-12-12 19:33:00.000000000 +0000
@@ -49,7 +49,7 @@ struct nbd_device {
int magic;
spinlock_t queue_lock;
struct list_head queue_head;/* Requests are added here... */
- struct semaphore tx_lock;
+ struct mutex tx_lock;
struct gendisk *disk;
int blksize;
u64 bytesize;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/ncp_fs_i.h linux-2.6.15-rc5-mutex/include/linux/ncp_fs_i.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/ncp_fs_i.h 2004-10-19 10:42:17.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/ncp_fs_i.h 2005-12-12 19:33:05.000000000 +0000
@@ -19,7 +19,7 @@ struct ncp_inode_info {
__le32 DosDirNum;
__u8 volNumber;
__le32 nwattr;
- struct semaphore open_sem;
+ struct mutex open_sem;
atomic_t opened;
int access;
int flags;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/ncp_fs_sb.h linux-2.6.15-rc5-mutex/include/linux/ncp_fs_sb.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/ncp_fs_sb.h 2004-06-18 13:42:15.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/ncp_fs_sb.h 2005-12-12 19:33:16.000000000 +0000
@@ -51,7 +51,7 @@ struct ncp_server {
receive replies */

int lock; /* To prevent mismatch in protocols. */
- struct semaphore sem;
+ struct mutex sem;

int current_size; /* for packet preparation */
int has_subfunction;
@@ -96,7 +96,7 @@ struct ncp_server {
struct {
struct work_struct tq; /* STREAM/DGRAM: data/error ready */
struct ncp_request_reply* creq; /* STREAM/DGRAM: awaiting reply from this request */
- struct semaphore creq_sem; /* DGRAM only: lock accesses to rcv.creq */
+ struct mutex creq_sem; /* DGRAM only: lock accesses to rcv.creq */

unsigned int state; /* STREAM only: receiver state */
struct {
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/netfilter/nfnetlink.h linux-2.6.15-rc5-mutex/include/linux/netfilter/nfnetlink.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/netfilter/nfnetlink.h 2005-12-08 16:23:55.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/netfilter/nfnetlink.h 2005-12-12 19:41:44.000000000 +0000
@@ -129,7 +129,7 @@ extern void __nfa_fill(struct sk_buff *s
({ if (skb_tailroom(skb) < (int)NFA_SPACE(attrlen)) goto nfattr_failure; \
__nfa_fill(skb, attrtype, attrlen, data); })

-extern struct semaphore nfnl_sem;
+extern struct mutex nfnl_sem;

#define nfnl_shlock() down(&nfnl_sem)
#define nfnl_shlock_nowait() down_trylock(&nfnl_sem)
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/parport.h linux-2.6.15-rc5-mutex/include/linux/parport.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/parport.h 2005-06-22 13:52:33.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/parport.h 2005-12-12 22:12:49.000000000 +0000
@@ -101,9 +101,9 @@ typedef enum {
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <linux/wait.h>
+#include <linux/semaphore.h>
#include <asm/system.h>
#include <asm/ptrace.h>
-#include <asm/semaphore.h>

/* Define this later. */
struct parport;
@@ -254,7 +254,7 @@ enum ieee1284_phase {
struct ieee1284_info {
int mode;
volatile enum ieee1284_phase phase;
- struct semaphore irq;
+ struct mutex irq;
};

/* A parallel port */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/quota.h linux-2.6.15-rc5-mutex/include/linux/quota.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/quota.h 2005-12-08 16:23:55.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/quota.h 2005-12-12 22:12:49.000000000 +0000
@@ -38,6 +38,7 @@
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/spinlock.h>
+#include <linux/semaphore.h>

#define __DQUOT_VERSION__ "dquot_6.5.1"
#define __DQUOT_NUM_VERSION__ 6*10000+5*100+1
@@ -215,7 +216,7 @@ struct dquot {
struct list_head dq_inuse; /* List of all quotas */
struct list_head dq_free; /* Free list element */
struct list_head dq_dirty; /* List of dirty dquots */
- struct semaphore dq_lock; /* dquot IO lock */
+ struct mutex dq_lock; /* dquot IO lock */
atomic_t dq_count; /* Use count */
wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */
struct super_block *dq_sb; /* superblock this applies to */
@@ -285,8 +286,8 @@ struct quota_format_type {

struct quota_info {
unsigned int flags; /* Flags for diskquotas on this device */
- struct semaphore dqio_sem; /* lock device while I/O in progress */
- struct semaphore dqonoff_sem; /* Serialize quotaon & quotaoff */
+ struct mutex dqio_sem; /* lock device while I/O in progress */
+ struct mutex dqonoff_sem; /* Serialize quotaon & quotaoff */
struct rw_semaphore dqptr_sem; /* serialize ops using quota_info struct, pointers from inode to dquots */
struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */
struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/raid/md.h linux-2.6.15-rc5-mutex/include/linux/raid/md.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/raid/md.h 2005-12-08 16:23:55.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/raid/md.h 2005-12-12 22:12:49.000000000 +0000
@@ -19,7 +19,7 @@
#define _MD_H

#include <linux/blkdev.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>
#include <linux/major.h>
#include <linux/ioctl.h>
#include <linux/types.h>
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/raid/md_k.h linux-2.6.15-rc5-mutex/include/linux/raid/md_k.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/raid/md_k.h 2005-12-08 16:23:55.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/raid/md_k.h 2005-12-12 19:40:30.000000000 +0000
@@ -204,7 +204,7 @@ struct mddev_s
unsigned long recovery;

int in_sync; /* know to not need resync */
- struct semaphore reconfig_sem;
+ struct mutex reconfig_sem;
atomic_t active;

int changed; /* true if we might need to reread partition info */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/reiserfs_fs_sb.h linux-2.6.15-rc5-mutex/include/linux/reiserfs_fs_sb.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/reiserfs_fs_sb.h 2005-08-30 13:56:37.000000000 +0100
+++ linux-2.6.15-rc5-mutex/include/linux/reiserfs_fs_sb.h 2005-12-12 19:44:40.000000000 +0000
@@ -152,7 +152,7 @@ struct reiserfs_journal_list {
atomic_t j_nonzerolen;
atomic_t j_commit_left;
atomic_t j_older_commits_done; /* all commits older than this on disk */
- struct semaphore j_commit_lock;
+ struct mutex j_commit_lock;
unsigned long j_trans_id;
time_t j_timestamp;
struct reiserfs_list_bitmap *j_list_bitmap;
@@ -194,8 +194,8 @@ struct reiserfs_journal {
struct buffer_head *j_header_bh;

time_t j_trans_start_time; /* time this transaction started */
- struct semaphore j_lock;
- struct semaphore j_flush_sem;
+ struct mutex j_lock;
+ struct mutex j_flush_sem;
wait_queue_head_t j_join_wait; /* wait for current transaction to finish before starting new one */
atomic_t j_jlock; /* lock for j_join_wait */
int j_list_bitmap_index; /* number of next list bitmap to use */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/include/linux/rtnetlink.h linux-2.6.15-rc5-mutex/include/linux/rtnetlink.h
--- /warthog/kernels/linux-2.6.15-rc5/include/linux/rtnetlink.h 2005-11-01 13:19:21.000000000 +0000
+++ linux-2.6.15-rc5-mutex/include/linux/rtnetlink.h 2005-12-12 17:55:26.000000000 +0000
@@ -1032,7 +1032,7 @@ __rta_reserve(struct sk_buff *skb, int a

extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change);

-extern struct semaphore rtnl_sem;
+extern struct mutex rtnl_sem;

#define rtnl_shlock() down(&rtnl_sem)
#define rtnl_shlock_nowait() down_trylock(&rtnl_sem)

David Howells

unread,
Dec 12, 2005, 7:00:26 PM12/12/05
to
The attached patch modifies the files of the drivers/i* thru drivers/k* to use
the new mutex functions.

Signed-Off-By: David Howells <dhow...@redhat.com>
---
warthog>diffstat -p1 mutex-drivers-ItoK-2615rc5.diff
drivers/i2c/busses/i2c-ali1535.c | 2 +-
drivers/i2c/busses/i2c-amd756-s4882.c | 2 +-
drivers/i2c/busses/scx200_acb.c | 2 +-
drivers/i2c/chips/eeprom.c | 2 +-
drivers/i2c/chips/max6875.c | 4 ++--
drivers/i2c/chips/pcf8591.c | 2 +-
drivers/i2c/chips/tps65010.c | 2 +-
drivers/ide/ide.c | 4 ++--
drivers/ieee1394/dv1394-private.h | 2 +-
drivers/ieee1394/eth1394.c | 2 +-
drivers/ieee1394/hosts.h | 2 +-
drivers/ieee1394/ieee1394_core.c | 2 +-
drivers/ieee1394/ieee1394_core.h | 2 +-
drivers/ieee1394/ieee1394_types.h | 2 +-
drivers/ieee1394/nodemgr.c | 10 +++++-----
drivers/ieee1394/raw1394.c | 8 ++++----
drivers/infiniband/core/device.c | 2 +-
drivers/infiniband/core/ucm.c | 2 +-
drivers/infiniband/core/user_mad.c | 4 ++--
drivers/infiniband/core/uverbs.h | 4 ++--
drivers/infiniband/hw/mthca/mthca_cmd.c | 10 +++++-----
drivers/infiniband/hw/mthca/mthca_dev.h | 10 +++++-----
drivers/infiniband/hw/mthca/mthca_memfree.c | 2 +-
drivers/infiniband/hw/mthca/mthca_memfree.h | 6 +++---
drivers/infiniband/ulp/ipoib/ipoib.h | 6 +++---
drivers/infiniband/ulp/srp/ib_srp.h | 4 ++--
drivers/input/joystick/db9.c | 2 +-
drivers/input/joystick/gamecon.c | 2 +-
drivers/input/joystick/iforce/iforce.h | 4 ++--
drivers/input/joystick/turbografx.c | 2 +-
drivers/input/keyboard/atkbd.c | 2 +-
drivers/input/keyboard/hil_kbd.c | 2 +-
drivers/input/misc/hp_sdc_rtc.c | 4 ++--
drivers/input/mouse/hil_ptr.c | 2 +-
drivers/input/serio/hp_sdc.c | 4 ++--
drivers/input/serio/hp_sdc_mlc.c | 2 +-
drivers/isdn/capi/capi.c | 2 +-
37 files changed, 64 insertions(+), 64 deletions(-)

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/busses/i2c-ali1535.c linux-2.6.15-rc5-mutex/drivers/i2c/busses/i2c-ali1535.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/busses/i2c-ali1535.c 2005-12-08 16:23:39.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/i2c/busses/i2c-ali1535.c 2005-12-12 22:08:48.000000000 +0000
@@ -63,7 +63,7 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <asm/io.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>


/* ALI1535 SMBus address offsets */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/busses/i2c-amd756-s4882.c linux-2.6.15-rc5-mutex/drivers/i2c/busses/i2c-amd756-s4882.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/busses/i2c-amd756-s4882.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/i2c/busses/i2c-amd756-s4882.c 2005-12-12 21:31:04.000000000 +0000
@@ -45,7 +45,7 @@ static struct i2c_adapter *s4882_adapter
static struct i2c_algorithm *s4882_algo;

/* Wrapper access functions for multiplexed SMBus */
-static struct semaphore amd756_lock;
+static struct mutex amd756_lock;

static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr,
unsigned short flags, char read_write,
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/busses/scx200_acb.c linux-2.6.15-rc5-mutex/drivers/i2c/busses/scx200_acb.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/busses/scx200_acb.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/i2c/busses/scx200_acb.c 2005-12-12 21:31:22.000000000 +0000
@@ -84,7 +84,7 @@ struct scx200_acb_iface
struct scx200_acb_iface *next;
struct i2c_adapter adapter;
unsigned base;


- struct semaphore sem;
+ struct mutex sem;

/* State machine data */
enum scx200_acb_state state;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/chips/eeprom.c linux-2.6.15-rc5-mutex/drivers/i2c/chips/eeprom.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/chips/eeprom.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/i2c/chips/eeprom.c 2005-12-12 21:31:31.000000000 +0000
@@ -54,7 +54,7 @@ enum eeprom_nature {
/* Each client has this additional data */
struct eeprom_data {
struct i2c_client client;
- struct semaphore update_lock;
+ struct mutex update_lock;
u8 valid; /* bitfield, bit!=0 if slice is valid */
unsigned long last_updated[8]; /* In jiffies, 8 slices */
u8 data[EEPROM_SIZE]; /* Register values */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/chips/max6875.c linux-2.6.15-rc5-mutex/drivers/i2c/chips/max6875.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/chips/max6875.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/i2c/chips/max6875.c 2005-12-12 22:08:48.000000000 +0000
@@ -31,7 +31,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

/* Do not scan - the MAX6875 access method will write to some EEPROM chips */
static unsigned short normal_i2c[] = {I2C_CLIENT_END};
@@ -54,7 +54,7 @@ I2C_CLIENT_INSMOD_1(max6875);
/* Each client has this additional data */
struct max6875_data {
struct i2c_client client;
- struct semaphore update_lock;
+ struct mutex update_lock;

u32 valid;
u8 data[USER_EEPROM_SIZE];
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/chips/pcf8591.c linux-2.6.15-rc5-mutex/drivers/i2c/chips/pcf8591.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/chips/pcf8591.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/i2c/chips/pcf8591.c 2005-12-12 21:31:48.000000000 +0000
@@ -74,7 +74,7 @@ MODULE_PARM_DESC(input_mode,

struct pcf8591_data {
struct i2c_client client;
- struct semaphore update_lock;
+ struct mutex update_lock;

u8 control;
u8 aout;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/chips/tps65010.c linux-2.6.15-rc5-mutex/drivers/i2c/chips/tps65010.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/i2c/chips/tps65010.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/i2c/chips/tps65010.c 2005-12-12 21:31:36.000000000 +0000
@@ -81,7 +81,7 @@ enum tps_model {

struct tps65010 {
struct i2c_client client;


- struct semaphore lock;
+ struct mutex lock;

int irq;
struct work_struct work;
struct dentry *file;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/ide/ide.c linux-2.6.15-rc5-mutex/drivers/ide/ide.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/ide/ide.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/ide/ide.c 2005-12-12 17:55:02.000000000 +0000
@@ -222,7 +222,7 @@ static void init_hwif_data(ide_hwif_t *h
hwif->mwdma_mask = 0x80; /* disable all mwdma */
hwif->swdma_mask = 0x80; /* disable all swdma */

- sema_init(&hwif->gendev_rel_sem, 0);
+ init_MUTEX_LOCKED(&hwif->gendev_rel_sem);

default_hwif_iops(hwif);
default_hwif_transport(hwif);
@@ -245,7 +245,7 @@ static void init_hwif_data(ide_hwif_t *h
drive->is_flash = 0;
drive->vdma = 0;
INIT_LIST_HEAD(&drive->list);
- sema_init(&drive->gendev_rel_sem, 0);
+ init_MUTEX_LOCKED(&drive->gendev_rel_sem);
}
}

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/dv1394-private.h linux-2.6.15-rc5-mutex/drivers/ieee1394/dv1394-private.h
--- /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/dv1394-private.h 2004-06-18 13:41:59.000000000 +0100
+++ linux-2.6.15-rc5-mutex/drivers/ieee1394/dv1394-private.h 2005-12-12 21:38:13.000000000 +0000
@@ -470,7 +470,7 @@ struct video_card {

NOTE: if you need both spinlock and sem, take sem first to avoid deadlock!


*/
- struct semaphore sem;
+ struct mutex sem;

/* people waiting for buffer space, please form a line here... */
wait_queue_head_t waitq;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/eth1394.c linux-2.6.15-rc5-mutex/drivers/ieee1394/eth1394.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/eth1394.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/ieee1394/eth1394.c 2005-12-12 22:08:48.000000000 +0000
@@ -64,7 +64,7 @@
#include <linux/ethtool.h>
#include <asm/uaccess.h>
#include <asm/delay.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>
#include <net/arp.h>

#include "csr1212.h"
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/hosts.h linux-2.6.15-rc5-mutex/drivers/ieee1394/hosts.h
--- /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/hosts.h 2005-11-01 13:19:07.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/ieee1394/hosts.h 2005-12-12 22:08:48.000000000 +0000
@@ -7,7 +7,7 @@
#include <linux/timer.h>
#include <linux/skbuff.h>

-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

#include "ieee1394_types.h"
#include "csr.h"
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/ieee1394_core.c linux-2.6.15-rc5-mutex/drivers/ieee1394/ieee1394_core.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/ieee1394_core.c 2005-11-01 13:19:07.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/ieee1394/ieee1394_core.c 2005-12-12 22:08:48.000000000 +0000
@@ -35,7 +35,7 @@
#include <linux/suspend.h>

#include <asm/byteorder.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

#include "ieee1394_types.h"
#include "ieee1394.h"
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/ieee1394_core.h linux-2.6.15-rc5-mutex/drivers/ieee1394/ieee1394_core.h
--- /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/ieee1394_core.h 2005-08-30 13:56:16.000000000 +0100
+++ linux-2.6.15-rc5-mutex/drivers/ieee1394/ieee1394_core.h 2005-12-12 22:08:48.000000000 +0000
@@ -5,7 +5,7 @@
#include <linux/slab.h>
#include <linux/devfs_fs_kernel.h>
#include <asm/atomic.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>
#include "hosts.h"


diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/ieee1394_types.h linux-2.6.15-rc5-mutex/drivers/ieee1394/ieee1394_types.h
--- /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/ieee1394_types.h 2004-06-18 13:41:59.000000000 +0100
+++ linux-2.6.15-rc5-mutex/drivers/ieee1394/ieee1394_types.h 2005-12-12 22:08:48.000000000 +0000
@@ -9,7 +9,7 @@
#include <linux/spinlock.h>
#include <linux/string.h>

-#include <asm/semaphore.h>
+#include <linux/semaphore.h>
#include <asm/byteorder.h>


diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/nodemgr.c linux-2.6.15-rc5-mutex/drivers/ieee1394/nodemgr.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/nodemgr.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/ieee1394/nodemgr.c 2005-12-12 20:21:37.000000000 +0000
@@ -1520,8 +1520,8 @@ static int nodemgr_host_thread(void *__h
unsigned int generation = 0;
int i;

- if (down_interruptible(&hi->reset_sem) ||
- down_interruptible(&nodemgr_serialize)) {
+ if (down_sem_interruptible(&hi->reset_sem) ||
+ down_sem_interruptible(&nodemgr_serialize)) {
if (try_to_freeze())
continue;
printk("NodeMgr: received unexpected signal?!\n" );
@@ -1551,7 +1551,7 @@ static int nodemgr_host_thread(void *__h

/* If we get a reset before we are done waiting, then
* start the the waiting over again */
- while (!down_trylock(&hi->reset_sem))
+ while (!down_sem_trylock(&hi->reset_sem))
i = 0;

/* Check the kill_me again */
@@ -1678,7 +1678,7 @@ static void nodemgr_host_reset(struct hp

if (hi != NULL) {
HPSB_VERBOSE("NodeMgr: Processing host reset for %s", hi->daemon_name);
- up(&hi->reset_sem);
+ up_sem(&hi->reset_sem);
} else
HPSB_ERR ("NodeMgr: could not process reset of unused host");

@@ -1693,7 +1693,7 @@ static void nodemgr_remove_host(struct h
if (hi->pid >= 0) {
hi->kill_me = 1;
mb();
- up(&hi->reset_sem);
+ up_sem(&hi->reset_sem);
wait_for_completion(&hi->exited);
nodemgr_remove_host_dev(&host->device);
}
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/raw1394.c linux-2.6.15-rc5-mutex/drivers/ieee1394/raw1394.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/ieee1394/raw1394.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/ieee1394/raw1394.c 2005-12-12 20:21:05.000000000 +0000
@@ -138,7 +138,7 @@ static void __queue_complete_req(struct
list_del(&req->list);
list_add_tail(&req->list, &fi->req_complete);

- up(&fi->complete_sem);
+ up_sem(&fi->complete_sem);
wake_up_interruptible(&fi->poll_wait_complete);
}

@@ -427,11 +427,11 @@ static ssize_t raw1394_read(struct file
}

if (file->f_flags & O_NONBLOCK) {
- if (down_trylock(&fi->complete_sem)) {
+ if (down_sem_trylock(&fi->complete_sem)) {
return -EAGAIN;
}
} else {
- if (down_interruptible(&fi->complete_sem)) {
+ if (down_sem_interruptible(&fi->complete_sem)) {
return -ERESTARTSYS;
}
}
@@ -2809,7 +2809,7 @@ static int raw1394_release(struct inode
spin_unlock_irqrestore(&fi->reqlists_lock, flags);

if (!done)
- down_interruptible(&fi->complete_sem);
+ down_sem_interruptible(&fi->complete_sem);
}

/* Remove any sub-trees left by user space programs */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/core/device.c linux-2.6.15-rc5-mutex/drivers/infiniband/core/device.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/core/device.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/infiniband/core/device.c 2005-12-12 22:12:49.000000000 +0000
@@ -39,7 +39,7 @@
#include <linux/slab.h>
#include <linux/init.h>

-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

#include "core_priv.h"

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/core/ucm.c linux-2.6.15-rc5-mutex/drivers/infiniband/core/ucm.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/core/ucm.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/infiniband/core/ucm.c 2005-12-12 21:14:22.000000000 +0000
@@ -60,7 +60,7 @@ struct ib_ucm_device {
};

struct ib_ucm_file {
- struct semaphore mutex;
+ struct mutex mutex;
struct file *filp;
struct ib_ucm_device *device;

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/core/user_mad.c linux-2.6.15-rc5-mutex/drivers/infiniband/core/user_mad.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/core/user_mad.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/infiniband/core/user_mad.c 2005-12-12 22:12:49.000000000 +0000
@@ -47,7 +47,7 @@
#include <linux/kref.h>

#include <asm/uaccess.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

#include <rdma/ib_mad.h>
#include <rdma/ib_user_mad.h>
@@ -92,7 +92,7 @@ struct ib_umad_port {

struct cdev *sm_dev;
struct class_device *sm_class_dev;
- struct semaphore sm_sem;
+ struct mutex sm_sem;

struct rw_semaphore mutex;
struct list_head file_list;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/core/uverbs.h linux-2.6.15-rc5-mutex/drivers/infiniband/core/uverbs.h
--- /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/core/uverbs.h 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/infiniband/core/uverbs.h 2005-12-12 21:14:18.000000000 +0000
@@ -88,7 +88,7 @@ struct ib_uverbs_event_file {

struct ib_uverbs_file {
struct kref ref;
- struct semaphore mutex;
+ struct mutex mutex;
struct ib_uverbs_device *device;
struct ib_ucontext *ucontext;
struct ib_event_handler event_handler;
@@ -131,7 +131,7 @@ struct ib_ucq_object {
u32 async_events_reported;
};

-extern struct semaphore ib_uverbs_idr_mutex;
+extern struct mutex ib_uverbs_idr_mutex;
extern struct idr ib_uverbs_pd_idr;
extern struct idr ib_uverbs_mr_idr;
extern struct idr ib_uverbs_mw_idr;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/hw/mthca/mthca_cmd.c linux-2.6.15-rc5-mutex/drivers/infiniband/hw/mthca/mthca_cmd.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/hw/mthca/mthca_cmd.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/infiniband/hw/mthca/mthca_cmd.c 2005-12-12 20:33:35.000000000 +0000
@@ -333,7 +333,7 @@ static int mthca_cmd_wait(struct mthca_d
int err = 0;
struct mthca_cmd_context *context;

- if (down_interruptible(&dev->cmd.event_sem))
+ if (down_sem_interruptible(&dev->cmd.event_sem))
return -EINTR;

spin_lock(&dev->cmd.context_lock);
@@ -375,7 +375,7 @@ out:
dev->cmd.free_head = context - dev->cmd.context;
spin_unlock(&dev->cmd.context_lock);

- up(&dev->cmd.event_sem);
+ up_sem(&dev->cmd.event_sem);
return err;
}

@@ -438,8 +438,8 @@ static int mthca_cmd_imm(struct mthca_de

int mthca_cmd_init(struct mthca_dev *dev)
{
- sema_init(&dev->cmd.hcr_sem, 1);
- sema_init(&dev->cmd.poll_sem, 1);
+ init_MUTEX(&dev->cmd.hcr_sem);
+ init_MUTEX(&dev->cmd.poll_sem);
dev->cmd.use_events = 0;

dev->hcr = ioremap(pci_resource_start(dev->pdev, 0) + MTHCA_HCR_BASE,
@@ -517,7 +517,7 @@ void mthca_cmd_use_polling(struct mthca_
dev->cmd.use_events = 0;

for (i = 0; i < dev->cmd.max_cmds; ++i)
- down(&dev->cmd.event_sem);
+ down_sem(&dev->cmd.event_sem);

kfree(dev->cmd.context);

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/hw/mthca/mthca_dev.h linux-2.6.15-rc5-mutex/drivers/infiniband/hw/mthca/mthca_dev.h
--- /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/hw/mthca/mthca_dev.h 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/infiniband/hw/mthca/mthca_dev.h 2005-12-12 22:06:13.000000000 +0000
@@ -43,7 +43,7 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/dma-mapping.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

#include "mthca_provider.h"
#include "mthca_doorbell.h"
@@ -110,8 +110,8 @@ enum {
struct mthca_cmd {
struct pci_pool *pool;
int use_events;
- struct semaphore hcr_sem;
- struct semaphore poll_sem;
+ struct mutex hcr_sem;
+ struct mutex poll_sem;
struct semaphore event_sem;
int max_cmds;
spinlock_t context_lock;
@@ -255,7 +255,7 @@ struct mthca_av_table {
};

struct mthca_mcg_table {


- struct semaphore sem;
+ struct mutex sem;

struct mthca_alloc alloc;
struct mthca_icm_table *table;
};
@@ -300,7 +300,7 @@ struct mthca_dev {
u64 ddr_end;

MTHCA_DECLARE_DOORBELL_LOCK(doorbell_lock)
- struct semaphore cap_mask_mutex;
+ struct mutex cap_mask_mutex;

void __iomem *hcr;
void __iomem *kar;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/hw/mthca/mthca_memfree.c linux-2.6.15-rc5-mutex/drivers/infiniband/hw/mthca/mthca_memfree.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/hw/mthca/mthca_memfree.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/infiniband/hw/mthca/mthca_memfree.c 2005-12-12 21:14:34.000000000 +0000
@@ -50,7 +50,7 @@ enum {
};

struct mthca_user_db_table {
- struct semaphore mutex;
+ struct mutex mutex;
struct {
u64 uvirt;
struct scatterlist mem;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/hw/mthca/mthca_memfree.h linux-2.6.15-rc5-mutex/drivers/infiniband/hw/mthca/mthca_memfree.h
--- /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/hw/mthca/mthca_memfree.h 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/infiniband/hw/mthca/mthca_memfree.h 2005-12-12 22:06:17.000000000 +0000
@@ -40,7 +40,7 @@
#include <linux/list.h>
#include <linux/pci.h>

-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

#define MTHCA_ICM_CHUNK_LEN \
((256 - sizeof (struct list_head) - 2 * sizeof (int)) / \
@@ -64,7 +64,7 @@ struct mthca_icm_table {
int num_obj;
int obj_size;
int lowmem;
- struct semaphore mutex;
+ struct mutex mutex;
struct mthca_icm *icm[0];
};

@@ -147,7 +147,7 @@ struct mthca_db_table {
int max_group1;
int min_group2;
struct mthca_db_page *page;
- struct semaphore mutex;
+ struct mutex mutex;
};

enum mthca_db_type {
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/ulp/ipoib/ipoib.h linux-2.6.15-rc5-mutex/drivers/infiniband/ulp/ipoib/ipoib.h
--- /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/ulp/ipoib/ipoib.h 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/infiniband/ulp/ipoib/ipoib.h 2005-12-12 22:12:49.000000000 +0000
@@ -49,7 +49,7 @@
#include <net/neighbour.h>

#include <asm/atomic.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

#include <rdma/ib_verbs.h>
#include <rdma/ib_pack.h>
@@ -123,8 +123,8 @@ struct ipoib_dev_priv {

unsigned long flags;

- struct semaphore mcast_mutex;
- struct semaphore vlan_mutex;
+ struct mutex mcast_mutex;
+ struct mutex vlan_mutex;

struct rb_root path_tree;
struct list_head path_list;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/ulp/srp/ib_srp.h linux-2.6.15-rc5-mutex/drivers/infiniband/ulp/srp/ib_srp.h
--- /warthog/kernels/linux-2.6.15-rc5/drivers/infiniband/ulp/srp/ib_srp.h 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/infiniband/ulp/srp/ib_srp.h 2005-12-12 22:12:49.000000000 +0000
@@ -38,7 +38,7 @@
#include <linux/types.h>
#include <linux/list.h>

-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
@@ -85,7 +85,7 @@ struct srp_host {
struct ib_mr *mr;
struct class_device class_dev;
struct list_head target_list;
- struct semaphore target_mutex;
+ struct mutex target_mutex;
struct completion released;
struct list_head list;
};
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/input/joystick/db9.c linux-2.6.15-rc5-mutex/drivers/input/joystick/db9.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/input/joystick/db9.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/input/joystick/db9.c 2005-12-12 20:56:11.000000000 +0000
@@ -111,7 +111,7 @@ struct db9 {
struct pardevice *pd;
int mode;
int used;


- struct semaphore sem;
+ struct mutex sem;

char phys[DB9_MAX_DEVICES][32];
};

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/input/joystick/gamecon.c linux-2.6.15-rc5-mutex/drivers/input/joystick/gamecon.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/input/joystick/gamecon.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/input/joystick/gamecon.c 2005-12-12 20:56:07.000000000 +0000
@@ -83,7 +83,7 @@ struct gc {
struct timer_list timer;
unsigned char pads[GC_MAX + 1];
int used;


- struct semaphore sem;
+ struct mutex sem;

char phys[GC_MAX_DEVICES][32];
};

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/input/joystick/iforce/iforce.h linux-2.6.15-rc5-mutex/drivers/input/joystick/iforce/iforce.h
--- /warthog/kernels/linux-2.6.15-rc5/drivers/input/joystick/iforce/iforce.h 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/input/joystick/iforce/iforce.h 2005-12-12 22:12:50.000000000 +0000
@@ -37,7 +37,7 @@
#include <linux/serio.h>
#include <linux/config.h>
#include <linux/circ_buf.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

/* This module provides arbitrary resource management routines.
* I use it to manage the device's memory.
@@ -146,7 +146,7 @@ struct iforce {
wait_queue_head_t wait;
struct resource device_memory;
struct iforce_core_effect core_effects[FF_EFFECTS_MAX];
- struct semaphore mem_mutex;
+ struct mutex mem_mutex;
};

/* Get hi and low bytes of a 16-bits int */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/input/joystick/turbografx.c linux-2.6.15-rc5-mutex/drivers/input/joystick/turbografx.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/input/joystick/turbografx.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/input/joystick/turbografx.c 2005-12-12 20:56:17.000000000 +0000
@@ -86,7 +86,7 @@ static struct tgfx {
char phys[TGFX_MAX_DEVICES][32];
int sticks;
int used;


- struct semaphore sem;
+ struct mutex sem;

} *tgfx_base[TGFX_MAX_PORTS];

/*
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/input/keyboard/atkbd.c linux-2.6.15-rc5-mutex/drivers/input/keyboard/atkbd.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/input/keyboard/atkbd.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/input/keyboard/atkbd.c 2005-12-12 17:52:17.000000000 +0000
@@ -216,7 +216,7 @@ struct atkbd {
unsigned long time;

struct work_struct event_work;
- struct semaphore event_sem;
+ struct mutex event_sem;
unsigned long event_mask;
};

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/input/keyboard/hil_kbd.c linux-2.6.15-rc5-mutex/drivers/input/keyboard/hil_kbd.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/input/keyboard/hil_kbd.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/input/keyboard/hil_kbd.c 2005-12-12 20:55:05.000000000 +0000
@@ -80,7 +80,7 @@ struct hil_kbd {
char rnm[HIL_KBD_MAX_LENGTH + 1]; /* RNM record + NULL term. */

/* Something to sleep around with. */


- struct semaphore sem;
+ struct mutex sem;
};

/* Process a complete packet after transfer from the HIL */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/input/misc/hp_sdc_rtc.c linux-2.6.15-rc5-mutex/drivers/input/misc/hp_sdc_rtc.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/input/misc/hp_sdc_rtc.c 2005-06-22 13:51:49.000000000 +0100
+++ linux-2.6.15-rc5-mutex/drivers/input/misc/hp_sdc_rtc.c 2005-12-12 20:55:41.000000000 +0000
@@ -52,7 +52,7 @@ MODULE_LICENSE("Dual BSD/GPL");

static unsigned long epoch = 2000;

-static struct semaphore i8042tregs;
+static struct mutex i8042tregs;

static hp_sdc_irqhook hp_sdc_rtc_isr;

@@ -85,7 +85,7 @@ static void hp_sdc_rtc_isr (int irq, voi

static int hp_sdc_rtc_do_read_bbrtc (struct rtc_time *rtctm)
{
- struct semaphore tsem;
+ struct mutex tsem;
hp_sdc_transaction t;
uint8_t tseq[91];
int i;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/input/mouse/hil_ptr.c linux-2.6.15-rc5-mutex/drivers/input/mouse/hil_ptr.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/input/mouse/hil_ptr.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/input/mouse/hil_ptr.c 2005-12-12 20:56:27.000000000 +0000
@@ -73,7 +73,7 @@ struct hil_ptr {
unsigned int btnmap[7];

/* Something to sleep around with. */


- struct semaphore sem;
+ struct mutex sem;
};

/* Process a complete packet after transfer from the HIL */
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/input/serio/hp_sdc.c linux-2.6.15-rc5-mutex/drivers/input/serio/hp_sdc.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/input/serio/hp_sdc.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/input/serio/hp_sdc.c 2005-12-12 20:56:45.000000000 +0000
@@ -777,7 +777,7 @@ static int __init hp_sdc_init(void)
char *errstr;
hp_sdc_transaction t_sync;
uint8_t ts_sync[6];
- struct semaphore s_sync;
+ struct mutex s_sync;

rwlock_init(&hp_sdc.lock);
rwlock_init(&hp_sdc.ibf_lock);
@@ -919,7 +919,7 @@ static int __init hp_sdc_register(void)
{
hp_sdc_transaction tq_init;
uint8_t tq_init_seq[5];
- struct semaphore tq_init_sem;
+ struct mutex tq_init_sem;
#if defined(__mc68000__)
mm_segment_t fs;
unsigned char i;
diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/input/serio/hp_sdc_mlc.c linux-2.6.15-rc5-mutex/drivers/input/serio/hp_sdc_mlc.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/input/serio/hp_sdc_mlc.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/input/serio/hp_sdc_mlc.c 2005-12-12 22:12:50.000000000 +0000
@@ -40,7 +40,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>

#define PREFIX "HP SDC MLC: "

diff -uNrp /warthog/kernels/linux-2.6.15-rc5/drivers/isdn/capi/capi.c linux-2.6.15-rc5-mutex/drivers/isdn/capi/capi.c
--- /warthog/kernels/linux-2.6.15-rc5/drivers/isdn/capi/capi.c 2005-12-08 16:23:40.000000000 +0000
+++ linux-2.6.15-rc5-mutex/drivers/isdn/capi/capi.c 2005-12-12 21:19:35.000000000 +0000
@@ -138,7 +138,7 @@ struct capidev {

struct capincci *nccis;

- struct semaphore ncci_list_sem;
+ struct mutex ncci_list_sem;
};

/* -------- global variables ---------------------------------------- */

Nick Piggin

unread,
Dec 12, 2005, 7:20:06 PM12/12/05
to
David Howells wrote:
> The attached patch introduces a simple mutex implementation as an alternative
> to the usual semaphore implementation where simple mutex functionality is all
> that is required.
>
> This is useful in two ways:
>
> (1) A number of archs only provide very simple atomic instructions (such as
> XCHG on i386, TAS on M68K, SWAP on FRV) which aren't sufficient to
> implement full semaphore support directly. Instead spinlocks must be
> employed to implement fuller functionality.
>

We have atomic_cmpxchg. Can you use that for a sufficient generic
implementation?

--
SUSE Labs, Novell Inc.

Send instant messages to your online friends http://au.messenger.yahoo.com

Andrew Morton

unread,
Dec 12, 2005, 7:20:11 PM12/12/05
to

Maybe I'm not understanding all this, but...

I'd have thought that the way to do this is to simply reimplement down(),
up(), down_trylock(), etc using the new xchg-based code and to then hunt
down those few parts of the kernel which actually use the old semaphore's
counting feature and convert them to use down_sem(), up_sem(), etc. And
rename all the old semaphore code: s/down/down_sem/etc.

So after such a transformation, this new "mutex" thingy would not exist.

> include/linux/mutex.h | 32 +++++++

But it does.

> +#define mutex_grab(mutex) (xchg(&(mutex)->state, 1) == 0)

mutex_trylock(), please.

> +#define is_mutex_locked(mutex) ((mutex)->state)

Let's keep the namespace consistent. mutex_is_locked().

> +static inline void down(struct mutex *mutex)
> +{
> + if (mutex_grab(mutex)) {

likely()

> +#ifdef CONFIG_DEBUG_MUTEX_OWNER
> + mutex->__owner = current;
> +#endif
> + }
> + else {
> + __down(mutex);
> + }
> +}
> +
> +/*
> + * sleep interruptibly until we get the mutex
> + * - return 0 if successful, -EINTR if interrupted
> + */
> +static inline int down_interruptible(struct mutex *mutex)
> +{
> + if (mutex_grab(mutex)) {

likely()

> +static inline int down_trylock(struct mutex *mutex)
> +{
> + if (mutex_grab(mutex)) {

etc.

You could just put likely() into mutex_trylock(). err, mutex_grab().

> +/*
> + * release the mutex
> + */
> +static inline void up(struct mutex *mutex)
> +{
> + unsigned long flags;
> +
> +#ifdef CONFIG_DEBUG_MUTEX_OWNER
> + if (mutex->__owner != current)
> + __up_bad(mutex);
> + mutex->__owner = NULL;
> +#endif
> +
> + /* must prevent a race */
> + spin_lock_irqsave(&mutex->wait_lock, flags);
> + if (!list_empty(&mutex->wait_list))
> + __up(mutex);
> + else
> + mutex_release(mutex);
> + spin_unlock_irqrestore(&mutex->wait_lock, flags);
> +}

This is too large to inline.

It's also significantly slower than the existing up()?

Nick Piggin

unread,
Dec 12, 2005, 7:30:12 PM12/12/05
to
David Howells wrote:

> + /* set up my own style of waitqueue */
> + waiter.task = tsk;
> +

Any reason why you're setting up your own style of waitqueue in
mutex-simple.c instead of just using the kernel's style of waitqueue?

> +
> +/*
> + * release a single token back to a mutex
> + * - entered with lock held and interrupts disabled
> + * - the queue will not be empty
> + */
> +void __up(struct mutex *mutex)
> +{
> + struct mutex_waiter *waiter;
> + struct task_struct *tsk;
> +
> + /* grant the token to the process at the front of the queue */
> + waiter = list_entry(mutex->wait_list.next, struct mutex_waiter, list);
> +
> + /* we must be careful not to touch 'waiter' after we set ->task = NULL.
> + * - it is an allocated on the waiter's stack and may become invalid at
> + * any time after that point (due to a wakeup from another source).
> + */
> + list_del_init(&waiter->list);
> + tsk = waiter->task;
> +#ifdef CONFIG_DEBUG_MUTEX_OWNER
> + mutex->__owner = tsk;
> +#endif
> + mb();

This should be smp_mb(), I think.

> + waiter->task = NULL;
> + wake_up_process(tsk);
> + put_task_struct(tsk);
> +}

Thanks,
Nick

--
SUSE Labs, Novell Inc.

Send instant messages to your online friends http://au.messenger.yahoo.com

Arnd Bergmann

unread,
Dec 12, 2005, 7:40:07 PM12/12/05
to
Am Dienstag 13 Dezember 2005 00:45 schrieb David Howells:
>  (7) Provides a debugging config option CONFIG_DEBUG_MUTEX_OWNER by which
> the mutex owner can be tracked and by which over-upping can be detected.

I can't see how your code actually detects the over-upping, although it's
fairly obvious how it would be done. Did you miss one patch for this?

Arnd <><

Daniel Walker

unread,
Dec 12, 2005, 8:00:16 PM12/12/05
to
On Mon, 2005-12-12 at 23:45 +0000, David Howells wrote:

> (1) Provides a simple xchg() based semaphore as a default for all
> architectures that don't wish to override it and provide their own.
>
> Overriding is possible by setting CONFIG_ARCH_IMPLEMENTS_MUTEX and
> supplying asm/mutex.h
>
> Partial overriding is possible by #defining mutex_grab(), mutex_release()
> and is_mutex_locked() to perform the appropriate optimised functions.

Your code is really similar to the RT mutex, which does everything that
your mutex does at least ? Assuming you've reviewed the RT mutex, why
would we want to use yours over it?

Daniel

Mark Lord

unread,
Dec 12, 2005, 10:00:11 PM12/12/05
to
> (5) Redirects the following to apply to the new mutexes rather than the
> traditional semaphores:
>
> down()
> down_trylock()
> down_interruptible()
> up()

This will BREAK a lot of out-of-tree stuff if merged.

So please figure out some way to hang a HUGE banner out there
so that the external codebases know they need updating.

The simplest way would be to NOT re-use the up()/down() symbols,
but rather to either keep them as-is (counting semaphores),
or delete them entirely (so that external code *knows* of the change).

Cheers

Steven Rostedt

unread,
Dec 12, 2005, 10:20:08 PM12/12/05
to
On Mon, 2005-12-12 at 21:57 -0500, Mark Lord wrote:
> > (5) Redirects the following to apply to the new mutexes rather than the
> > traditional semaphores:
> >
> > down()
> > down_trylock()
> > down_interruptible()
> > up()
>
> This will BREAK a lot of out-of-tree stuff if merged.
>
> So please figure out some way to hang a HUGE banner out there
> so that the external codebases know they need updating.
>
> The simplest way would be to NOT re-use the up()/down() symbols,
> but rather to either keep them as-is (counting semaphores),
> or delete them entirely (so that external code *knows* of the change).

Actually, up and down don't imply mutex at all. So maybe it would be
better to keep up and down as normal semaphores, rename what you want to
mutex_lock / mutex_unlock which makes it obvious what it is, and then
you can go through and find all the semaphores that are being used as
mutexes (or is that mutices?) and make the change more incrementally.

-- Steve

Steven Rostedt

unread,
Dec 12, 2005, 10:30:12 PM12/12/05
to
On Mon, 2005-12-12 at 16:57 -0800, Daniel Walker wrote:
> On Mon, 2005-12-12 at 23:45 +0000, David Howells wrote:
>
> > (1) Provides a simple xchg() based semaphore as a default for all
> > architectures that don't wish to override it and provide their own.
> >
> > Overriding is possible by setting CONFIG_ARCH_IMPLEMENTS_MUTEX and
> > supplying asm/mutex.h
> >
> > Partial overriding is possible by #defining mutex_grab(), mutex_release()
> > and is_mutex_locked() to perform the appropriate optimised functions.
>
> Your code is really similar to the RT mutex, which does everything that
> your mutex does at least ? Assuming you've reviewed the RT mutex, why
> would we want to use yours over it?

Maybe this would be the better !PREEMPT_RT version. But the true mutex
that Ingo is making would be used for the PREEMPT_RT side.

This code at least brings down the over head of semaphores where they
are not really needed. Looking at the code slightly (I must admit, I
spent maybe 30 seconds looking at it), it does seem a little similar to
Ingo's. Could just be coincidence, since the methods are pretty much
what multiple people would come up with. But you both work for RedHat,
hmm.

-- Steve

Andi Kleen

unread,
Dec 13, 2005, 3:00:12 AM12/13/05
to
> - i introduced a 'type-sensitive' macro wrapper that switches down()
> (and the other APIs) to either to the assembly variant (if the
> variable's type is struct compat_semaphore), or switches it to the new
> generic mutex (if the type is struct semaphore), at build-time. There
> is no runtime overhead due to this build-time-switching.

Didn't that drop compatibility with 2.95? The necessary builtins
are only in 3.x.

Not that I'm not in favour - I would like to use C99 everywhere
and it would get of the ugly spinlock workaround for i386
and x86-64 doesn't support earlier compilers anyways -
but others might not agree.

-Andi

Ingo Molnar

unread,
Dec 13, 2005, 3:00:13 AM12/13/05
to

* Andrew Morton <ak...@osdl.org> wrote:

> I'd have thought that the way to do this is to simply reimplement
> down(), up(), down_trylock(), etc using the new xchg-based code and to
> then hunt down those few parts of the kernel which actually use the
> old semaphore's counting feature and convert them to use down_sem(),
> up_sem(), etc. And rename all the old semaphore code:
> s/down/down_sem/etc.

even better than that, why not use the solution that we've implemented
for the -rt patchset, more than a year ago?

the solution i took was this:

- i did not touch the 'struct semaphore' namespace, but introduced a
'struct compat_semaphore'.

- i introduced a 'type-sensitive' macro wrapper that switches down()
(and the other APIs) to either to the assembly variant (if the
variable's type is struct compat_semaphore), or switches it to the new
generic mutex (if the type is struct semaphore), at build-time. There
is no runtime overhead due to this build-time-switching.

- for many months we worked with upstream maintainers to convert dozens
of mutex users over to struct completion, where this was appropriate.

all this simplified the 'compatibility conversion' to the patch below.
No other non-generic changes are needed.

Ingo

----
convert the remaining users of 'full Linux semaphore semantics' over to
compat_semaphore.

drivers/acpi/osl.c | 12 ++++++------
drivers/ieee1394/ieee1394_types.h | 2 +-
drivers/ieee1394/nodemgr.c | 2 +-
drivers/ieee1394/raw1394-private.h | 2 +-
drivers/media/dvb/dvb-core/dvb_frontend.c | 2 +-
drivers/media/dvb/dvb-core/dvb_frontend.h | 2 +-
drivers/net/3c527.c | 2 +-
drivers/net/hamradio/6pack.c | 2 +-
drivers/net/hamradio/mkiss.c | 2 +-
drivers/net/plip.c | 5 ++++-
drivers/net/ppp_async.c | 2 +-
drivers/net/ppp_synctty.c | 2 +-
drivers/pci/hotplug/cpci_hotplug_core.c | 4 ++--
drivers/pci/hotplug/cpqphp_ctrl.c | 4 ++--
drivers/pci/hotplug/ibmphp_hpc.c | 2 +-
drivers/pci/hotplug/pciehp_ctrl.c | 4 ++--
drivers/pci/hotplug/shpchp_ctrl.c | 4 ++--
drivers/scsi/aacraid/aacraid.h | 4 ++--
drivers/scsi/aic7xxx/aic79xx_osm.h | 2 +-
drivers/scsi/aic7xxx/aic7xxx_osm.h | 2 +-
drivers/scsi/qla2xxx/qla_def.h | 2 +-
drivers/usb/storage/usb.h | 2 +-
fs/xfs/linux-2.6/mutex.h | 2 +-
fs/xfs/linux-2.6/sema.h | 2 +-
fs/xfs/linux-2.6/xfs_buf.h | 4 ++--
include/linux/jffs2_fs_i.h | 10 +++++++++-
include/linux/jffs2_fs_sb.h | 6 +++---
include/linux/parport.h | 2 +-
include/pcmcia/ss.h | 2 +-
include/scsi/scsi_transport_spi.h | 2 +-
30 files changed, 54 insertions(+), 43 deletions(-)

Index: linux/drivers/acpi/osl.c
===================================================================
--- linux.orig/drivers/acpi/osl.c
+++ linux/drivers/acpi/osl.c
@@ -728,14 +728,14 @@ void acpi_os_delete_lock(acpi_handle han
acpi_status
acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
{
- struct semaphore *sem = NULL;
+ struct compat_semaphore *sem = NULL;

ACPI_FUNCTION_TRACE("os_create_semaphore");

- sem = acpi_os_allocate(sizeof(struct semaphore));
+ sem = acpi_os_allocate(sizeof(struct compat_semaphore));
if (!sem)
return_ACPI_STATUS(AE_NO_MEMORY);
- memset(sem, 0, sizeof(struct semaphore));
+ memset(sem, 0, sizeof(struct compat_semaphore));

sema_init(sem, initial_units);

@@ -758,7 +758,7 @@ EXPORT_SYMBOL(acpi_os_create_semaphore);

acpi_status acpi_os_delete_semaphore(acpi_handle handle)
{
- struct semaphore *sem = (struct semaphore *)handle;
+ struct compat_semaphore *sem = (struct compat_semaphore *)handle;

ACPI_FUNCTION_TRACE("os_delete_semaphore");

@@ -787,7 +787,7 @@ EXPORT_SYMBOL(acpi_os_delete_semaphore);
acpi_status acpi_os_wait_semaphore(acpi_handle handle, u32 units, u16 timeout)
{
acpi_status status = AE_OK;
- struct semaphore *sem = (struct semaphore *)handle;
+ struct compat_semaphore *sem = (struct compat_semaphore *)handle;
int ret = 0;

ACPI_FUNCTION_TRACE("os_wait_semaphore");
@@ -868,7 +868,7 @@ EXPORT_SYMBOL(acpi_os_wait_semaphore);
*/
acpi_status acpi_os_signal_semaphore(acpi_handle handle, u32 units)
{
- struct semaphore *sem = (struct semaphore *)handle;
+ struct compat_semaphore *sem = (struct compat_semaphore *)handle;

ACPI_FUNCTION_TRACE("os_signal_semaphore");

Index: linux/drivers/ieee1394/ieee1394_types.h
===================================================================
--- linux.orig/drivers/ieee1394/ieee1394_types.h
+++ linux/drivers/ieee1394/ieee1394_types.h
@@ -19,7 +19,7 @@ struct hpsb_tlabel_pool {
spinlock_t lock;
u8 next;
u32 allocations;
- struct semaphore count;
+ struct compat_semaphore count;
};

#define HPSB_TPOOL_INIT(_tp) \
Index: linux/drivers/ieee1394/nodemgr.c
===================================================================
--- linux.orig/drivers/ieee1394/nodemgr.c
+++ linux/drivers/ieee1394/nodemgr.c
@@ -114,7 +114,7 @@ struct host_info {
struct hpsb_host *host;
struct list_head list;
struct completion exited;
- struct semaphore reset_sem;
+ struct compat_semaphore reset_sem;
int pid;
char daemon_name[15];
int kill_me;
Index: linux/drivers/ieee1394/raw1394-private.h
===================================================================
--- linux.orig/drivers/ieee1394/raw1394-private.h
+++ linux/drivers/ieee1394/raw1394-private.h
@@ -29,7 +29,7 @@ struct file_info {

struct list_head req_pending;
struct list_head req_complete;
- struct semaphore complete_sem;
+ struct compat_semaphore complete_sem;
spinlock_t reqlists_lock;
wait_queue_head_t poll_wait_complete;

Index: linux/drivers/media/dvb/dvb-core/dvb_frontend.c
===================================================================
--- linux.orig/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ linux/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -95,7 +95,7 @@ struct dvb_frontend_private {
struct dvb_device *dvbdev;
struct dvb_frontend_parameters parameters;
struct dvb_fe_events events;
- struct semaphore sem;
+ struct compat_semaphore sem;
struct list_head list_head;
wait_queue_head_t wait_queue;
pid_t thread_pid;
Index: linux/drivers/media/dvb/dvb-core/dvb_frontend.h
===================================================================
--- linux.orig/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ linux/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -86,7 +86,7 @@ struct dvb_fe_events {
int eventr;
int overflow;
wait_queue_head_t wait_queue;
- struct semaphore sem;
+ struct compat_semaphore sem;
};

struct dvb_frontend {
Index: linux/drivers/net/3c527.c
===================================================================
--- linux.orig/drivers/net/3c527.c
+++ linux/drivers/net/3c527.c
@@ -182,7 +182,7 @@ struct mc32_local

u16 rx_ring_tail; /* index to rx de-queue end */

- struct semaphore cmd_mutex; /* Serialises issuing of execute commands */
+ struct compat_semaphore cmd_mutex; /* Serialises issuing of execute commands */
struct completion execution_cmd; /* Card has completed an execute command */
struct completion xceiver_cmd; /* Card has completed a tx or rx command */
};
Index: linux/drivers/net/hamradio/6pack.c
===================================================================
--- linux.orig/drivers/net/hamradio/6pack.c
+++ linux/drivers/net/hamradio/6pack.c
@@ -124,7 +124,7 @@ struct sixpack {
struct timer_list tx_t;
struct timer_list resync_t;
atomic_t refcnt;
- struct semaphore dead_sem;
+ struct compat_semaphore dead_sem;
spinlock_t lock;
};

Index: linux/drivers/net/hamradio/mkiss.c
===================================================================
--- linux.orig/drivers/net/hamradio/mkiss.c
+++ linux/drivers/net/hamradio/mkiss.c
@@ -85,7 +85,7 @@ struct mkiss {
#define CRC_MODE_SMACK_TEST 4

atomic_t refcnt;
- struct semaphore dead_sem;
+ struct compat_semaphore dead_sem;
};

/*---------------------------------------------------------------------------*/
Index: linux/drivers/net/plip.c
===================================================================
--- linux.orig/drivers/net/plip.c
+++ linux/drivers/net/plip.c
@@ -229,7 +229,10 @@ struct net_local {
struct hh_cache *hh);
spinlock_t lock;
atomic_t kill_timer;
- struct semaphore killed_timer_sem;
+ /*
+ * PREEMPT_RT: this isnt a mutex, it should be struct completion.
+ */
+ struct compat_semaphore killed_timer_sem;
};

static inline void enable_parport_interrupts (struct net_device *dev)
Index: linux/drivers/net/ppp_async.c
===================================================================
--- linux.orig/drivers/net/ppp_async.c
+++ linux/drivers/net/ppp_async.c
@@ -66,7 +66,7 @@ struct asyncppp {
struct tasklet_struct tsk;

atomic_t refcnt;
- struct semaphore dead_sem;
+ struct compat_semaphore dead_sem;
struct ppp_channel chan; /* interface to generic ppp layer */
unsigned char obuf[OBUFSIZE];
};
Index: linux/drivers/net/ppp_synctty.c
===================================================================
--- linux.orig/drivers/net/ppp_synctty.c
+++ linux/drivers/net/ppp_synctty.c
@@ -70,7 +70,7 @@ struct syncppp {
struct tasklet_struct tsk;

atomic_t refcnt;
- struct semaphore dead_sem;
+ struct compat_semaphore dead_sem;
struct ppp_channel chan; /* interface to generic ppp layer */
};

Index: linux/drivers/pci/hotplug/cpci_hotplug_core.c
===================================================================
--- linux.orig/drivers/pci/hotplug/cpci_hotplug_core.c
+++ linux/drivers/pci/hotplug/cpci_hotplug_core.c
@@ -60,8 +60,8 @@ static int slots;
static atomic_t extracting;
int cpci_debug;
static struct cpci_hp_controller *controller;
-static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
-static struct semaphore thread_exit; /* guard ensure thread has exited before calling it quits */
+static struct compat_semaphore event_semaphore; /* mutex for process loop (up if something to process) */
+static struct compat_semaphore thread_exit; /* guard ensure thread has exited before calling it quits */
static int thread_finished = 1;

static int enable_slot(struct hotplug_slot *slot);
Index: linux/drivers/pci/hotplug/cpqphp_ctrl.c
===================================================================
--- linux.orig/drivers/pci/hotplug/cpqphp_ctrl.c
+++ linux/drivers/pci/hotplug/cpqphp_ctrl.c
@@ -45,8 +45,8 @@ static int configure_new_function(struct
u8 behind_bridge, struct resource_lists *resources);
static void interrupt_event_handler(struct controller *ctrl);

-static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
-static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */
+static struct compat_semaphore event_semaphore; /* mutex for process loop (up if something to process) */
+static struct compat_semaphore event_exit; /* guard ensure thread has exited before calling it quits */
static int event_finished;
static unsigned long pushbutton_pending; /* = 0 */

Index: linux/drivers/pci/hotplug/ibmphp_hpc.c
===================================================================
--- linux.orig/drivers/pci/hotplug/ibmphp_hpc.c
+++ linux/drivers/pci/hotplug/ibmphp_hpc.c
@@ -104,7 +104,7 @@ static int tid_poll;
static struct semaphore sem_hpcaccess; // lock access to HPC
static struct semaphore semOperations; // lock all operations and
// access to data structures
-static struct semaphore sem_exit; // make sure polling thread goes away
+static struct compat_semaphore sem_exit; // make sure polling thread goes away
//----------------------------------------------------------------------------
// local function prototypes
//----------------------------------------------------------------------------
Index: linux/drivers/pci/hotplug/pciehp_ctrl.c
===================================================================
--- linux.orig/drivers/pci/hotplug/pciehp_ctrl.c
+++ linux/drivers/pci/hotplug/pciehp_ctrl.c
@@ -37,8 +37,8 @@

static void interrupt_event_handler(struct controller *ctrl);

-static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
-static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */
+static struct compat_semaphore event_semaphore; /* mutex for process loop (up if something to process) */
+static struct compat_semaphore event_exit; /* guard ensure thread has exited before calling it quits */
static int event_finished;
static unsigned long pushbutton_pending; /* = 0 */
static unsigned long surprise_rm_pending; /* = 0 */
Index: linux/drivers/pci/hotplug/shpchp_ctrl.c
===================================================================
--- linux.orig/drivers/pci/hotplug/shpchp_ctrl.c
+++ linux/drivers/pci/hotplug/shpchp_ctrl.c
@@ -37,8 +37,8 @@

static void interrupt_event_handler(struct controller *ctrl);

-static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */
-static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */
+static struct compat_semaphore event_semaphore; /* mutex for process loop (up if something to process) */
+static struct compat_semaphore event_exit; /* guard ensure thread has exited before calling it quits */
static int event_finished;
static unsigned long pushbutton_pending; /* = 0 */

Index: linux/drivers/scsi/aacraid/aacraid.h
===================================================================
--- linux.orig/drivers/scsi/aacraid/aacraid.h
+++ linux/drivers/scsi/aacraid/aacraid.h
@@ -735,7 +735,7 @@ struct aac_fib_context {
u32 unique; // unique value representing this context
ulong jiffies; // used for cleanup - dmb changed to ulong
struct list_head next; // used to link context's into a linked list
- struct semaphore wait_sem; // this is used to wait for the next fib to arrive.
+ struct compat_semaphore wait_sem; // this is used to wait for the next fib to arrive.
int wait; // Set to true when thread is in WaitForSingleObject
unsigned long count; // total number of FIBs on FibList
struct list_head fib_list; // this holds fibs and their attachd hw_fibs
@@ -804,7 +804,7 @@ struct fib {
* This is the event the sendfib routine will wait on if the
* caller did not pass one and this is synch io.
*/
- struct semaphore event_wait;
+ struct compat_semaphore event_wait;
spinlock_t event_lock;

u32 done; /* gets set to 1 when fib is complete */
Index: linux/drivers/scsi/aic7xxx/aic79xx_osm.h
===================================================================
--- linux.orig/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ linux/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -390,7 +390,7 @@ struct ahd_platform_data {
spinlock_t spin_lock;
u_int qfrozen;
struct timer_list reset_timer;
- struct semaphore eh_sem;
+ struct compat_semaphore eh_sem;
struct Scsi_Host *host; /* pointer to scsi host */
#define AHD_LINUX_NOIRQ ((uint32_t)~0)
uint32_t irq; /* IRQ for this adapter */
Index: linux/drivers/scsi/aic7xxx/aic7xxx_osm.h
===================================================================
--- linux.orig/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ linux/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -394,7 +394,7 @@ struct ahc_platform_data {
spinlock_t spin_lock;
u_int qfrozen;
struct timer_list reset_timer;
- struct semaphore eh_sem;
+ struct compat_semaphore eh_sem;
struct Scsi_Host *host; /* pointer to scsi host */
#define AHC_LINUX_NOIRQ ((uint32_t)~0)
uint32_t irq; /* IRQ for this adapter */
Index: linux/drivers/scsi/qla2xxx/qla_def.h
===================================================================
--- linux.orig/drivers/scsi/qla2xxx/qla_def.h
+++ linux/drivers/scsi/qla2xxx/qla_def.h
@@ -2411,7 +2411,7 @@ typedef struct scsi_qla_host {
spinlock_t mbx_reg_lock; /* Mbx Cmd Register Lock */

struct semaphore mbx_cmd_sem; /* Serialialize mbx access */
- struct semaphore mbx_intr_sem; /* Used for completion notification */
+ struct compat_semaphore mbx_intr_sem; /* Used for completion notification */

uint32_t mbx_flags;
#define MBX_IN_PROGRESS BIT_0
Index: linux/drivers/usb/storage/usb.h
===================================================================
--- linux.orig/drivers/usb/storage/usb.h
+++ linux/drivers/usb/storage/usb.h
@@ -171,7 +171,7 @@ struct us_data {
dma_addr_t iobuf_dma;

/* mutual exclusion and synchronization structures */
- struct semaphore sema; /* to sleep thread on */
+ struct compat_semaphore sema; /* to sleep thread on */
struct completion notify; /* thread begin/end */
wait_queue_head_t delay_wait; /* wait during scan, reset */

Index: linux/fs/xfs/linux-2.6/mutex.h
===================================================================
--- linux.orig/fs/xfs/linux-2.6/mutex.h
+++ linux/fs/xfs/linux-2.6/mutex.h
@@ -28,7 +28,7 @@
* callers.
*/
#define MUTEX_DEFAULT 0x0
-typedef struct semaphore mutex_t;
+typedef struct compat_semaphore mutex_t;

#define mutex_init(lock, type, name) sema_init(lock, 1)
#define mutex_destroy(lock) sema_init(lock, -99)
Index: linux/fs/xfs/linux-2.6/sema.h
===================================================================
--- linux.orig/fs/xfs/linux-2.6/sema.h
+++ linux/fs/xfs/linux-2.6/sema.h
@@ -27,7 +27,7 @@
* sema_t structure just maps to struct semaphore in Linux kernel.
*/

-typedef struct semaphore sema_t;
+typedef struct compat_semaphore sema_t;

#define init_sema(sp, val, c, d) sema_init(sp, val)
#define initsema(sp, val) sema_init(sp, val)
Index: linux/fs/xfs/linux-2.6/xfs_buf.h
===================================================================
--- linux.orig/fs/xfs/linux-2.6/xfs_buf.h
+++ linux/fs/xfs/linux-2.6/xfs_buf.h
@@ -114,7 +114,7 @@ typedef int (*page_buf_bdstrat_t)(struct
#define PB_PAGES 2

typedef struct xfs_buf {
- struct semaphore pb_sema; /* semaphore for lockables */
+ struct compat_semaphore pb_sema; /* semaphore for lockables */
unsigned long pb_queuetime; /* time buffer was queued */
atomic_t pb_pin_count; /* pin count */
wait_queue_head_t pb_waiters; /* unpin waiters */
@@ -134,7 +134,7 @@ typedef struct xfs_buf {
page_buf_iodone_t pb_iodone; /* I/O completion function */
page_buf_relse_t pb_relse; /* releasing function */
page_buf_bdstrat_t pb_strat; /* pre-write function */
- struct semaphore pb_iodonesema; /* Semaphore for I/O waiters */
+ struct compat_semaphore pb_iodonesema; /* Semaphore for I/O waiters */
void *pb_fspriv;
void *pb_fspriv2;
void *pb_fspriv3;
Index: linux/include/linux/jffs2_fs_i.h
===================================================================
--- linux.orig/include/linux/jffs2_fs_i.h
+++ linux/include/linux/jffs2_fs_i.h
@@ -14,7 +14,15 @@ struct jffs2_inode_info {


before letting GC proceed. Or we'd have to put ugliness
into the GC code so it didn't attempt to obtain the i_sem

for the inode(s) which are already locked */
- struct semaphore sem;
+ /*
+ * (On PREEMPT_RT: while use of ei->sem is mostly mutex-alike, the
+ * SLAB cache keeps the semaphore locked, which breaks the strict
+ * "owner must exist" properties of rt_mutexes. Fix it the easy
+ * way: by going to a compat_semaphore. But the real fix would be
+ * to cache inodes in an unlocked state and lock them when
+ * allocating a new inode.)
+ */
+ struct compat_semaphore sem;



/* The highest (datanode) version number used for this ino */
uint32_t highest_version;

Index: linux/include/linux/jffs2_fs_sb.h
===================================================================
--- linux.orig/include/linux/jffs2_fs_sb.h
+++ linux/include/linux/jffs2_fs_sb.h


@@ -35,7 +35,7 @@ struct jffs2_sb_info {
struct completion gc_thread_start; /* GC thread start completion */
struct completion gc_thread_exit; /* GC thread exit completion port */

- struct semaphore alloc_sem; /* Used to protect all the following

+ struct compat_semaphore alloc_sem; /* Used to protect all the following


fields, and also to protect against
out-of-order writing of nodes. And GC. */
uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER
@@ -93,7 +93,7 @@ struct jffs2_sb_info {
/* Sem to allow jffs2_garbage_collect_deletion_dirent to
drop the erase_completion_lock while it's holding a pointer
to an obsoleted node. I don't like this. Alternatives welcomed. */
- struct semaphore erase_free_sem;

+ struct compat_semaphore erase_free_sem;



uint32_t wbuf_pagesize; /* 0 for NOR and other flashes with no wbuf */

@@ -104,7 +104,7 @@ struct jffs2_sb_info {
uint32_t wbuf_len;
struct jffs2_inodirty *wbuf_inodes;

- struct rw_semaphore wbuf_sem; /* Protects the write buffer */
+ struct compat_rw_semaphore wbuf_sem; /* Protects the write buffer */

/* Information about out-of-band area usage... */
struct nand_oobinfo *oobinfo;
Index: linux/include/linux/parport.h
===================================================================
--- linux.orig/include/linux/parport.h
+++ linux/include/linux/parport.h


@@ -254,7 +254,7 @@ enum ieee1284_phase {
struct ieee1284_info {
int mode;
volatile enum ieee1284_phase phase;
- struct semaphore irq;

+ struct compat_semaphore irq;


};

/* A parallel port */

Index: linux/include/pcmcia/ss.h
===================================================================
--- linux.orig/include/pcmcia/ss.h
+++ linux/include/pcmcia/ss.h
@@ -243,7 +243,7 @@ struct pcmcia_socket {
#endif

/* state thread */
- struct semaphore skt_sem; /* protects socket h/w state */
+ struct compat_semaphore skt_sem; /* protects socket h/w state */

struct task_struct *thread;
struct completion thread_done;
Index: linux/include/scsi/scsi_transport_spi.h
===================================================================
--- linux.orig/include/scsi/scsi_transport_spi.h
+++ linux/include/scsi/scsi_transport_spi.h
@@ -51,7 +51,7 @@ struct spi_transport_attrs {
unsigned int support_qas; /* supports quick arbitration and selection */
/* Private Fields */
unsigned int dv_pending:1; /* Internal flag */
- struct semaphore dv_sem; /* semaphore to serialise dv */
+ struct compat_semaphore dv_sem; /* semaphore to serialise dv */
};

enum spi_signal_type {

Arjan van de Ven

unread,
Dec 13, 2005, 3:10:07 AM12/13/05
to
On Tue, 2005-12-13 at 08:54 +0100, Ingo Molnar wrote:
> * Andrew Morton <ak...@osdl.org> wrote:
>
> > I'd have thought that the way to do this is to simply reimplement
> > down(), up(), down_trylock(), etc using the new xchg-based code and to
> > then hunt down those few parts of the kernel which actually use the
> > old semaphore's counting feature and convert them to use down_sem(),
> > up_sem(), etc. And rename all the old semaphore code:
> > s/down/down_sem/etc.
>
> even better than that, why not use the solution that we've implemented
> for the -rt patchset, more than a year ago?
>
> the solution i took was this:
>
> - i did not touch the 'struct semaphore' namespace, but introduced a
> 'struct compat_semaphore'.

which I think is wrong. THis naming sucks. Sure doing a full sed on the
tree is not pretty but it's also not THAT painful. And the pain of wrong
names is something the kernel needs to carry around for years.


>
> - i introduced a 'type-sensitive' macro wrapper that switches down()
> (and the other APIs) to either to the assembly variant (if the
> variable's type is struct compat_semaphore), or switches it to the new
> generic mutex (if the type is struct semaphore), at build-time. There
> is no runtime overhead due to this build-time-switching.

while this is a smart trick, I rather prefer seperate functions, just so
that people are "aware" which they use. Since 99% of the users is a
mutex anyway, the new names are only used in a few special cases.

Andrew Morton

unread,
Dec 13, 2005, 3:50:17 AM12/13/05
to
Andi Kleen <a...@suse.de> wrote:
>
> > - i introduced a 'type-sensitive' macro wrapper that switches down()
> > (and the other APIs) to either to the assembly variant (if the
> > variable's type is struct compat_semaphore), or switches it to the new
> > generic mutex (if the type is struct semaphore), at build-time. There
> > is no runtime overhead due to this build-time-switching.
>
> Didn't that drop compatibility with 2.95? The necessary builtins
> are only in 3.x.
>
> Not that I'm not in favour - I would like to use C99 everywhere
> and it would get of the ugly spinlock workaround for i386
> and x86-64 doesn't support earlier compilers anyways -
> but others might not agree.
>

2.95.x is basically buggered at present. There's one scsi driver which
doesn't compile due to weird __VA_ARGS__ tricks and the rather useful
scsi/sd.c is currently getting an ICE. None of the new SAS code compiles,
due to extensive use of anonymous unions. The V4L guys are very good at
exploiting the gcc-2.95.x macro expansion bug (_why_ does each driver need
to implement its own debug macros?) and various people keep on sneaking in
anonymous unions.

It's time to give up on it and just drink more coffee or play more tetris
or something, I'm afraid.

Andi Kleen

unread,
Dec 13, 2005, 4:00:16 AM12/13/05
to
> It's time to give up on it and just drink more coffee or play more tetris
> or something, I'm afraid.

Or start using icecream (http://wiki.kde.org/icecream)

Anyways cool. Gratulations. Can you please apply the following patch then?

Remove -Wdeclaration-after-statement

Now that gcc 2.95 is not supported anymore it's ok to use C99
style mixed declarations everywhere.

Signed-off-by: Andi Kleen <a...@suse.de>

Index: linux/Makefile
===================================================================
--- linux/Makefile
+++ linux/Makefile
@@ -535,9 +535,6 @@ include $(srctree)/arch/$(ARCH)/Makefile
NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
CHECKFLAGS += $(NOSTDINC_FLAGS)

-# warn about C99 declaration after statement
-CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
-
# disable pointer signedness warnings in gcc 4.0
CFLAGS += $(call cc-option,-Wno-pointer-sign,)

Andi Kleen

unread,
Dec 13, 2005, 4:10:05 AM12/13/05
to
On Tue, Dec 13, 2005 at 01:01:26AM -0800, Andrew Morton wrote:
> Andi Kleen <a...@suse.de> wrote:
> >
> > Can you please apply the following patch then?
> >
> > Remove -Wdeclaration-after-statement
>
> OK.
>
> Thus far I have this:

Would it be possible to drop support for gcc 3.0 too?
AFAIK it has never been widely used. If we assume 3.1+ minimum it has the
advantage that named assembly arguments work, which make
the inline assembly often a lot easier to read and maintain.

-Andi

Christoph Hellwig

unread,
Dec 13, 2005, 4:10:06 AM12/13/05
to
>
> Remove -Wdeclaration-after-statement
>
> Now that gcc 2.95 is not supported anymore it's ok to use C99
> style mixed declarations everywhere.

Nack. This code style is pure obsfucation and we should disallow it forever.

Christoph Hellwig

unread,
Dec 13, 2005, 4:10:08 AM12/13/05
to
On Mon, Dec 12, 2005 at 09:57:40PM -0500, Mark Lord wrote:
> This will BREAK a lot of out-of-tree stuff if merged.

Well, bad luck for them.

> The simplest way would be to NOT re-use the up()/down() symbols,
> but rather to either keep them as-is (counting semaphores),
> or delete them entirely (so that external code *knows* of the change).

That I agree with actually. Keeping the semaphore interface as-is
would simplify in-kernel transition a lot aswell and make it easier for
people to get the API read. And the mutex symbols could get far more sensible
names like mutex_lock, mutex_unlock and mutex_trylock..

Christoph Hellwig

unread,
Dec 13, 2005, 4:10:09 AM12/13/05
to
On Tue, Dec 13, 2005 at 08:54:41AM +0100, Ingo Molnar wrote:
> - i did not touch the 'struct semaphore' namespace, but introduced a
> 'struct compat_semaphore'.

Because it's totally brindead. Your compat_semaphore is a real semaphore
and your semaphore is a mutex. So name them as such.

> - i introduced a 'type-sensitive' macro wrapper that switches down()
> (and the other APIs) to either to the assembly variant (if the
> variable's type is struct compat_semaphore), or switches it to the new
> generic mutex (if the type is struct semaphore), at build-time. There
> is no runtime overhead due to this build-time-switching.

And this one is probably is a great help to win the obsfucated C contests,
but otherwise just harmfull.

Christoph Hellwig

unread,
Dec 13, 2005, 4:10:09 AM12/13/05
to
On Tue, Dec 13, 2005 at 12:42:57AM -0800, Andrew Morton wrote:
> scsi/sd.c is currently getting an ICE. None of the new SAS code compiles,
> due to extensive use of anonymous unions.

This is just the headers in the luben code which need redoing completely
because they're doing other stupid things like using bitfields for on the
wire structures.

Andrew Morton

unread,
Dec 13, 2005, 4:10:11 AM12/13/05
to
Andi Kleen <a...@suse.de> wrote:
>
> Can you please apply the following patch then?
>
> Remove -Wdeclaration-after-statement

OK.

Thus far I have this:


From: Andrew Morton <ak...@osdl.org>

There's one scsi driver which doesn't compile due to weird __VA_ARGS__ tricks
and the rather useful scsi/sd.c is currently getting an ICE. None of the new
SAS code compiles, due to extensive use of anonymous unions. The V4L guys are
very good at exploiting the gcc-2.95.x macro expansion bug (_why_ does each
driver need to implement its own debug macros?) and various people keep on
sneaking in anonymous unions.

Plus anonymous unions are rather useful.

Signed-off-by: Andrew Morton <ak...@osdl.org>
---

dev/null | 29 -----------------------------
include/linux/compiler.h | 2 --
init/main.c | 7 +------
3 files changed, 1 insertion(+), 37 deletions(-)

diff -puN init/main.c~abandon-gcc-295x init/main.c
--- devel/init/main.c~abandon-gcc-295x 2005-12-13 00:48:17.000000000 -0800
+++ devel-akpm/init/main.c 2005-12-13 00:48:17.000000000 -0800
@@ -58,11 +58,6 @@
* This is one of the first .c files built. Error out early
* if we have compiler trouble..
*/
-#if __GNUC__ == 2 && __GNUC_MINOR__ == 96
-#ifdef CONFIG_FRAME_POINTER
-#error This compiler cannot compile correctly with frame pointers enabled
-#endif
-#endif

#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/smp.h>
@@ -74,7 +69,7 @@
* To avoid associated bogus bug reports, we flatly refuse to compile
* with a gcc that is known to be too old from the very beginning.
*/
-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95)
+#if __GNUC__ < 3
#error Sorry, your GCC is too old. It builds incorrect kernels.
#endif

diff -L include/linux/compiler-gcc2.h -puN include/linux/compiler-gcc2.h~abandon-gcc-295x /dev/null
--- devel/include/linux/compiler-gcc2.h
+++ /dev/null 2003-09-15 06:40:47.000000000 -0700
@@ -1,29 +0,0 @@
-/* Never include this file directly. Include <linux/compiler.h> instead. */
-
-/* These definitions are for GCC v2.x. */
-
-/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
- a mechanism by which the user can annotate likely branch directions and
- expect the blocks to be reordered appropriately. Define __builtin_expect
- to nothing for earlier compilers. */
-#include <linux/compiler-gcc.h>
-
-#if __GNUC_MINOR__ < 96
-# define __builtin_expect(x, expected_value) (x)
-#endif
-
-#define __attribute_used__ __attribute__((__unused__))
-
-/*
- * The attribute `pure' is not implemented in GCC versions earlier
- * than 2.96.
- */
-#if __GNUC_MINOR__ >= 96
-# define __attribute_pure__ __attribute__((pure))
-# define __attribute_const__ __attribute__((__const__))
-#endif
-
-/* GCC 2.95.x/2.96 recognize __va_copy, but not va_copy. Actually later GCC's
- * define both va_copy and __va_copy, but the latter may go away, so limit this
- * to this header */
-#define va_copy __va_copy
diff -puN include/linux/compiler.h~abandon-gcc-295x include/linux/compiler.h
--- devel/include/linux/compiler.h~abandon-gcc-295x 2005-12-13 00:48:17.000000000 -0800
+++ devel-akpm/include/linux/compiler.h 2005-12-13 00:48:17.000000000 -0800
@@ -42,8 +42,6 @@ extern void __chk_io_ptr(void __iomem *)
# include <linux/compiler-gcc4.h>
#elif __GNUC__ == 3
# include <linux/compiler-gcc3.h>
-#elif __GNUC__ == 2
-# include <linux/compiler-gcc2.h>
#else
# error Sorry, your compiler is too old/not recognized.
#endif
_

Andrew Morton

unread,
Dec 13, 2005, 4:10:12 AM12/13/05
to
Andrew Morton <ak...@osdl.org> wrote:
>
> Thus far I have this:
>

And this:


From: Andrew Morton <ak...@osdl.org>

Remove various things which were checking for gcc-1.x and gcc-2.x compilers.


Signed-off-by: Andrew Morton <ak...@osdl.org>
---

arch/arm/kernel/asm-offsets.c | 7 +------
arch/arm26/kernel/asm-offsets.c | 7 -------
arch/ia64/kernel/head.S | 2 +-
arch/ia64/kernel/ia64_ksyms.c | 2 +-
arch/ia64/oprofile/backtrace.c | 2 +-
drivers/md/raid0.c | 6 ------
fs/xfs/xfs_log.h | 8 +-------
include/asm-um/rwsem.h | 4 ----
include/asm-v850/unistd.h | 18 ------------------
include/linux/seccomp.h | 6 +-----
include/linux/spinlock_types_up.h | 14 --------------
11 files changed, 6 insertions(+), 70 deletions(-)

diff -puN drivers/md/raid0.c~remove-gcc2-checks drivers/md/raid0.c
--- devel/drivers/md/raid0.c~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800
+++ devel-akpm/drivers/md/raid0.c 2005-12-13 00:51:35.000000000 -0800
@@ -307,9 +307,6 @@ static int raid0_run (mddev_t *mddev)
printk("raid0 : conf->hash_spacing is %llu blocks.\n",
(unsigned long long)conf->hash_spacing);
{
-#if __GNUC__ < 3
- volatile
-#endif
sector_t s = mddev->array_size;
sector_t space = conf->hash_spacing;
int round;
@@ -440,9 +437,6 @@ static int raid0_make_request (request_q


{
-#if __GNUC__ < 3
- volatile
-#endif
sector_t x = block >> conf->preshift;
sector_div(x, (u32)conf->hash_spacing);
zone = conf->hash_table[x];
diff -puN fs/xfs/xfs_log.h~remove-gcc2-checks fs/xfs/xfs_log.h
--- devel/fs/xfs/xfs_log.h~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800
+++ devel-akpm/fs/xfs/xfs_log.h 2005-12-13 00:52:10.000000000 -0800
@@ -30,13 +30,7 @@
* By comparing each compnent, we don't have to worry about extra
* endian issues in treating two 32 bit numbers as one 64 bit number
*/
-static
-#if defined(__GNUC__) && (__GNUC__ == 2) && ( (__GNUC_MINOR__ == 95) || (__GNUC_MINOR__ == 96))
-__attribute__((unused)) /* gcc 2.95, 2.96 miscompile this when inlined */
-#else
-__inline__
-#endif
-xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
+static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
{
if (CYCLE_LSN(lsn1) != CYCLE_LSN(lsn2))
return (CYCLE_LSN(lsn1)<CYCLE_LSN(lsn2))? -999 : 999;
diff -puN arch/arm/kernel/asm-offsets.c~remove-gcc2-checks arch/arm/kernel/asm-offsets.c
--- devel/arch/arm/kernel/asm-offsets.c~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800
+++ devel-akpm/arch/arm/kernel/asm-offsets.c 2005-12-13 00:53:27.000000000 -0800
@@ -23,18 +23,13 @@
#error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
#endif
/*
- * GCC 2.95.1, 2.95.2: ignores register clobber list in asm().
* GCC 3.0, 3.1: general bad code generation.
* GCC 3.2.0: incorrect function argument offset calculation.
* GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
* (http://gcc.gnu.org/PR8896) and incorrect structure
* initialisation in fs/jffs2/erase.c
*/
-#if __GNUC__ < 2 || \
- (__GNUC__ == 2 && __GNUC_MINOR__ < 95) || \
- (__GNUC__ == 2 && __GNUC_MINOR__ == 95 && __GNUC_PATCHLEVEL__ != 0 && \
- __GNUC_PATCHLEVEL__ < 3) || \
- (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#if __GNUC__ < 2 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
#error Your compiler is too buggy; it is known to miscompile kernels.
#error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3
#endif
diff -puN arch/arm26/kernel/asm-offsets.c~remove-gcc2-checks arch/arm26/kernel/asm-offsets.c
--- devel/arch/arm26/kernel/asm-offsets.c~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800
+++ devel-akpm/arch/arm26/kernel/asm-offsets.c 2005-12-13 00:53:47.000000000 -0800
@@ -25,13 +25,6 @@
#if defined(__APCS_32__) && defined(CONFIG_CPU_26)
#error Sorry, your compiler targets APCS-32 but this kernel requires APCS-26
#endif


-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 95)

-#error Sorry, your compiler is known to miscompile kernels. Only use gcc 2.95.3 and later.
-#endif
-#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
-/* shame we can't detect the .1 or .2 releases */
-#warning GCC 2.95.2 and earlier miscompiles kernels.
-#endif

/* Use marker if you need to separate the values later */

diff -puN arch/ia64/kernel/ia64_ksyms.c~remove-gcc2-checks arch/ia64/kernel/ia64_ksyms.c
--- devel/arch/ia64/kernel/ia64_ksyms.c~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800
+++ devel-akpm/arch/ia64/kernel/ia64_ksyms.c 2005-12-13 00:54:02.000000000 -0800
@@ -103,7 +103,7 @@ EXPORT_SYMBOL(unw_init_running);

#ifdef ASM_SUPPORTED
# ifdef CONFIG_SMP
-# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+# if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
/*
* This is not a normal routine and we don't want a function descriptor for it, so we use
* a fake declaration here.
diff -puN arch/ia64/kernel/head.S~remove-gcc2-checks arch/ia64/kernel/head.S
--- devel/arch/ia64/kernel/head.S~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800
+++ devel-akpm/arch/ia64/kernel/head.S 2005-12-13 00:54:10.000000000 -0800
@@ -1060,7 +1060,7 @@ SET_REG(b5);
* the clobber lists for spin_lock() in include/asm-ia64/spinlock.h.
*/

-#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)

GLOBAL_ENTRY(ia64_spinlock_contention_pre3_4)
.prologue
diff -puN arch/ia64/oprofile/backtrace.c~remove-gcc2-checks arch/ia64/oprofile/backtrace.c
--- devel/arch/ia64/oprofile/backtrace.c~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800
+++ devel-akpm/arch/ia64/oprofile/backtrace.c 2005-12-13 00:54:16.000000000 -0800
@@ -32,7 +32,7 @@ typedef struct
u64 *prev_pfs_loc; /* state for WAR for old spinlock ool code */
} ia64_backtrace_t;

-#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
+#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
/*
* Returns non-zero if the PC is in the spinlock contention out-of-line code
* with non-standard calling sequence (on older compilers).
diff -puN include/linux/spinlock_types_up.h~remove-gcc2-checks include/linux/spinlock_types_up.h
--- devel/include/linux/spinlock_types_up.h~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800
+++ devel-akpm/include/linux/spinlock_types_up.h 2005-12-13 00:55:14.000000000 -0800
@@ -22,30 +22,16 @@ typedef struct {

#else

-/*
- * All gcc 2.95 versions and early versions of 2.96 have a nasty bug
- * with empty initializers.
- */
-#if (__GNUC__ > 2)
typedef struct { } raw_spinlock_t;

#define __RAW_SPIN_LOCK_UNLOCKED { }
-#else
-typedef struct { int gcc_is_buggy; } raw_spinlock_t;
-#define __RAW_SPIN_LOCK_UNLOCKED (raw_spinlock_t) { 0 }
-#endif

#endif

-#if (__GNUC__ > 2)
typedef struct {
/* no debug version on UP */
} raw_rwlock_t;

#define __RAW_RW_LOCK_UNLOCKED { }
-#else
-typedef struct { int gcc_is_buggy; } raw_rwlock_t;
-#define __RAW_RW_LOCK_UNLOCKED (raw_rwlock_t) { 0 }
-#endif

#endif /* __LINUX_SPINLOCK_TYPES_UP_H */
diff -puN include/linux/seccomp.h~remove-gcc2-checks include/linux/seccomp.h
--- devel/include/linux/seccomp.h~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800
+++ devel-akpm/include/linux/seccomp.h 2005-12-13 00:55:25.000000000 -0800
@@ -26,11 +26,7 @@ static inline int has_secure_computing(s

#else /* CONFIG_SECCOMP */

-#if (__GNUC__ > 2)
- typedef struct { } seccomp_t;
-#else
- typedef struct { int gcc_is_buggy; } seccomp_t;
-#endif
+typedef struct { } seccomp_t;

#define secure_computing(x) do { } while (0)
/* static inline to preserve typechecking */
diff -puN include/asm-um/rwsem.h~remove-gcc2-checks include/asm-um/rwsem.h
--- devel/include/asm-um/rwsem.h~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800
+++ devel-akpm/include/asm-um/rwsem.h 2005-12-13 00:55:41.000000000 -0800
@@ -1,10 +1,6 @@
#ifndef __UM_RWSEM_H__
#define __UM_RWSEM_H__

-#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96)
-#define __builtin_expect(exp,c) (exp)
-#endif
-
#include "asm/arch/rwsem.h"

#endif
diff -puN include/asm-v850/unistd.h~remove-gcc2-checks include/asm-v850/unistd.h
--- devel/include/asm-v850/unistd.h~remove-gcc2-checks 2005-12-13 00:51:15.000000000 -0800
+++ devel-akpm/include/asm-v850/unistd.h 2005-12-13 00:56:07.000000000 -0800
@@ -241,9 +241,6 @@
/* User programs sometimes end up including this header file
(indirectly, via uClibc header files), so I'm a bit nervous just
including <linux/compiler.h>. */
-#if !defined(__builtin_expect) && __GNUC__ == 2 && __GNUC_MINOR__ < 96
-#define __builtin_expect(x, expected_value) (x)
-#endif

#define __syscall_return(type, res) \
do { \
@@ -346,20 +343,6 @@ type name (atype a, btype b, ctype c, dt
__syscall_return (type, __ret); \
}

-#if __GNUC__ < 3
-/* In older versions of gcc, `asm' statements with more than 10
- input/output arguments produce a fatal error. To work around this
- problem, we use two versions, one for gcc-3.x and one for earlier
- versions of gcc (the `earlier gcc' version doesn't work with gcc-3.x
- because gcc-3.x doesn't allow clobbers to also be input arguments). */
-#define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f) \
- __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP \
- : "=r" (ret), "=r" (syscall) \
- : "1" (syscall), \
- "r" (a), "r" (b), "r" (c), "r" (d), \
- "r" (e), "r" (f) \
- : SYSCALL_CLOBBERS, SYSCALL_ARG4, SYSCALL_ARG5);
-#else /* __GNUC__ >= 3 */
#define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f) \
__asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP \
: "=r" (ret), "=r" (syscall), \
@@ -368,7 +351,6 @@ type name (atype a, btype b, ctype c, dt
"r" (a), "r" (b), "r" (c), "r" (d), \
"2" (e), "3" (f) \
: SYSCALL_CLOBBERS);
-#endif

#define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f) \
type name (atype a, btype b, ctype c, dtype d, etype e, ftype f) \

Ingo Molnar

unread,
Dec 13, 2005, 4:20:11 AM12/13/05
to

* Andrew Morton <ak...@osdl.org> wrote:

> Andi Kleen <a...@suse.de> wrote:
> >
> > Can you please apply the following patch then?
> >
> > Remove -Wdeclaration-after-statement
>
> OK.
>
> Thus far I have this:
>
>
> From: Andrew Morton <ak...@osdl.org>

hurray!!

This-Move-Is-Emphatically-Supported-by: Ingo Molnar <mi...@elte.hu>

Ingo

Andi Kleen

unread,
Dec 13, 2005, 4:20:14 AM12/13/05
to
> it's not _that_ bad, if done overnight. It does not touch any of the
> down/up APIs. Touching those would create a monster patch and monster
> impact.

One argument for a full rename (and abandoning the old "struct semaphore"
name completely) would be that it would offer a clean break for out tree code,
no silent breakage.

-Andi

Andrew Morton

unread,
Dec 13, 2005, 4:20:15 AM12/13/05
to
Andi Kleen <a...@suse.de> wrote:
>
> On Tue, Dec 13, 2005 at 01:01:26AM -0800, Andrew Morton wrote:
> > Andi Kleen <a...@suse.de> wrote:
> > >
> > > Can you please apply the following patch then?
> > >
> > > Remove -Wdeclaration-after-statement
> >
> > OK.
> >
> > Thus far I have this:
>
> Would it be possible to drop support for gcc 3.0 too?

Spose so - I don't know what people are using out there.

> AFAIK it has never been widely used. If we assume 3.1+ minimum it has the
> advantage that named assembly arguments work, which make
> the inline assembly often a lot easier to read and maintain.

There are a few places in the tree which refuse to compile with 3.1 and 3.2.

Ingo Molnar

unread,
Dec 13, 2005, 4:20:18 AM12/13/05
to

* Christoph Hellwig <h...@infradead.org> wrote:

> >
> > Remove -Wdeclaration-after-statement
> >
> > Now that gcc 2.95 is not supported anymore it's ok to use C99
> > style mixed declarations everywhere.
>
> Nack. This code style is pure obsfucation and we should disallow it
> forever.

agreed. I often get quilt mismerges uncovered by that warning. If
someone wants to start a new section of code that is too large, it
should go into a separate function.

Ingo

Ingo Molnar

unread,
Dec 13, 2005, 4:20:18 AM12/13/05
to

* Andi Kleen <a...@suse.de> wrote:

> > It's time to give up on it and just drink more coffee or play more tetris
> > or something, I'm afraid.
>
> Or start using icecream (http://wiki.kde.org/icecream)

distcc is pretty good too. I have a minimal kernel build done in 19
seconds, a fuller build (1.5MB bzImage that boots on all my testboxes)
done in 45 seconds, using gcc 4.0.2.

with the default settings, distcc wasnt saturating my boxes, the key was
to start distccd with a longer queue size (/etc/sysconfig/distccd):

OPTIONS="--nice 5 --jobs 128"

and to get the DISTCC_HOSTS tuning right:

export DISTCC_HOSTS='j/16 n/120 v/40 s/13 e2/7'

in fact my distcc builds are almost as fast as a fully cached ccache
build coming straight out of RAM ...

Ingo

Andrew Morton

unread,
Dec 13, 2005, 4:20:21 AM12/13/05
to
Christoph Hellwig <h...@infradead.org> wrote:
>
> On Tue, Dec 13, 2005 at 12:42:57AM -0800, Andrew Morton wrote:
> > scsi/sd.c is currently getting an ICE. None of the new SAS code compiles,
> > due to extensive use of anonymous unions.
>
> This is just the headers in the luben code which need redoing completely
> because they're doing other stupid things like using bitfields for on the
> wire structures.

Don't think so (you're referring to Jeff's git-sas-jg.patch?). It dies
with current -linus tree.


drivers/scsi/sd.c: In function `sd_read_capacity':
drivers/scsi/sd.c:1301: internal error--unrecognizable insn:
(insn 1274 1273 1797 (parallel[
(set (reg:SI 0 %eax)
(asm_operands ("") ("=a") 0[
(reg:DI 1 %edx)
]
[
(asm_input:DI ("A"))
] ("drivers/scsi/sd.c") 1282))
(set (reg:SI 1 %edx)
(asm_operands ("") ("=d") 1[
(reg:DI 1 %edx)
]
[
(asm_input:DI ("A"))
] ("drivers/scsi/sd.c") 1282))
] ) -1 (insn_list 1269 (nil))
(nil))

It'll be workable aroundable of course, but it's a hassle.

Arjan van de Ven

unread,
Dec 13, 2005, 4:30:21 AM12/13/05
to
On Tue, 2005-12-13 at 10:03 +0100, Ingo Molnar wrote:

> * Arjan van de Ven <ar...@infradead.org> wrote:
>
> > > even better than that, why not use the solution that we've implemented
> > > for the -rt patchset, more than a year ago?
> > >
> > > the solution i took was this:
> > >
> > > - i did not touch the 'struct semaphore' namespace, but introduced a
> > > 'struct compat_semaphore'.
> >
> > which I think is wrong. THis naming sucks. Sure doing a full sed on
> > the tree is not pretty but it's also not THAT painful. And the pain of
> > wrong names is something the kernel needs to carry around for years.
>
> well, i'm all for renaming struct semaphore to struct mutex, but dont
> the same arguments apply as to 'struct timer_list'?

don't think so; this is not a "lets do them one by one over the year",
this is a "do them all right now at once" move.

Andi Kleen

unread,
Dec 13, 2005, 4:30:29 AM12/13/05
to
> Spose so - I don't know what people are using out there.

I don't think it was shipped in major distros at least (AFAIK)
They all went from 2.95 to 3.1/3.2

Perhaps stick an error for 3.0 in and wait if people are complaining?

>
> > AFAIK it has never been widely used. If we assume 3.1+ minimum it has the
> > advantage that named assembly arguments work, which make
> > the inline assembly often a lot easier to read and maintain.
>
> There are a few places in the tree which refuse to compile with 3.1 and 3.2.

Really? Which ones?

Haven't seen that and I still use 3.2 occasionally (it's the default
compiler on SLES9 and I believe on RHEL3 too)

-Andi

Christoph Hellwig

unread,
Dec 13, 2005, 4:30:29 AM12/13/05
to
On Tue, Dec 13, 2005 at 01:14:13AM -0800, Andrew Morton wrote:
> Christoph Hellwig <h...@infradead.org> wrote:
> >
> > On Tue, Dec 13, 2005 at 12:42:57AM -0800, Andrew Morton wrote:
> > > scsi/sd.c is currently getting an ICE. None of the new SAS code compiles,
> > > due to extensive use of anonymous unions.
> >
> > This is just the headers in the luben code which need redoing completely
> > because they're doing other stupid things like using bitfields for on the
> > wire structures.
>
> Don't think so (you're referring to Jeff's git-sas-jg.patch?). It dies
> with current -linus tree.

I didn't mean sd.c but the anonymous union usage. Everything that's stuffed
into include/scsi/sas/ in -mm is far from mergeable. It's really badly done
headers that need to be redone.

Andi Kleen

unread,
Dec 13, 2005, 4:30:29 AM12/13/05
to
> > Or start using icecream (http://wiki.kde.org/icecream)
>
> distcc is pretty good too. I have a minimal kernel build done in 19
> seconds, a fuller build (1.5MB bzImage that boots on all my testboxes)
> done in 45 seconds, using gcc 4.0.2.

icecream is better though - it reacts dynamically to your network
and it handles different installed compiler versions and cross compilation
nicely.

-Andi

Ingo Molnar

unread,
Dec 13, 2005, 4:40:23 AM12/13/05
to

* Andi Kleen <a...@suse.de> wrote:

> > it's not _that_ bad, if done overnight. It does not touch any of the
> > down/up APIs. Touching those would create a monster patch and monster
> > impact.
>
> One argument for a full rename (and abandoning the old "struct
> semaphore" name completely) would be that it would offer a clean break
> for out tree code, no silent breakage.

yeah. Another way to handle it would be to keep 'struct semaphore' for
the traditional semaphore type (together with the APIs), and to mark
them deprecated. I.e. we'd have 3 separate types and 3 separate sets of
APIs:

'struct mutex' & APIs
'struct semaphore' & APIs
'struct compat_semaphore' & APIs

phase #1: we do an overnight rename to 'struct mutex' and to
'struct compat_semaphore', based on the info that has been
mapped by the -rt tree. We mark 'struct semaphore' deprecated.

phase #2: we let out-of-tree code still work that uses struct
semaphore, but for new code applied, it must not be used.

phase #3: we remove 'struct semaphore' and APIs.

the problem with this approach is that it touches the semaphore APIs
too, which increases the impact of the rename by a _factor of 10_. Right
now we have ~600 places that use 'struct semaphore', but we have over
7000 places that use the APIs! I dont think it's realistic to do an
overnight change of all the APIs, we'd break every out-of-kernel tree in
a massive way. (the type change alone is much more manageable)

Ingo

Ingo Molnar

unread,
Dec 13, 2005, 4:40:22 AM12/13/05
to

* Andi Kleen <a...@suse.de> wrote:

> > it's not _that_ bad, if done overnight. It does not touch any of the
> > down/up APIs. Touching those would create a monster patch and monster
> > impact.
>
> One argument for a full rename (and abandoning the old "struct
> semaphore" name completely) would be that it would offer a clean break
> for out tree code, no silent breakage.

btw., in the -rt tree we rarely had 'silent breakage' - roughly 80% of
the cases were caught build-time: we eliminated DECLARE_MUTEX_LOCKED,
which is a clear sign for non-mutex semaphore usage. Another 19% was
caught by runtime checks: 'does owner unlock the mutex'. The remaining
1% was breakage that was not found quickly.

Ingo

Ingo Molnar

unread,
Dec 13, 2005, 4:50:11 AM12/13/05
to

* Christoph Hellwig <h...@infradead.org> wrote:

> On Tue, Dec 13, 2005 at 08:54:41AM +0100, Ingo Molnar wrote:
> > - i did not touch the 'struct semaphore' namespace, but introduced a
> > 'struct compat_semaphore'.
>

> Because it's totally braindead. Your compat_semaphore is a real

> semaphore and your semaphore is a mutex. So name them as such.

well, i had the choice between a 30K patch, a 300K patch and a 3000K
patch. I went for the 30K patch ;-)

> > - i introduced a 'type-sensitive' macro wrapper that switches down()
> > (and the other APIs) to either to the assembly variant (if the
> > variable's type is struct compat_semaphore), or switches it to the new
> > generic mutex (if the type is struct semaphore), at build-time. There
> > is no runtime overhead due to this build-time-switching.
>
> And this one is probably is a great help to win the obsfucated C
> contests, but otherwise just harmfull.

i never found it to be harmful in any way, and we've now got a year of
experience with them. Could you elaborate?

Ingo

Andrew Morton

unread,
Dec 13, 2005, 4:50:13 AM12/13/05
to
Andi Kleen <a...@suse.de> wrote:
>
> > There are a few places in the tree which refuse to compile with 3.1 and 3.2.
>
> Really? Which ones?

grep for __GNUC_MINOR__

Andi Kleen

unread,
Dec 13, 2005, 5:00:13 AM12/13/05
to
On Tue, Dec 13, 2005 at 01:44:37AM -0800, Andrew Morton wrote:
> Andi Kleen <a...@suse.de> wrote:
> >
> > > There are a few places in the tree which refuse to compile with 3.1 and 3.2.
> >
> > Really? Which ones?
>
> grep for __GNUC_MINOR__

I reviewed them and I didn't find any that refused 3.2 or 3.3.

Some architectures have special code for old gccs, but nothing
generic.

-Andi

Ingo Molnar

unread,
Dec 13, 2005, 5:00:17 AM12/13/05
to

* Ingo Molnar <mi...@elte.hu> wrote:

> all this simplified the 'compatibility conversion' to the patch below.
> No other non-generic changes are needed.

there were 3 more patches needed, which convert some semaphores to
completions:

sx8-sem2completions.patch
cpu5wdt-sem2completions.patch
ide-gendev-sem-to-completion.patch

all attached.

Ingo

sx8-sem2completions.patch
cpu5wdt-sem2completions.patch
ide-gendev-sem-to-completion.patch

David Howells

unread,
Dec 13, 2005, 5:00:20 AM12/13/05
to
Nick Piggin <nickp...@yahoo.com.au> wrote:

> We have atomic_cmpxchg. Can you use that for a sufficient generic
> implementation?

No. CMPXCHG/CAS is not as available as XCHG, and it's also unnecessary.

David

Jakub Jelinek

unread,
Dec 13, 2005, 5:10:14 AM12/13/05
to
On Tue, Dec 13, 2005 at 01:02:33AM -0800, Andrew Morton wrote:
> Andrew Morton <ak...@osdl.org> wrote:
> >
> > Thus far I have this:
> >
>
> And this:
>
>
> From: Andrew Morton <ak...@osdl.org>
>
> Remove various things which were checking for gcc-1.x and gcc-2.x compilers.

> --- devel/arch/arm/kernel/asm-offsets.c~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800


> +++ devel-akpm/arch/arm/kernel/asm-offsets.c 2005-12-13 00:53:27.000000000 -0800
> @@ -23,18 +23,13 @@
> #error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
> #endif
> /*
> - * GCC 2.95.1, 2.95.2: ignores register clobber list in asm().
> * GCC 3.0, 3.1: general bad code generation.
> * GCC 3.2.0: incorrect function argument offset calculation.
> * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
> * (http://gcc.gnu.org/PR8896) and incorrect structure
> * initialisation in fs/jffs2/erase.c
> */
> -#if __GNUC__ < 2 || \
> - (__GNUC__ == 2 && __GNUC_MINOR__ < 95) || \
> - (__GNUC__ == 2 && __GNUC_MINOR__ == 95 && __GNUC_PATCHLEVEL__ != 0 && \
> - __GNUC_PATCHLEVEL__ < 3) || \
> - (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
> +#if __GNUC__ < 2 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
> #error Your compiler is too buggy; it is known to miscompile kernels.
> #error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3
> #endif

Guess

#if __GNUC__ == 3 && __GNUC_MINOR__ < 3


#error Your compiler is too buggy; it is known to miscompile kernels.

#error Known good compilers: 3.3, 3.4, 4.0
#endif

would be better. __GNUC__ < 2 will certainly be errored about in other
places and it is bad to suggest compilers that are no longer supported
as known good ones.

Jakub

Ingo Molnar

unread,
Dec 13, 2005, 5:10:17 AM12/13/05
to

* Ingo Molnar <mi...@elte.hu> wrote:

> > On Tue, Dec 13, 2005 at 08:54:41AM +0100, Ingo Molnar wrote:
> > > - i did not touch the 'struct semaphore' namespace, but introduced a
> > > 'struct compat_semaphore'.
> >
> > Because it's totally braindead. Your compat_semaphore is a real
> > semaphore and your semaphore is a mutex. So name them as such.
>
> well, i had the choice between a 30K patch, a 300K patch and a 3000K
> patch. I went for the 30K patch ;-)

in that sense i'm all for going for the 300K patch, which is roughly the
direction David is heading into: rename to 'struct mutex' but keep the
down/up APIs, and introduce sem_down()/sem_up()/ for the cases that need
full semaphores.

i dont think the 3000K patch (full API rename, introduction of
mutex_down()/mutex_up()) is realistic.

Andi Kleen

unread,
Dec 13, 2005, 5:20:14 AM12/13/05
to
> Guess
>
> #if __GNUC__ == 3 && __GNUC_MINOR__ < 3
> #error Your compiler is too buggy; it is known to miscompile kernels.
> #error Known good compilers: 3.3, 3.4, 4.0
> #endif
>
> would be better. __GNUC__ < 2 will certainly be errored about in other
> places and it is bad to suggest compilers that are no longer supported
> as known good ones.

Are there really any known serious miscompilation with 3.1/3.2?
(I knew it used to miscompile some loops on x86-64, but I think I worked
around all that)

Preventing SLES9 and RHEL3 users from easily compiling new kernels
isn't good.

-Andi

Jakub Jelinek

unread,
Dec 13, 2005, 5:20:20 AM12/13/05
to
On Tue, Dec 13, 2005 at 11:11:53AM +0100, Andi Kleen wrote:
> > Guess
> >
> > #if __GNUC__ == 3 && __GNUC_MINOR__ < 3
> > #error Your compiler is too buggy; it is known to miscompile kernels.
> > #error Known good compilers: 3.3, 3.4, 4.0
> > #endif
> >
> > would be better. __GNUC__ < 2 will certainly be errored about in other
> > places and it is bad to suggest compilers that are no longer supported
> > as known good ones.
>
> Are there really any known serious miscompilation with 3.1/3.2?
> (I knew it used to miscompile some loops on x86-64, but I think I worked
> around all that)
>
> Preventing SLES9 and RHEL3 users from easily compiling new kernels
> isn't good.

The above is ARM solely, the comment there mentions some ARM postreload bug
that was only fixed in 3.3+.
I'd say 3.2 should be generally supported for the time being on arches
where there weren't significant problems with it.

Jakub

Jakub Jelinek

unread,
Dec 13, 2005, 5:20:27 AM12/13/05
to
On Tue, Dec 13, 2005 at 09:04:29AM +0000, Christoph Hellwig wrote:
> >
> > Remove -Wdeclaration-after-statement
> >
> > Now that gcc 2.95 is not supported anymore it's ok to use C99
> > style mixed declarations everywhere.
>
> Nack. This code style is pure obsfucation and we should disallow it forever.

Why? It greatly increases readability when variable declarations can be
moved close to their actual uses. glibc changed a lot of its codebase
this way and from my experience it really helps.

Ingo Molnar

unread,
Dec 13, 2005, 5:20:31 AM12/13/05
to

* David Howells <dhow...@redhat.com> wrote:

> Nick Piggin <nickp...@yahoo.com.au> wrote:
>
> > We have atomic_cmpxchg. Can you use that for a sufficient generic
> > implementation?
>
> No. CMPXCHG/CAS is not as available as XCHG, and it's also unnecessary.

take a look at the PREEMPT_RT implementation of mutexes: it uses
cmpxchg(), and thus both the down() and the up() fastpath is lockless!
(And that is a mutex type that does alot more things, as it supports
priority inheritance.)

architectures which dont have cmpxchg can use a spinlock just fine.

Ingo

Alexey Dobriyan

unread,
Dec 13, 2005, 5:20:33 AM12/13/05
to
On Tue, Dec 13, 2005 at 01:14:13AM -0800, Andrew Morton wrote:
> drivers/scsi/sd.c: In function `sd_read_capacity':
> drivers/scsi/sd.c:1301: internal error--unrecognizable insn:
> (insn 1274 1273 1797 (parallel[
> (set (reg:SI 0 %eax)
> (asm_operands ("") ("=a") 0[
> (reg:DI 1 %edx)
> ]
> [
> (asm_input:DI ("A"))
> ] ("drivers/scsi/sd.c") 1282))
> (set (reg:SI 1 %edx)
> (asm_operands ("") ("=d") 1[
> (reg:DI 1 %edx)
> ]
> [
> (asm_input:DI ("A"))
> ] ("drivers/scsi/sd.c") 1282))
> ] ) -1 (insn_list 1269 (nil))
> (nil))
>
> It'll be workable aroundable of course, but it's a hassle.

FWIW,

--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1282,9 +1282,9 @@ got_data:
sector_div(mb, 1950);

printk(KERN_NOTICE "SCSI device %s: "
- "%llu %d-byte hdwr sectors (%llu MB)\n",
+ "%llu %d-byte hdwr sectors\n",
diskname, (unsigned long long)sdkp->capacity,
- hard_sector, (unsigned long long)mb);
+ hard_sector);
}

/* Rescale capacity to 512-byte units */

Andrew Morton

unread,
Dec 13, 2005, 5:30:08 AM12/13/05
to
Andi Kleen <a...@suse.de> wrote:
>
> > Guess
> >
> > #if __GNUC__ == 3 && __GNUC_MINOR__ < 3
> > #error Your compiler is too buggy; it is known to miscompile kernels.
> > #error Known good compilers: 3.3, 3.4, 4.0
> > #endif
> >
> > would be better. __GNUC__ < 2 will certainly be errored about in other
> > places and it is bad to suggest compilers that are no longer supported
> > as known good ones.
>
> Are there really any known serious miscompilation with 3.1/3.2?
> (I knew it used to miscompile some loops on x86-64, but I think I worked
> around all that)
>
> Preventing SLES9 and RHEL3 users from easily compiling new kernels
> isn't good.
>

3.2.1 works OK on x86.

Christoph Hellwig

unread,
Dec 13, 2005, 5:30:16 AM12/13/05
to
On Tue, Dec 13, 2005 at 05:11:41AM -0500, Jakub Jelinek wrote:
> On Tue, Dec 13, 2005 at 09:04:29AM +0000, Christoph Hellwig wrote:
> > >
> > > Remove -Wdeclaration-after-statement
> > >
> > > Now that gcc 2.95 is not supported anymore it's ok to use C99
> > > style mixed declarations everywhere.
> >
> > Nack. This code style is pure obsfucation and we should disallow it forever.
>
> Why? It greatly increases readability when variable declarations can be
> moved close to their actual uses. glibc changed a lot of its codebase
> this way and from my experience it really helps.

mentioning glibc and readability in the same sentence disqualies your here,
sorry ;-)

But serious, having to look all over the source instead of just a block
beginning decreases code readability a lot. And if you have to scroll more
than a page to the block beginning on a 80x24 terminal means the code needs
a refactoring anyway.

Ingo Molnar

unread,
Dec 13, 2005, 5:30:17 AM12/13/05
to

* Christoph Hellwig <h...@infradead.org> wrote:

> On Tue, Dec 13, 2005 at 05:11:41AM -0500, Jakub Jelinek wrote:
> > On Tue, Dec 13, 2005 at 09:04:29AM +0000, Christoph Hellwig wrote:
> > > >
> > > > Remove -Wdeclaration-after-statement
> > > >
> > > > Now that gcc 2.95 is not supported anymore it's ok to use C99
> > > > style mixed declarations everywhere.
> > >
> > > Nack. This code style is pure obsfucation and we should disallow it forever.
> >
> > Why? It greatly increases readability when variable declarations can be
> > moved close to their actual uses. glibc changed a lot of its codebase
> > this way and from my experience it really helps.
>
> mentioning glibc and readability in the same sentence disqualies your
> here, sorry ;-)

it's a different coding style, but otherwise i find glibc highly
readable and well-maintained. It is also a more mature piece of code
than say the kernel, e.g. API-wise, so we could indeed learn a few
things. Just consider the fact that glibc has 10 times more APIs than
the kernel, and still it is breaking apps less often than the kernel.
But i digress :-)

Ingo

Ingo Molnar

unread,
Dec 13, 2005, 5:40:07 AM12/13/05
to

* Ingo Molnar <mi...@elte.hu> wrote:

>
> * Ingo Molnar <mi...@elte.hu> wrote:
>
> > > Nick Piggin <nickp...@yahoo.com.au> wrote:
> > >
> > > > We have atomic_cmpxchg. Can you use that for a sufficient generic
> > > > implementation?
> > >
> > > No. CMPXCHG/CAS is not as available as XCHG, and it's also unnecessary.
> >
> > take a look at the PREEMPT_RT implementation of mutexes: it uses
> > cmpxchg(), and thus both the down() and the up() fastpath is lockless!
> > (And that is a mutex type that does alot more things, as it supports
> > priority inheritance.)
> >
> > architectures which dont have cmpxchg can use a spinlock just fine.
>

> the cost of a spinlock-based generic_cmpxchg could be significantly
> reduced by adding a generic_cmpxchg() variant that also includes a
> 'spinlock pointer' parameter.
>
> Architectures that do not have the instruction, can use the specified
> spinlock to do the cmpxchg. This means that there wont be one single
> global spinlock to emulate cmpxchg, but the mutex's own spinlock can
> be used for it.
>
> Architectures that have the cmpxchg instruction would simply ignore
> the parameter, and would incur no overhead.

an additional twist: we could add generic_cmpxchg_lock(), which would
return the spinlock locked if the cmpxchg fails. (this is what we want
to do anyway) This way architectures that dont have CMPXCHG would take
the spinlock unconditionally and do the cmp-xchg emulation, while the
other architectures would take it only if the cmpxchg fails.

Ingo Molnar

unread,
Dec 13, 2005, 5:40:07 AM12/13/05
to

* Ingo Molnar <mi...@elte.hu> wrote:

> > Nick Piggin <nickp...@yahoo.com.au> wrote:
> >
> > > We have atomic_cmpxchg. Can you use that for a sufficient generic
> > > implementation?
> >
> > No. CMPXCHG/CAS is not as available as XCHG, and it's also unnecessary.
>
> take a look at the PREEMPT_RT implementation of mutexes: it uses
> cmpxchg(), and thus both the down() and the up() fastpath is lockless!
> (And that is a mutex type that does alot more things, as it supports
> priority inheritance.)
>
> architectures which dont have cmpxchg can use a spinlock just fine.

the cost of a spinlock-based generic_cmpxchg could be significantly

reduced by adding a generic_cmpxchg() variant that also includes a
'spinlock pointer' parameter.

Architectures that do not have the instruction, can use the specified
spinlock to do the cmpxchg. This means that there wont be one single
global spinlock to emulate cmpxchg, but the mutex's own spinlock can be
used for it.

Architectures that have the cmpxchg instruction would simply ignore the
parameter, and would incur no overhead.

Ingo

Andi Kleen

unread,
Dec 13, 2005, 5:40:13 AM12/13/05
to
On Tue, Dec 13, 2005 at 11:28:41AM +0100, Andreas Schwab wrote:
> Andi Kleen <a...@suse.de> writes:
>
> > Haven't seen that and I still use 3.2 occasionally (it's the default
> > compiler on SLES9 and I believe on RHEL3 too)
>
> SLES9 has 3.3-hammer.

You're right - i meant to write SLES8 where 3.2 was default.

Andreas Schwab

unread,
Dec 13, 2005, 5:40:15 AM12/13/05
to
Andi Kleen <a...@suse.de> writes:

> Haven't seen that and I still use 3.2 occasionally (it's the default
> compiler on SLES9 and I believe on RHEL3 too)

SLES9 has 3.3-hammer.

Andreas.

--
Andreas Schwab, SuSE Labs, sch...@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."

David Howells

unread,
Dec 13, 2005, 6:00:29 AM12/13/05
to
Andrew Morton <ak...@osdl.org> wrote:

> Maybe I'm not understanding all this, but...
>
> I'd have thought that the way to do this is to simply reimplement down(),
> up(), down_trylock(), etc using the new xchg-based code

Which I did.

> and to then hunt down those few parts of the kernel which actually use the
> old semaphore's counting feature and convert them to use down_sem(),
> up_sem(), etc.

Done, I think. It's not always 100% obvious.

> And rename all the old semaphore code: s/down/down_sem/etc.

Done.

> So after such a transformation, this new "mutex" thingy would not exist.

Why not? I want to make them different types so that you can't use the wrong
operators by accident or mix them.

> > include/linux/mutex.h | 32 +++++++
>
> But it does.

Well, I could fold this into each asm/semaphore.h.

> > +#define mutex_grab(mutex) (xchg(&(mutex)->state, 1) == 0)
>
> mutex_trylock(), please.

You're right.

> > +#define is_mutex_locked(mutex) ((mutex)->state)
>
> Let's keep the namespace consistent. mutex_is_locked().

But that's a poor name: it turns it from a question into a statement:-(

> > +static inline void down(struct mutex *mutex)
> > +{
> > + if (mutex_grab(mutex)) {
>
> likely()

No... down_trylock().

> > +static inline int down_interruptible(struct mutex *mutex)
> > +{
> > + if (mutex_grab(mutex)) {
>
> likely()

down_trylock() again.

> > +static inline int down_trylock(struct mutex *mutex)
> > +{
> > + if (mutex_grab(mutex)) {
>
> etc.

Yes.

> You could just put likely() into mutex_trylock(). err, mutex_grab().
>
> > +/*
> > + * release the mutex
> > + */
> > +static inline void up(struct mutex *mutex)
> > +{
> > + unsigned long flags;
> > +
> > +#ifdef CONFIG_DEBUG_MUTEX_OWNER
> > + if (mutex->__owner != current)
> > + __up_bad(mutex);
> > + mutex->__owner = NULL;
> > +#endif
> > +
> > + /* must prevent a race */
> > + spin_lock_irqsave(&mutex->wait_lock, flags);
> > + if (!list_empty(&mutex->wait_list))
> > + __up(mutex);
> > + else
> > + mutex_release(mutex);
> > + spin_unlock_irqrestore(&mutex->wait_lock, flags);
> > +}
>
> This is too large to inline.

You're probably right.

> It's also significantly slower than the existing up()?

Hmmm... If you've only got two states available to you and/or you can only
exchange states, then there's a limit to what you can actually do. You can lose
the spinlock in the up() fastpath if you're willing to forgo fairness or resort
to waking up processes superfluously.

Ingo and Nick have a point about using CMPXCHG or equivalent if it's
available. This lets you modify the state you have, rather than swapping it for
a whole new state; in which case the state can be annotated to indicate that
there is waking up to be done, thus permitting the fast path to be much
faster. But this can only be done in the case where the state may be modified.

As I tried to make clear: this is the simplest I could come up with, but I have
made provision for overriding it with something better if that's possible.

David

Ingo Molnar

unread,
Dec 13, 2005, 6:00:38 AM12/13/05
to

* David Howells <dhow...@redhat.com> wrote:

> init_MUTEX_LOCKED()
> DECLARE_MUTEX_LOCKED()

please kill these two in the simple mutex implementation - they are a
sign of mutexes used as completions.

> (7) Provides a debugging config option CONFIG_DEBUG_MUTEX_OWNER by which the
> mutex owner can be tracked and by which over-upping can be detected.

another simplification: also enforce that only the owner can unlock the
mutex. This is what we are doing in the -rt patch. (This rule also
ensures that such mutexes can be used for priority inheritance.)

Ingo

David Howells

unread,
Dec 13, 2005, 6:30:21 AM12/13/05
to
Ingo Molnar <mi...@elte.hu> wrote:

> > init_MUTEX_LOCKED()
> > DECLARE_MUTEX_LOCKED()
>
> please kill these two in the simple mutex implementation - they are a
> sign of mutexes used as completions.

That can be done later. It's not necessary to do it in this particular patch
set.

David

David Howells

unread,
Dec 13, 2005, 6:30:28 AM12/13/05
to
Nick Piggin <nickp...@yahoo.com.au> wrote:

> Any reason why you're setting up your own style of waitqueue in
> mutex-simple.c instead of just using the kernel's style of waitqueue?

Because I can steal the code from FRV's semaphores or rw-semaphores, and this
way I can be sure of what I'm doing.

Note that the sleeping processes are generally dequeued and dispatched by the
up() function, which means they don't have to take the spinlock themselves.
This may be possible to do magically with the waitqueue stuff, but I'm not sure
how to do it; it's horribly complicated to read through the sources and there
isn't much documentation.

> > + mb();
>
> This should be smp_mb(), I think.

Yes.

David Howells

unread,
Dec 13, 2005, 6:40:12 AM12/13/05
to
David Howells <dhow...@redhat.com> wrote:

> > Any reason why you're setting up your own style of waitqueue in
> > mutex-simple.c instead of just using the kernel's style of waitqueue?
>
> Because I can steal the code from FRV's semaphores or rw-semaphores, and this
> way I can be sure of what I'm doing.

And because:

struct mutex {
int state;
wait_queue_head_t wait_queue;
};

Wastes 8 more bytes of memory than:

struct mutex {
int state;
spinlock_t wait_lock;
struct list_head wait_list;
};

on a 64-bit machine if spinlock_t is 4 bytes. Both waste 4 bytes if spinlock_t
is 8 bytes.

Matthew Wilcox

unread,
Dec 13, 2005, 7:40:23 AM12/13/05
to
On Tue, Dec 13, 2005 at 10:24:37AM +0100, Andi Kleen wrote:
> > Spose so - I don't know what people are using out there.
>
> I don't think it was shipped in major distros at least (AFAIK)
> They all went from 2.95 to 3.1/3.2

Debian Woody (3.0) shipped a mess of compilers -- 2.95 for most, 2.96
for ia64 and 3.0 for parisc. That was released in July 2002. Sarge
(3.1) shipped in June 2005 and uses GCC 3.3 on all architectures.

Matthew Wilcox

unread,
Dec 13, 2005, 7:50:16 AM12/13/05
to
On Tue, Dec 13, 2005 at 10:48:19AM +0000, David Howells wrote:
> > > +#define is_mutex_locked(mutex) ((mutex)->state)
> >
> > Let's keep the namespace consistent. mutex_is_locked().
>
> But that's a poor name: it turns it from a question into a statement:-(

Ah, but look at it in context of how it's used:

if (is_mutex_locked())
That's gramatically incorrect!

if (mutex_is_locked())
much better.

Oliver Neukum

unread,
Dec 13, 2005, 7:50:27 AM12/13/05
to
Am Dienstag, 13. Dezember 2005 11:34 schrieb Ingo Molnar:

> the cost of a spinlock-based generic_cmpxchg could be significantly
> reduced by adding a generic_cmpxchg() variant that also includes a
> 'spinlock pointer' parameter.
>
> Architectures that do not have the instruction, can use the specified
> spinlock to do the cmpxchg. This means that there wont be one single
> global spinlock to emulate cmpxchg, but the mutex's own spinlock can be
> used for it.

Can't you use the pointer as a hash input?

Regards
Oliver

Alan Cox

unread,
Dec 13, 2005, 8:10:10 AM12/13/05
to
On Llu, 2005-12-12 at 23:45 +0000, David Howells wrote:
> (5) Redirects the following to apply to the new mutexes rather than the
> traditional semaphores:
>
> down()
> down_trylock()
> down_interruptible()
> up()
> init_MUTEX()
> init_MUTEX_LOCKED()
> DECLARE_MUTEX()
> DECLARE_MUTEX_LOCKED()

And you've audited every occurence ?

> On the basis that most usages of semaphores are as mutexes, this makes
> sense for in most cases it's just then a matter of changing the type from
> struct semaphore to struct mutex.

You propose to rename the existing up and down, which are counting
semaphores, documented and used that way everywhere with mutexes which
are not. Worse still up/down are, second to P/V, the usual forms of
referring to _counting_ semaphores.

It seems to me it would be far far saner to define something like

sleep_lock(&foo)
sleep_unlock(&foo)
sleep_trylock(&foo)

given the new mutex interface is actually a sleeping interface with the
semantics of the spin_lock interface. Its then obvious what it does, you
don't randomly break other drivers you've not reviewed and the interface
is intuitive rather than obfuscated.

It won't take long for people to then change the name of the performance
critical cases and the others will catch up in time.

It also saves breaking every piece of out of tree kernel code for now
good reason.

Alan

Alan Cox

unread,
Dec 13, 2005, 8:20:09 AM12/13/05
to
Actually a PS to this while I think about it. spin_locks and mutex type
locks could both do with a macro for

call_locked(&lock, foo(a,b,c,d))

to cut down on all the error path forgot to release a lock type errors.

Alan Cox

unread,
Dec 13, 2005, 8:20:11 AM12/13/05
to
On Maw, 2005-12-13 at 13:47 +0100, Oliver Neukum wrote:
> > spinlock to do the cmpxchg. This means that there wont be one single
> > global spinlock to emulate cmpxchg, but the mutex's own spinlock can be
> > used for it.
>
> Can't you use the pointer as a hash input?

Some platforms already do this for certain sets of operations like
atomic_t. The downside however is that you no longer control the lock
contention or cache line bouncing. It becomes a question of luck rather
than science as to how well it scales.

Matthew Wilcox

unread,
Dec 13, 2005, 8:20:12 AM12/13/05
to
On Tue, Dec 13, 2005 at 01:09:31PM +0000, Alan Cox wrote:
> On Maw, 2005-12-13 at 13:47 +0100, Oliver Neukum wrote:
> > Can't you use the pointer as a hash input?
>
> Some platforms already do this for certain sets of operations like
> atomic_t. The downside however is that you no longer control the lock
> contention or cache line bouncing. It becomes a question of luck rather
> than science as to how well it scales.

s/luck/statistics/

You can always increase the size of the hash table if you encounter
scaling problems.

Oliver Neukum

unread,
Dec 13, 2005, 8:30:09 AM12/13/05
to
Am Dienstag, 13. Dezember 2005 14:09 schrieb Alan Cox:
> On Maw, 2005-12-13 at 13:47 +0100, Oliver Neukum wrote:
> > > spinlock to do the cmpxchg. This means that there wont be one single
> > > global spinlock to emulate cmpxchg, but the mutex's own spinlock can be
> > > used for it.
> >
> > Can't you use the pointer as a hash input?
>
> Some platforms already do this for certain sets of operations like
> atomic_t. The downside however is that you no longer control the lock
> contention or cache line bouncing. It becomes a question of luck rather
> than science as to how well it scales.

On the other hand you don't control cache eviction either, do you?

Regards
Oliver

David Howells

unread,
Dec 13, 2005, 8:40:14 AM12/13/05
to
Alan Cox <al...@lxorguk.ukuu.org.uk> wrote:

> > (5) Redirects the following to apply to the new mutexes rather than the
> > traditional semaphores:
> >
> > down()

> ...


>
> And you've audited every occurence ?

Outside of the arch directories, yes; but I don't know that I've made the
correct decision in 100% of the cases.

I've changed some of the uses into completions, and found about a dozen or so
uses of counting semaphores; but the vast majority of occurrences seem to be
wanting mutex behaviour.

> It seems to me it would be far far saner to define something like
>
> sleep_lock(&foo)
> sleep_unlock(&foo)
> sleep_trylock(&foo)

Which would be a _lot_ more work. It would involve about ten times as many
changes, I think, and thus be more prone to errors.

> Its then obvious what it does, you don't randomly break other drivers you've
> not reviewed and the interface is intuitive rather than obfuscated.

I've attempted to review everything in 2.6.15-rc5 outside of most of the archs.
I can't easily modify any driver not contained in that tarball, but at least
the compiler will barf and force a review.

> It won't take long for people to then change the name of the performance
> critical cases and the others will catch up in time.

It took about ten hours to go through the declarations of struct semaphore and
review them; I hate to think how long it'd take to go through all the ups and
downs too.

> It also saves breaking every piece of out of tree kernel code for now
> good reason.

But my patch means the changes required are in the most cases minimal: just
changing struct semaphore to struct mutex is sufficient for the vast majority
of cases.

Your way requires a lot more work, both in the tree and out of it.

David

Ingo Molnar

unread,
Dec 13, 2005, 8:50:30 AM12/13/05
to

* David Howells <dhow...@redhat.com> wrote:

> Ingo Molnar <mi...@elte.hu> wrote:
>
> > > init_MUTEX_LOCKED()
> > > DECLARE_MUTEX_LOCKED()
> >
> > please kill these two in the simple mutex implementation - they are a
> > sign of mutexes used as completions.
>
> That can be done later. It's not necessary to do it in this particular
> patch set.

i disagree - it's necessary that we dont build complexities into the
'simple' mutex type, or the whole game starts again. I.e. the 'owner
unlocks the mutex' rule must be enforced - which makes
DECLARE_MUTEX_LOCKED() meaningless.

Ingo

Alan Cox

unread,
Dec 13, 2005, 1:40:38 PM12/13/05
to
On Maw, 2005-12-13 at 13:32 +0000, David Howells wrote:
> > Its then obvious what it does, you don't randomly break other drivers you've
> > not reviewed and the interface is intuitive rather than obfuscated.
>
> I've attempted to review everything in 2.6.15-rc5 outside of most of the archs.
> I can't easily modify any driver not contained in that tarball, but at least
> the compiler will barf and force a review.


Is there a reason you didnt answer the comment about down/up being the
usual way computing refers to the operations on counting semaphores but
just deleted it ?

Alan Cox

unread,
Dec 13, 2005, 1:40:44 PM12/13/05
to
On Maw, 2005-12-13 at 06:13 -0700, Matthew Wilcox wrote:
> > Some platforms already do this for certain sets of operations like
> > atomic_t. The downside however is that you no longer control the lock
> > contention or cache line bouncing. It becomes a question of luck rather
> > than science as to how well it scales.
>
> s/luck/statistics/

Unfortunately not always. Statistical probability models generally
assume that samples are independent, as does just growing the hash
table. If there are correlations then how those correlations and the
hash function interact isn't simple statistics so growing the hash might
not work as well as would be hoped.

A second problem with the hash is it makes priority inversions
entertaining and unpredictable when using Ingo's -rt work. That isn't a
big problem with the atomic_t stuff in the parisc tree because atomic_t
is effectively the top of the lock ordering for the system.

Growing the hash while it may improve the behaviour isn't going to work
as well as embedding the lock in the object.

Alan

Arjan van de Ven

unread,
Dec 13, 2005, 1:40:56 PM12/13/05
to
On Tue, 2005-12-13 at 08:35 -0600, Christopher Friesen wrote:
> David Howells wrote:

> > Alan Cox <al...@lxorguk.ukuu.org.uk> wrote:
>
> >>It seems to me it would be far far saner to define something like
> >>
> >> sleep_lock(&foo)
> >> sleep_unlock(&foo)
> >> sleep_trylock(&foo)
> >
> > Which would be a _lot_ more work. It would involve about ten times as many
> > changes, I think, and thus be more prone to errors.
>
> "lots of work" has never been a valid reason for not doing a kernel
> change...
>
> In this case, introducing a new API means the changes can be made over time.

in this case, doing this change gradual I think is a mistake. We should
do all of the in-kernel code at least...

Linus Torvalds

unread,
Dec 13, 2005, 1:41:18 PM12/13/05
to

On Tue, 13 Dec 2005, Andi Kleen wrote:
>
> Remove -Wdeclaration-after-statement

Please don't.

It's a coding style issue. We put our variable declarations where people
can _find_ them, not in random places in the code.

Putting variables in the middle of code only improves readability when you
have messy code.

Now, one feature that _may_ be worth it is the loop counter thing:

for (int i = 10; i; i--)
...

kind of syntax actually makes sense and is a real feature (it makes "i"
local to the loop, and can actually help people avoid bugs - you can't use
"i" by mistake after the loop).

But I think you need "--std=c99" for gcc to take that.

Linus

David Howells

unread,
Dec 13, 2005, 1:41:26 PM12/13/05
to
Christopher Friesen <cfri...@nortel.com> wrote:

> > Which would be a _lot_ more work. It would involve about ten times as many
> > changes, I think, and thus be more prone to errors.
>

> "lots of work" has never been a valid reason for not doing a kernel change...

There are a number of considerations:

(1) If _I_ am going to be doing the work, then I'm quite happy to reduce the
load by 90%. And I think it'd be at least that, probably more. Finding
struct semaphore with grep is much easier than finding up/down with grep
because of:

(a) comments

(b) other instances of up/down names, including rw_semaphores

There are a lot fewer instances of struct semaphore than up and down.

(2) It makes it easier for other people. In most cases, all they need do is
change "struct semaphore" to "struct mutex". If they've used
DECLARE_MUTEX() then they need do nothing at all, and if they've used
init_MUTEX(), then they don't need to convert sema_init() either.

(3) It forces people to reconsider how they want to use their semaphores.

I have no objection to making life easier for other people. I suspect most
other people don't care that their semaphores are now mutexes, and think of
them that way anyway.

I admit that there are downsides:

(1) up and down now do something effectively different (though in most cases
it's also exactly the same).

(2) Users of counting semaphores have to change, but they're in the minority
by quite a way.

(3) Some people want mutexes to be:

(a) only releasable in the same context as they were taken

(b) not accessible in interrupt context, or that (a) applies here also

(c) not initialisable to the locked state

But this means that the current usages all have to be carefully audited,
and sometimes that unobvious.

Christopher Friesen

unread,
Dec 13, 2005, 1:42:05 PM12/13/05
to
Arjan van de Ven wrote:
> On Tue, 2005-12-13 at 08:35 -0600, Christopher Friesen wrote:

>>In this case, introducing a new API means the changes can be made over time.
>
>
> in this case, doing this change gradual I think is a mistake. We should
> do all of the in-kernel code at least...

This means verifying all the users before patch submission, which may be
problematic.

I guess the point I'm trying to make is that if you create a new API you
have the option of converting the obvious cases first, which should
cover the majority of users. Anywhere the behaviour is non-obvious can
be left using the old API, and the out-of-tree users will continue to
work correctly.

Chris

Mark Lord

unread,
Dec 13, 2005, 1:42:06 PM12/13/05
to
>'struct compat_semaphore'

I really think this data type needs a better name,
one that reflects what it does.

Something like 'struct binary_semaphore' or something.

Cheers

David Howells

unread,
Dec 13, 2005, 1:42:22 PM12/13/05
to
Paul Jackson <p...@sgi.com> wrote:

> It is usually too easy to produce a nearly correct script, and too
> difficult to produce an exactly right one, for all but serious sed or
> perl regex hackers.

I'd be especially impressed if you can get it to also analyse the context in
which the semaphore is used and determine whether or not it should be a
counting semaphore, a mutex or a completion. You can probably do this sort of
thing with Perl regexes... they seem to be terrifically[*] powerful.

[*] and I mean that in the proper sense:-)

David

David Howells

unread,
Dec 13, 2005, 1:42:46 PM12/13/05
to
Alan Cox <al...@lxorguk.ukuu.org.uk> wrote:

> Is there a reason you didnt answer the comment about down/up being the
> usual way computing refers to the operations on counting semaphores but
> just deleted it ?

up/down is also used in conjunction with mutexes and R/W semaphores, so
counting semaphores do not have exclusive rights to the terminology.

David

Arjan van de Ven

unread,
Dec 13, 2005, 1:42:56 PM12/13/05
to
On Tue, 2005-12-13 at 09:33 -0500, Mark Lord wrote:
> >'struct compat_semaphore'
>
> I really think this data type needs a better name,
> one that reflects what it does.
>
> Something like 'struct binary_semaphore' or something.

see the thing is.. this is the counting one ;)
the -rt naming is just too confusing (but done to keep patch maintenance
reasonable, which is fair enough for that purpose, but not good enough
for kernel.org)

Paul Jackson

unread,
Dec 13, 2005, 1:43:11 PM12/13/05
to
If we are doing global rename patches, could we make one of the
deliverables a sed or perl script that exactly produces the patch,
suitable for running one-time on out-of-kernel trees? Add the script
in the kernel scripts directory.

It is usually too easy to produce a nearly correct script, and too
difficult to produce an exactly right one, for all but serious sed or
perl regex hackers.

--
I won't rest till it's the best ...
Programmer, Linux Scalability
Paul Jackson <p...@sgi.com> 1.925.600.0401

Christopher Friesen

unread,
Dec 13, 2005, 1:43:28 PM12/13/05
to
David Howells wrote:
> Alan Cox <al...@lxorguk.ukuu.org.uk> wrote:

>>It seems to me it would be far far saner to define something like
>>
>> sleep_lock(&foo)
>> sleep_unlock(&foo)
>> sleep_trylock(&foo)
>
> Which would be a _lot_ more work. It would involve about ten times as many
> changes, I think, and thus be more prone to errors.

"lots of work" has never been a valid reason for not doing a kernel
change...

In this case, introducing a new API means the changes can be made over time.

As time goes on you can convert more and more code to the mutex/sleep
lock and any tricky code just stays with the older API until someone who
understands it can vet it.

As Alan mentioned, the standard counting semaphore API is up/down.
Making those refer to a sleeping mutex violates the principle of least
surprise.

Chris

Steven Rostedt

unread,
Dec 13, 2005, 3:10:29 PM12/13/05
to
On Tue, 2005-12-13 at 13:32 +0000, David Howells wrote:
> Alan Cox <al...@lxorguk.ukuu.org.uk> wrote:
>
> > > (5) Redirects the following to apply to the new mutexes rather than the
> > > traditional semaphores:
> > >
> > > down()
> > ...
> >
> > And you've audited every occurence ?
>
> Outside of the arch directories, yes; but I don't know that I've made the
> correct decision in 100% of the cases.

I'm in the crowd that thinks that the mutex downs and ups should be
converted to mutex_lock/mutex_unlock. Simply because that is basically
what a mutex is doing. I rather not have another "historical" API in
the kernel.

>
> I've changed some of the uses into completions, and found about a dozen or so
> uses of counting semaphores; but the vast majority of occurrences seem to be
> wanting mutex behaviour.

And we can take our time in looking at this in a case by case basis.

>
> > It seems to me it would be far far saner to define something like
> >
> > sleep_lock(&foo)
> > sleep_unlock(&foo)
> > sleep_trylock(&foo)
>
> Which would be a _lot_ more work. It would involve about ten times as many
> changes, I think, and thus be more prone to errors.

I don't think this should be a one shot patch. Your patch (and what you
would be responsible for) would just introduce the use of the mutex.
Let others go around and find the places where a semaphore is used where
a mutex should be. Yes there is a lot more mutexes than true
semaphores, and that is why we really should look at this in a case by
case basis. One big global change will probably more likely miss a case
that should be a semaphore.

>
> > Its then obvious what it does, you don't randomly break other drivers you've
> > not reviewed and the interface is intuitive rather than obfuscated.
>
> I've attempted to review everything in 2.6.15-rc5 outside of most of the archs.
> I can't easily modify any driver not contained in that tarball, but at least
> the compiler will barf and force a review.
>
> > It won't take long for people to then change the name of the performance
> > critical cases and the others will catch up in time.
>
> It took about ten hours to go through the declarations of struct semaphore and
> review them; I hate to think how long it'd take to go through all the ups and
> downs too.

That's why this should be a step by step integration.

>
> > It also saves breaking every piece of out of tree kernel code for now
> > good reason.
>
> But my patch means the changes required are in the most cases minimal: just
> changing struct semaphore to struct mutex is sufficient for the vast majority
> of cases.

But not every case.

>
> Your way requires a lot more work, both in the tree and out of it.

Not really. Over time this would be all cleaned up, but introducing a
new API should be the first step, then we can go to each and every spot
to find where a semaphore should be a mutex. You'll get a lot more
people helping you in that method then you globally changing it, and
people only help when it breaks.

I'm sure I'm not the only one that would be happy to send patches in to
convert semaphores to mutexes where I find them. But I'd be more
confused if something suddenly breaks that use to work, and then have to
see that "Oh this was a semaphore that mistakenly became a mutex!".

-- Steve

David Howells

unread,
Dec 13, 2005, 4:10:30 PM12/13/05
to
Arnd Bergmann <ar...@arndb.de> wrote:

> I can't see how your code actually detects the over-upping, although it's
> fairly obvious how it would be done. Did you miss one patch for this?

If owner is NULL, then you've probably upped twice.

David

Andi Kleen

unread,
Dec 13, 2005, 5:00:27 PM12/13/05
to
[dropping linux-arch because it seems to generate bounces]

On Tue, Dec 13, 2005 at 08:16:39AM -0800, Linus Torvalds wrote:
>
>
> On Tue, 13 Dec 2005, Andi Kleen wrote:
> >
> > Remove -Wdeclaration-after-statement
>
> Please don't.
>
> It's a coding style issue. We put our variable declarations where people
> can _find_ them, not in random places in the code.
>
> Putting variables in the middle of code only improves readability when you
> have messy code.

I like it when the scopes for variables are as small as possible because then
I also find it good documentation when the first initialization
of a variable also has the type.

While it's possible with nested {} blocks too that imho makes the code ugly
because you either end up with non syntactic elements with wrong
indentation (driving emacs/indent etc crazy) or with too much
indentation.

I can see Ingo's argument about catching merging mistakes though -
that is a good point against it that I didn't consider.

>
> Now, one feature that _may_ be worth it is the loop counter thing:
>
> for (int i = 10; i; i--)
> ...
>
> kind of syntax actually makes sense and is a real feature (it makes "i"
> local to the loop, and can actually help people avoid bugs - you can't use
> "i" by mistake after the loop).
>
> But I think you need "--std=c99" for gcc to take that.

Ok. So should we enable that? Or rather --std=gnu99

But actually I tried it and it causes lots of

mm/page_alloc.c:49: error: initializer element is not constant

It looks like casts in constant initializers for global structures are not
allowed anymore: struct foo x = (struct foo) { ... }; warns. That's
not good because when the (struct foo){} is generated in a macro
then it's the only easy way to allow initialization outside a declaration.

Common case is SPIN_LOCK_UNLOCKED() / DEFINE_SPINLOCK().

Richard, any comments on that?

P.S.: Linus, I wish you weren't so fond of using downcounting loops: I find
them always slightly confusing (or rather they need more consideration
than a standard upcounting loop to understand) and gcc is perfectly
capable of reversing loops when suitable on its own.

-Andi

Adrian Bunk

unread,
Dec 13, 2005, 5:20:13 PM12/13/05
to
On Tue, Dec 13, 2005 at 10:05:18AM +0100, Andi Kleen wrote:
> On Tue, Dec 13, 2005 at 01:01:26AM -0800, Andrew Morton wrote:
> > Andi Kleen <a...@suse.de> wrote:
> > >
> > > Can you please apply the following patch then?
> > >
> > > Remove -Wdeclaration-after-statement
> >
> > OK.
> >
> > Thus far I have this:
>
> Would it be possible to drop support for gcc 3.0 too?
> AFAIK it has never been widely used. If we assume 3.1+ minimum it has the
> advantage that named assembly arguments work, which make
> the inline assembly often a lot easier to read and maintain.

3.2+ would be better than 3.1+

Remember that 3.2 would have been named 3.1.2 if there wasn't the C++
ABI change, and I don't remember any big Linux distribution actually
using gcc 3.1 as default compiler.

And since gcc 3.2 was released one and a half years before kernel 2.6.0,
I doubt there's any distribution both supporting kernel 2.6 and not
shipping any gcc >= 3.2 .

> -Andi

cu
Adrian

--

"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed

Andi Kleen

unread,
Dec 13, 2005, 5:30:20 PM12/13/05
to
> 3.2+ would be better than 3.1+
>
> Remember that 3.2 would have been named 3.1.2 if there wasn't the C++
> ABI change, and I don't remember any big Linux distribution actually
> using gcc 3.1 as default compiler.

Yes, but the kernel doesn't use C++ and afaik other than that there were only
a few minor bugfixes between 3.1 and 3.2. So it doesn't make any
difference for this special case.

-Andi

Adrian Bunk

unread,
Dec 13, 2005, 5:40:09 PM12/13/05
to
On Tue, Dec 13, 2005 at 11:25:43PM +0100, Andi Kleen wrote:
> > 3.2+ would be better than 3.1+
> >
> > Remember that 3.2 would have been named 3.1.2 if there wasn't the C++
> > ABI change, and I don't remember any big Linux distribution actually
> > using gcc 3.1 as default compiler.
>
> Yes, but the kernel doesn't use C++ and afaik other than that there were only
> a few minor bugfixes between 3.1 and 3.2. So it doesn't make any
> difference for this special case.

gcc 3.2.3 is four bugfix releases and nine months later than 3.1.1, and
there are virtually no gcc 3.1 users.

It's not a strong opinion, but if the question is whether to draw the
line before or after gcc 3.1 I'd vote for dropping gcc 3.1 support.

> -Andi

cu
Adrian

--

"Is there not promise of rain?" Ling Tan asked suddenly out
of the darkness. There had been need of rain for many days.
"Only a promise," Lao Er said.
Pearl S. Buck - Dragon Seed

-

Paul Jackson

unread,
Dec 13, 2005, 5:40:17 PM12/13/05
to
> I'd be especially impressed if you can get it to also analyse the context in
> which the semaphore is used and determine whether or not it should be a
> counting semaphore, a mutex or a completion

That would impress me too, if I could do that.

I think that is well beyond my humble capabilities.

The sed/perl script to make the textual change should be practical.
Indeed, I would claim that the initial big patch -should- be done
that way. Keep refining a sed script until manual inspection and
trial builds of all arch's, allconfig, show that it seems to be right.
Each time you find an error doing this, don't manually edit the
kernel source; rather refine the script and try applying it again.

--
I won't rest till it's the best ...
Programmer, Linux Scalability
Paul Jackson <p...@sgi.com> 1.925.600.0401

Al Viro

unread,
Dec 13, 2005, 6:10:08 PM12/13/05
to
On Tue, Dec 13, 2005 at 10:56:10PM +0100, Andi Kleen wrote:
> It looks like casts in constant initializers for global structures are not
> allowed anymore: struct foo x = (struct foo) { ... }; warns. That's
> not good because when the (struct foo){} is generated in a macro
> then it's the only easy way to allow initialization outside a declaration.
>
> Common case is SPIN_LOCK_UNLOCKED() / DEFINE_SPINLOCK().

There are two similar things - struct initializers and compound literals.
They are *not* the same, though; compound literal defines an unnamed
object, so
{


struct foo x = (struct foo){...};

is equivalent to
struct foo unnamed_variable = {....};
struct foo x = unnamed_variable;

For auto variables it's fine; there initializer doesn't have to be
constant. For globals it's _not_.

Note that it's really a definition of object - e.. you can say
f(&(struct foo){....});
and have it work just fine.

IOW, DEFINE_SPINLOCK() should be spinlock_t x = __SPIN_LOCK_UNLOCKED()
and SPIN_LOCK_UNLOCKED - (spinlock_t) __SPIN_LOCK_UNLOCKED. That's
enough to make it valid C99...

Nikita Danilov

unread,
Dec 13, 2005, 6:30:10 PM12/13/05
to
Alan Cox writes:
> Actually a PS to this while I think about it. spin_locks and mutex type
> locks could both do with a macro for
>
> call_locked(&lock, foo(a,b,c,d))

reiser4 code was publicly humiliated for such macros, but indeed they
are useful. The only problem is that one needs two macros: one for foo()
returning void and one for all other cases.

>
> to cut down on all the error path forgot to release a lock type errors.
>

Nikita.

Andi Kleen

unread,
Dec 13, 2005, 6:50:09 PM12/13/05
to
> There are two similar things - struct initializers and compound literals.

I know they are not the same, but it's still annoying that gcc arbitarily
changes the definition of "GNU C" again. That is why I would consider
it more a bug than a feature.

-Andi

Nick Piggin

unread,
Dec 13, 2005, 8:10:08 PM12/13/05
to
David Howells wrote:
> Nick Piggin <nickp...@yahoo.com.au> wrote:
>
>
>>We have atomic_cmpxchg. Can you use that for a sufficient generic
>>implementation?
>
>
> No. CMPXCHG/CAS is not as available as XCHG, and it's also unnecessary.
>

atomic_cmpxchg should be available on all platforms.

While it may be strictly unnecessary, if it can be used to avoid
having a crappy default implementation that requires it to be
reimplemented in all architectures then that would be a good thing.

Any arguments about bad scalability or RT behaviour of the hashed
spinlock emulation atomic_t implementations are silly because they
are used by all atomic_ operations. It is an arch implementation
detail that generic code should not have to worry about.

--
SUSE Labs, Novell Inc.

Send instant messages to your online friends http://au.messenger.yahoo.com

Ingo Molnar

unread,
Dec 14, 2005, 3:40:07 AM12/14/05
to

* David Howells <dhow...@redhat.com> wrote:

> (3) Some people want mutexes to be:
>
> (a) only releasable in the same context as they were taken
>
> (b) not accessible in interrupt context, or that (a) applies here also
>
> (c) not initialisable to the locked state
>
> But this means that the current usages all have to be carefully audited,
> and sometimes that unobvious.

(a) and (c) is not a big problem, are they are essentially the
constraints of -rt mutexes. As long as there's good debugging code, it's
very much doable. We dont want to change semantics _yet again_, later
down the line.

Ingo

Alan Cox

unread,
Dec 14, 2005, 5:30:15 AM12/14/05
to
On Maw, 2005-12-13 at 15:39 +0000, David Howells wrote:
> (3) Some people want mutexes to be:
>
> (a) only releasable in the same context as they were taken
>
> (b) not accessible in interrupt context, or that (a) applies here also
>
> (c) not initialisable to the locked state
>
> But this means that the current usages all have to be carefully audited,
> and sometimes that unobvious.

Only if you insist on replacing them immediately. If you submit a
*small* patch which just adds the new mutexes then a series of small
patches can gradually convert code where mutexes are better. People will
naturally hit the hot and critical points first meaning that in a short
time the users of semaphores will be those who need it, and those who
are not critical to performance.

There is a problemn with init_MUTEX*/DECLARE_MUTEX naming being used for
semaphore struct init and I don't see a nice way to fix that either. I'd
rather see people just have to fix those as compiler errors (or a perl
-e regexp run to make them all init_SEM/DECLARE_SEM before any other
changes are made).

Arjan van de Ven

unread,
Dec 14, 2005, 5:40:15 AM12/14/05
to
On Tue, 2005-12-13 at 16:10 +0000, Alan Cox wrote:
> On Maw, 2005-12-13 at 15:39 +0000, David Howells wrote:
> > (3) Some people want mutexes to be:
> >
> > (a) only releasable in the same context as they were taken
> >
> > (b) not accessible in interrupt context, or that (a) applies here also
> >
> > (c) not initialisable to the locked state
> >
> > But this means that the current usages all have to be carefully audited,
> > and sometimes that unobvious.
>
> Only if you insist on replacing them immediately. If you submit a
> *small* patch which just adds the new mutexes then a series of small
> patches can gradually convert code where mutexes are better.

this unfortunately is not very realistic in practice...

Russell King

unread,
Dec 14, 2005, 5:50:09 AM12/14/05
to
On Tue, Dec 13, 2005 at 01:02:33AM -0800, Andrew Morton wrote:
> diff -puN arch/arm/kernel/asm-offsets.c~remove-gcc2-checks arch/arm/kernel/asm-offsets.c
> --- devel/arch/arm/kernel/asm-offsets.c~remove-gcc2-checks 2005-12-13 00:51:14.000000000 -0800
> +++ devel-akpm/arch/arm/kernel/asm-offsets.c 2005-12-13 00:53:27.000000000 -0800
> @@ -23,18 +23,13 @@
> #error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
> #endif
> /*
> - * GCC 2.95.1, 2.95.2: ignores register clobber list in asm().
> * GCC 3.0, 3.1: general bad code generation.
> * GCC 3.2.0: incorrect function argument offset calculation.
> * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c
> * (http://gcc.gnu.org/PR8896) and incorrect structure
> * initialisation in fs/jffs2/erase.c
> */
> -#if __GNUC__ < 2 || \
> - (__GNUC__ == 2 && __GNUC_MINOR__ < 95) || \
> - (__GNUC__ == 2 && __GNUC_MINOR__ == 95 && __GNUC_PATCHLEVEL__ != 0 && \
> - __GNUC_PATCHLEVEL__ < 3) || \
> - (__GNUC__ == 3 && __GNUC_MINOR__ < 3)
> +#if __GNUC__ < 2 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)

Shouldn't this be:

+#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3)

?

> #error Your compiler is too buggy; it is known to miscompile kernels.
> #error Known good compilers: 2.95.3, 2.95.4, 2.96, 3.3

And this should also have the 2.95 and 2.96 stuff edited out.

--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 Serial core

David Howells

unread,
Dec 14, 2005, 6:00:26 AM12/14/05
to
Nick Piggin <nickp...@yahoo.com.au> wrote:

> atomic_cmpxchg should be available on all platforms.

Two points:

(1) If it's using spinlocks, then it's pointless to use atomic_cmpxchg.

(2) atomic_t is a 32-bit type, and on a 64-bit platform I will want a 64-bit
type so that I can stick the owner address in there (I've got a second
variant not yet released).

David

Arjan van de Ven

unread,
Dec 14, 2005, 6:10:13 AM12/14/05
to
On Wed, 2005-12-14 at 11:29 +0100, Arjan van de Ven wrote:
> On Tue, 2005-12-13 at 16:10 +0000, Alan Cox wrote:
> > On Maw, 2005-12-13 at 15:39 +0000, David Howells wrote:
> > > (3) Some people want mutexes to be:
> > >
> > > (a) only releasable in the same context as they were taken
> > >
> > > (b) not accessible in interrupt context, or that (a) applies here also
> > >
> > > (c) not initialisable to the locked state
> > >
> > > But this means that the current usages all have to be carefully audited,
> > > and sometimes that unobvious.
> >
> > Only if you insist on replacing them immediately. If you submit a
> > *small* patch which just adds the new mutexes then a series of small
> > patches can gradually convert code where mutexes are better.
>
> this unfortunately is not very realistic in practice...

to expand on this; this kind of change no matter what needs a mass
change inside the kernel, or the point of it all is sort of moot. The
idea is to make the mutex type the most common one, since most users ARE
mutexes. To make that happen a one time "rather big" change is needed
and planned afaics.

What's remaining is
1) transition period for in kernel stuff
2) out of the kernel code compatibility
3) should a forgotten item be a compile time failure or be allowed to
work still

1) is a matter of "do we do it all now" or in phases. I don't see a
reason to not do it all now, otherwise a 2 year process will happen

2) that is a semi moot issue; sure a big bang change will break this
compatibility, but so will a gradual switchover. A gradual switchover of
converting core semaphores into mutexes will need changes in external
modules regardless (think vfs but there's many more). The question is
doing it once or doing it multiple times over a period of 2 years.

3) history has shown that non-compiletime items keep lingering on
forever, since there is no incentive or even detection of "old" use. At
minimum a compiler warning is needed. Just look at the sleep_on_*() api;
more than half the users in 2.6 are *new code* in 2.6, even though it's
a deprecated api for ... how long?

Arjan van de Ven

unread,
Dec 14, 2005, 6:10:15 AM12/14/05
to
On Wed, 2005-12-14 at 11:03 +0000, Alan Cox wrote:

> On Mer, 2005-12-14 at 11:29 +0100, Arjan van de Ven wrote:
> > > > But this means that the current usages all have to be carefully audited,
> > > > and sometimes that unobvious.
> > >
> > > Only if you insist on replacing them immediately. If you submit a
> > > *small* patch which just adds the new mutexes then a series of small
> > > patches can gradually convert code where mutexes are better.
> >
> > this unfortunately is not very realistic in practice...
>
> Strange because it is how most such work has been done in the past, from
> the big kernel lock to the scsi core rewrite.

1) the BKL change hasn't finished, and we're 5 years down the line. API
changes done gradual tend to take forever in practice, esp if there's no
"compile" incentive for people to fix things.

2) the scsi rewrite was a major functional change. that's different from
a basically pure API change (split). Splitting functional changes to one
part of the kernel up into a sequence is very good. THat's different
though: even in the scsi change, API changes that went outside the scsi
core into the drivers were mostly done in one bang (not all of them, the
ones that weren't ended up being rather painful)


> You also forgot to attach
> a reason you think it isnt realistic ?
>
that was in a follow up email

David Howells

unread,
Dec 14, 2005, 6:10:15 AM12/14/05
to
Paul Jackson <p...@sgi.com> wrote:

> The sed/perl script to make the textual change should be practical.
> Indeed, I would claim that the initial big patch -should- be done
> that way. Keep refining a sed script until manual inspection and
> trial builds of all arch's, allconfig, show that it seems to be right.
> Each time you find an error doing this, don't manually edit the
> kernel source; rather refine the script and try applying it again.

Actually, you may have a point.

If the order of patches is:

(1) Create new mutex as struct mutex/up_mutex/down_mutex, say.

(2) Make counting semaphore implementation struct semaphore/up_sem/down_sem.

(3) Convert uses of semaphores that should be completions into completions.

(4) Convert uses of semaphores that should be counting semaphores to use
up_sem/down_sem.

(5) Mass convert by script all the remaining ups and downs into up_mutex and
down_mutex.

(6) Make wrappers for up/down that map to counting semaphores with the
deprecation attribute set.

That might work, and would be a lot easier; except for the humongous patch
generated at step 5 - which could be regenerated by script. I think I can make
a simple perl script to do that.

Note that I am assuming above that down == down/down_trylock/down_interruptible
for clarity.

David

It is loading more messages.
0 new messages