Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 31799
b: refs/heads/master
c: 8a25d5d
h: refs/heads/master
i:
  31797: eb0ba63
  31795: 8751afd
  31791: d850f5c
v: v3
  • Loading branch information
Ingo Molnar authored and Linus Torvalds committed Jul 3, 2006
1 parent 4727352 commit 63b299b
Show file tree
Hide file tree
Showing 14 changed files with 218 additions and 35 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4ea2176dfa714882e88180b474e4cbcd888b70af
refs/heads/master: 8a25d5debff2daee280e83e09d8c25d67c26a972
7 changes: 7 additions & 0 deletions trunk/include/asm-i386/spinlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,20 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
"=m" (lock->slock) : : "memory");
}

/*
* It is easier for the lock validator if interrupts are not re-enabled
* in the middle of a lock-acquire. This is a performance feature anyway
* so we turn it off:
*/
#ifndef CONFIG_PROVE_LOCKING
static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags)
{
alternative_smp(
__raw_spin_lock_string_flags,
__raw_spin_lock_string_up,
"=m" (lock->slock) : "r" (flags) : "memory");
}
#endif

static inline int __raw_spin_trylock(raw_spinlock_t *lock)
{
Expand Down
63 changes: 46 additions & 17 deletions trunk/include/linux/spinlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,40 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock);
/*
* Pull the __raw*() functions/declarations (UP-nondebug doesnt need them):
*/
#if defined(CONFIG_SMP)
#ifdef CONFIG_SMP
# include <asm/spinlock.h>
#else
# include <linux/spinlock_up.h>
#endif

#define spin_lock_init(lock) do { *(lock) = SPIN_LOCK_UNLOCKED; } while (0)
#define rwlock_init(lock) do { *(lock) = RW_LOCK_UNLOCKED; } while (0)
#ifdef CONFIG_DEBUG_SPINLOCK
extern void __spin_lock_init(spinlock_t *lock, const char *name,
struct lock_class_key *key);
# define spin_lock_init(lock) \
do { \
static struct lock_class_key __key; \
\
__spin_lock_init((lock), #lock, &__key); \
} while (0)

#else
# define spin_lock_init(lock) \
do { *(lock) = SPIN_LOCK_UNLOCKED; } while (0)
#endif

#ifdef CONFIG_DEBUG_SPINLOCK
extern void __rwlock_init(rwlock_t *lock, const char *name,
struct lock_class_key *key);
# define rwlock_init(lock) \
do { \
static struct lock_class_key __key; \
\
__rwlock_init((lock), #lock, &__key); \
} while (0)
#else
# define rwlock_init(lock) \
do { *(lock) = RW_LOCK_UNLOCKED; } while (0)
#endif

#define spin_is_locked(lock) __raw_spin_is_locked(&(lock)->raw_lock)

Expand All @@ -113,25 +139,24 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock);
#define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock)
extern int _raw_spin_trylock(spinlock_t *lock);
extern void _raw_spin_unlock(spinlock_t *lock);

extern void _raw_read_lock(rwlock_t *lock);
extern int _raw_read_trylock(rwlock_t *lock);
extern void _raw_read_unlock(rwlock_t *lock);
extern void _raw_write_lock(rwlock_t *lock);
extern int _raw_write_trylock(rwlock_t *lock);
extern void _raw_write_unlock(rwlock_t *lock);
#else
# define _raw_spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock)
# define _raw_spin_trylock(lock) __raw_spin_trylock(&(lock)->raw_lock)
# define _raw_spin_lock(lock) __raw_spin_lock(&(lock)->raw_lock)
# define _raw_spin_lock_flags(lock, flags) \
__raw_spin_lock_flags(&(lock)->raw_lock, *(flags))
# define _raw_spin_trylock(lock) __raw_spin_trylock(&(lock)->raw_lock)
# define _raw_spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock)
# define _raw_read_lock(rwlock) __raw_read_lock(&(rwlock)->raw_lock)
# define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock)
# define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock)
# define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock)
# define _raw_read_trylock(rwlock) __raw_read_trylock(&(rwlock)->raw_lock)
# define _raw_read_unlock(rwlock) __raw_read_unlock(&(rwlock)->raw_lock)
# define _raw_write_lock(rwlock) __raw_write_lock(&(rwlock)->raw_lock)
# define _raw_write_trylock(rwlock) __raw_write_trylock(&(rwlock)->raw_lock)
# define _raw_write_unlock(rwlock) __raw_write_unlock(&(rwlock)->raw_lock)
#endif

#define read_can_lock(rwlock) __raw_read_can_lock(&(rwlock)->raw_lock)
Expand All @@ -147,6 +172,13 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock);
#define write_trylock(lock) __cond_lock(_write_trylock(lock))

