Skip to content

Commit

Permalink
locking, rwsem: Annotate inner lock as raw
Browse files Browse the repository at this point in the history
There is no reason to allow the lock protecting rwsems (the
ownerless variant) to be preemptible on -rt. Convert it to raw.

In mainline this change documents the low level nature of
the lock - otherwise there's no functional difference. Lockdep
and Sparse checking will work as usual.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Thomas Gleixner authored and Ingo Molnar committed Sep 13, 2011
1 parent 8292c9e commit ddb6c9b
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 31 deletions.
2 changes: 1 addition & 1 deletion include/linux/rwsem-spinlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
*/
struct rw_semaphore {
__s32 activity;
spinlock_t wait_lock;
raw_spinlock_t wait_lock;
struct list_head wait_list;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
Expand Down
10 changes: 6 additions & 4 deletions include/linux/rwsem.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct rw_semaphore;
/* All arch specific implementations share the same struct */
struct rw_semaphore {
long count;
spinlock_t wait_lock;
raw_spinlock_t wait_lock;
struct list_head wait_list;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
Expand Down Expand Up @@ -56,9 +56,11 @@ static inline int rwsem_is_locked(struct rw_semaphore *sem)
# define __RWSEM_DEP_MAP_INIT(lockname)
#endif

#define __RWSEM_INITIALIZER(name) \
{ RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED(name.wait_lock), \
LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) }
#define __RWSEM_INITIALIZER(name) \
{ RWSEM_UNLOCKED_VALUE, \
__RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \
LIST_HEAD_INIT((name).wait_list) \
__RWSEM_DEP_MAP_INIT(name) }

#define DECLARE_RWSEM(name) \
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
Expand Down
38 changes: 19 additions & 19 deletions lib/rwsem-spinlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ int rwsem_is_locked(struct rw_semaphore *sem)
int ret = 1;
unsigned long flags;

if (spin_trylock_irqsave(&sem->wait_lock, flags)) {
if (raw_spin_trylock_irqsave(&sem->wait_lock, flags)) {
ret = (sem->activity != 0);
spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
}
return ret;
}
Expand All @@ -44,7 +44,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name,
lockdep_init_map(&sem->dep_map, name, key, 0);
#endif
sem->activity = 0;
spin_lock_init(&sem->wait_lock);
raw_spin_lock_init(&sem->wait_lock);
INIT_LIST_HEAD(&sem->wait_list);
}
EXPORT_SYMBOL(__init_rwsem);
Expand Down Expand Up @@ -145,12 +145,12 @@ void __sched __down_read(struct rw_semaphore *sem)
struct task_struct *tsk;
unsigned long flags;

spin_lock_irqsave(&sem->wait_lock, flags);
raw_spin_lock_irqsave(&sem->wait_lock, flags);

if (sem->activity >= 0 && list_empty(&sem->wait_list)) {
/* granted */
sem->activity++;
spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
goto out;
}

Expand All @@ -165,7 +165,7 @@ void __sched __down_read(struct rw_semaphore *sem)
list_add_tail(&waiter.list, &sem->wait_list);

/* we don't need to touch the semaphore struct anymore */
spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);

/* wait to be given the lock */
for (;;) {
Expand All @@ -189,15 +189,15 @@ int __down_read_trylock(struct rw_semaphore *sem)
int ret = 0;


spin_lock_irqsave(&sem->wait_lock, flags);
raw_spin_lock_irqsave(&sem->wait_lock, flags);

if (sem->activity >= 0 && list_empty(&sem->wait_list)) {
/* granted */
sem->activity++;
ret = 1;
}

spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);

return ret;
}
Expand All @@ -212,12 +212,12 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)
struct task_struct *tsk;
unsigned long flags;

spin_lock_irqsave(&sem->wait_lock, flags);
raw_spin_lock_irqsave(&sem->wait_lock, flags);

if (sem->activity == 0 && list_empty(&sem->wait_list)) {
/* granted */
sem->activity = -1;
spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
goto out;
}

Expand All @@ -232,7 +232,7 @@ void __sched __down_write_nested(struct rw_semaphore *sem, int subclass)
list_add_tail(&waiter.list, &sem->wait_list);

/* we don't need to touch the semaphore struct anymore */
spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);

/* wait to be given the lock */
for (;;) {
Expand Down Expand Up @@ -260,15 +260,15 @@ int __down_write_trylock(struct rw_semaphore *sem)
unsigned long flags;
int ret = 0;

spin_lock_irqsave(&sem->wait_lock, flags);
raw_spin_lock_irqsave(&sem->wait_lock, flags);

if (sem->activity == 0 && list_empty(&sem->wait_list)) {
/* granted */
sem->activity = -1;
ret = 1;
}

spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);

return ret;
}
Expand All @@ -280,12 +280,12 @@ void __up_read(struct rw_semaphore *sem)
{
unsigned long flags;

spin_lock_irqsave(&sem->wait_lock, flags);
raw_spin_lock_irqsave(&sem->wait_lock, flags);

if (--sem->activity == 0 && !list_empty(&sem->wait_list))
sem = __rwsem_wake_one_writer(sem);

spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
}

/*
Expand All @@ -295,13 +295,13 @@ void __up_write(struct rw_semaphore *sem)
{
unsigned long flags;

spin_lock_irqsave(&sem->wait_lock, flags);
raw_spin_lock_irqsave(&sem->wait_lock, flags);

sem->activity = 0;
if (!list_empty(&sem->wait_list))
sem = __rwsem_do_wake(sem, 1);

spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
}

/*
Expand All @@ -312,12 +312,12 @@ void __downgrade_write(struct rw_semaphore *sem)
{
unsigned long flags;

spin_lock_irqsave(&sem->wait_lock, flags);
raw_spin_lock_irqsave(&sem->wait_lock, flags);

sem->activity = 1;
if (!list_empty(&sem->wait_list))
sem = __rwsem_do_wake(sem, 0);

spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);
}

14 changes: 7 additions & 7 deletions lib/rwsem.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name,
lockdep_init_map(&sem->dep_map, name, key, 0);
#endif
sem->count = RWSEM_UNLOCKED_VALUE;
spin_lock_init(&sem->wait_lock);
raw_spin_lock_init(&sem->wait_lock);
INIT_LIST_HEAD(&sem->wait_list);
}

Expand Down Expand Up @@ -180,7 +180,7 @@ rwsem_down_failed_common(struct rw_semaphore *sem,
set_task_state(tsk, TASK_UNINTERRUPTIBLE);

/* set up my own style of waitqueue */
spin_lock_irq(&sem->wait_lock);
raw_spin_lock_irq(&sem->wait_lock);
waiter.task = tsk;
waiter.flags = flags;
get_task_struct(tsk);
Expand All @@ -204,7 +204,7 @@ rwsem_down_failed_common(struct rw_semaphore *sem,
adjustment == -RWSEM_ACTIVE_WRITE_BIAS)
sem = __rwsem_do_wake(sem, RWSEM_WAKE_READ_OWNED);

spin_unlock_irq(&sem->wait_lock);
raw_spin_unlock_irq(&sem->wait_lock);

/* wait to be given the lock */
for (;;) {
Expand Down Expand Up @@ -245,13 +245,13 @@ struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem)
{
unsigned long flags;

spin_lock_irqsave(&sem->wait_lock, flags);
raw_spin_lock_irqsave(&sem->wait_lock, flags);

/* do nothing if list empty */
if (!list_empty(&sem->wait_list))
sem = __rwsem_do_wake(sem, RWSEM_WAKE_ANY);

spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);

return sem;
}
Expand All @@ -265,13 +265,13 @@ struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem)
{
unsigned long flags;

spin_lock_irqsave(&sem->wait_lock, flags);
raw_spin_lock_irqsave(&sem->wait_lock, flags);

/* do nothing if list empty */
if (!list_empty(&sem->wait_list))
sem = __rwsem_do_wake(sem, RWSEM_WAKE_READ_OWNED);

spin_unlock_irqrestore(&sem->wait_lock, flags);
raw_spin_unlock_irqrestore(&sem->wait_lock, flags);

return sem;
}
Expand Down

0 comments on commit ddb6c9b

Please sign in to comment.