#define spin_lock(lock) _spin_lock(lock)

#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define spin_lock_nested(lock, subclass) _spin_lock_nested(lock, subclass)
#else
# define spin_lock_nested(lock, subclass) _spin_lock(lock)
#endif

#define write_lock(lock) _write_lock(lock)
#define read_lock(lock) _read_lock(lock)

Expand All @@ -172,21 +204,18 @@ extern int __lockfunc generic__raw_read_trylock(raw_rwlock_t *lock);
/*
* We inline the unlock functions in the nondebug case:
*/
#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP)
#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || \
!defined(CONFIG_SMP)
# define spin_unlock(lock) _spin_unlock(lock)
# define read_unlock(lock) _read_unlock(lock)
# define write_unlock(lock) _write_unlock(lock)
#else
# define spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock)
# define read_unlock(lock) __raw_read_unlock(&(lock)->raw_lock)
# define write_unlock(lock) __raw_write_unlock(&(lock)->raw_lock)
#endif

#if defined(CONFIG_DEBUG_SPINLOCK) || defined(CONFIG_PREEMPT) || !defined(CONFIG_SMP)
# define spin_unlock_irq(lock) _spin_unlock_irq(lock)
# define read_unlock_irq(lock) _read_unlock_irq(lock)
# define write_unlock_irq(lock) _write_unlock_irq(lock)
#else
# define spin_unlock(lock) __raw_spin_unlock(&(lock)->raw_lock)
# define read_unlock(lock) __raw_read_unlock(&(lock)->raw_lock)
# define write_unlock(lock) __raw_write_unlock(&(lock)->raw_lock)
# define spin_unlock_irq(lock) \
do { __raw_spin_unlock(&(lock)->raw_lock); local_irq_enable(); } while (0)
# define read_unlock_irq(lock) \
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/spinlock_api_smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ int in_lock_functions(unsigned long addr);
#define assert_spin_locked(x) BUG_ON(!spin_is_locked(x))

void __lockfunc _spin_lock(spinlock_t *lock) __acquires(spinlock_t);
void __lockfunc _spin_lock_nested(spinlock_t *lock, int subclass)
__acquires(spinlock_t);
void __lockfunc _read_lock(rwlock_t *lock) __acquires(rwlock_t);
void __lockfunc _write_lock(rwlock_t *lock) __acquires(rwlock_t);
void __lockfunc _spin_lock_bh(spinlock_t *lock) __acquires(spinlock_t);
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/spinlock_api_up.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
do { local_irq_restore(flags); __UNLOCK(lock); } while (0)

#define _spin_lock(lock) __LOCK(lock)
#define _spin_lock_nested(lock, subclass) __LOCK(lock)
#define _read_lock(lock) __LOCK(lock)
#define _write_lock(lock) __LOCK(lock)
#define _spin_lock_bh(lock) __LOCK_BH(lock)
Expand Down
32 changes: 28 additions & 4 deletions trunk/include/linux/spinlock_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* Released under the General Public License (GPL).
*/

#include <linux/lockdep.h>

#if defined(CONFIG_SMP)
# include <asm/spinlock_types.h>
#else
Expand All @@ -24,6 +26,9 @@ typedef struct {
unsigned int magic, owner_cpu;
void *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
} spinlock_t;

#define SPINLOCK_MAGIC 0xdead4ead
Expand All @@ -37,28 +42,47 @@ typedef struct {
unsigned int magic, owner_cpu;
void *owner;
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
} rwlock_t;

#define RWLOCK_MAGIC 0xdeaf1eed

#define SPINLOCK_OWNER_INIT ((void *)-1L)

#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define SPIN_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname }
#else
# define SPIN_DEP_MAP_INIT(lockname)
#endif

#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname }
#else
# define RW_DEP_MAP_INIT(lockname)
#endif

#ifdef CONFIG_DEBUG_SPINLOCK
# define __SPIN_LOCK_UNLOCKED(lockname) \
(spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \
.magic = SPINLOCK_MAGIC, \
.owner = SPINLOCK_OWNER_INIT, \
.owner_cpu = -1 }
.owner_cpu = -1, \
SPIN_DEP_MAP_INIT(lockname) }
#define __RW_LOCK_UNLOCKED(lockname) \
(rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \
.magic = RWLOCK_MAGIC, \
.owner = SPINLOCK_OWNER_INIT, \
.owner_cpu = -1 }
.owner_cpu = -1, \
RW_DEP_MAP_INIT(lockname) }
#else
# define __SPIN_LOCK_UNLOCKED(lockname) \
(spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED }
(spinlock_t) { .raw_lock = __RAW_SPIN_LOCK_UNLOCKED, \
SPIN_DEP_MAP_INIT(lockname) }
#define __RW_LOCK_UNLOCKED(lockname) \
(rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED }
(rwlock_t) { .raw_lock = __RAW_RW_LOCK_UNLOCKED, \
RW_DEP_MAP_INIT(lockname) }
#endif

#define SPIN_LOCK_UNLOCKED __SPIN_LOCK_UNLOCKED(old_style_spin_init)
Expand Down
9 changes: 8 additions & 1 deletion trunk/include/linux/spinlock_types_up.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@
* Released under the General Public License (GPL).
*/

#ifdef CONFIG_DEBUG_SPINLOCK
#if defined(CONFIG_DEBUG_SPINLOCK) || \
defined(CONFIG_DEBUG_LOCK_ALLOC)

typedef struct {
volatile unsigned int slock;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
} raw_spinlock_t;

#define __RAW_SPIN_LOCK_UNLOCKED { 1 }
Expand All @@ -30,6 +34,9 @@ typedef struct { } raw_spinlock_t;

typedef struct {
/* no debug version on UP */
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif
} raw_rwlock_t;

#define __RAW_RW_LOCK_UNLOCKED { }
Expand Down
1 change: 0 additions & 1 deletion trunk/include/linux/spinlock_up.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
*/

#ifdef CONFIG_DEBUG_SPINLOCK

#define __raw_spin_is_locked(x) ((x)->slock == 0)

static inline void __raw_spin_lock(raw_spinlock_t *lock)
Expand Down
1 change: 1 addition & 0 deletions trunk/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o
obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
obj-$(CONFIG_SMP) += cpu.o spinlock.o
obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
obj-$(CONFIG_UID16) += uid16.o
obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
Expand Down
10 changes: 10 additions & 0 deletions trunk/kernel/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,13 @@ static inline void finish_lock_switch(runqueue_t *rq, task_t *prev)
/* this is a valid case when another task releases the spinlock */
rq->lock.owner = current;
#endif
/*
* If we are tracking spinlock dependencies then we have to
* fix up the runqueue lock - which gets 'carried over' from
* prev into current:
*/
spin_acquire(&rq->lock.dep_map, 0, 0, _THIS_IP_);

spin_unlock_irq(&rq->lock);
}

Expand Down Expand Up @@ -1778,6 +1785,7 @@ task_t * context_switch(runqueue_t *rq, task_t *prev, task_t *next)
WARN_ON(rq->prev_mm);
rq->prev_mm = oldmm;
}
spin_release(&rq->lock.dep_map, 1, _THIS_IP_);

/* Here we just switch the register state and the stack. */
switch_to(prev, next, prev);
Expand Down Expand Up @@ -4384,6 +4392,7 @@ asmlinkage long sys_sched_yield(void)
* no need to preempt or enable interrupts:
*/
__release(rq->lock);
spin_release(&rq->lock.dep_map, 1, _THIS_IP_);
_raw_spin_unlock(&rq->lock);
preempt_enable_no_resched();

Expand Down Expand Up @@ -4447,6 +4456,7 @@ int cond_resched_lock(spinlock_t *lock)
spin_lock(lock);
}
if (need_resched() && __resched_legal()) {
spin_release(&lock->dep_map, 1, _THIS_IP_);
_raw_spin_unlock(lock);
preempt_enable_no_resched();
__cond_resched();
Expand Down
Loading

0 comments on commit 63b299b

Please sign in to comment.