Skip to content

Commit

Permalink
Merge branch 'core-locking-for-linus' of git://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/linux/kernel/git/tip/tip

Pull core locking changes from Ingo Molnar:
 "The biggest change is the rwsem lock-steal improvements, both to the
  assembly optimized and the spinlock based variants.

  The other notable change is the clean up of the seqlock implementation
  to be based on the seqcount infrastructure.

  The rest is assorted smaller debuggability, cleanup and continued -rt
  locking changes."

* 'core-locking-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  rwsem-spinlock: Implement writer lock-stealing for better scalability
  futex: Revert "futex: Mark get_robust_list as deprecated"
  generic: Use raw local irq variant for generic cmpxchg
  lockdep: Selftest: convert spinlock to raw spinlock
  seqlock: Use seqcount infrastructure
  seqlock: Remove unused functions
  ntp: Make ntp_lock raw
  intel_idle: Convert i7300_idle_lock to raw_spinlock
  locking: Various static lock initializer fixes
  lockdep: Print more info when MAX_LOCK_DEPTH is exceeded
  rwsem: Implement writer lock-stealing for better scalability
  lockdep: Silence warning if CONFIG_LOCKDEP isn't set
  watchdog: Use local_clock for get_timestamp()
  lockdep: Rename print_unlock_inbalance_bug() to print_unlock_imbalance_bug()
  locking/stat: Fix a typo
  • Loading branch information
torvalds committed Feb 23, 2013
2 parents c47f39e + 41ef8f8 commit 3b5d851
Show file tree
Hide file tree
Showing 17 changed files with 221 additions and 237 deletions.
2 changes: 1 addition & 1 deletion Documentation/lockstat.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ that had to wait on lock acquisition.

- CONFIGURATION

Lock statistics are enabled via CONFIG_LOCK_STATS.
Lock statistics are enabled via CONFIG_LOCK_STAT.

- USAGE

Expand Down
6 changes: 3 additions & 3 deletions drivers/char/random.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ static struct entropy_store input_pool = {
.poolinfo = &poolinfo_table[0],
.name = "input",
.limit = 1,
.lock = __SPIN_LOCK_UNLOCKED(&input_pool.lock),
.lock = __SPIN_LOCK_UNLOCKED(input_pool.lock),
.pool = input_pool_data
};

Expand All @@ -454,15 +454,15 @@ static struct entropy_store blocking_pool = {
.name = "blocking",
.limit = 1,
.pull = &input_pool,
.lock = __SPIN_LOCK_UNLOCKED(&blocking_pool.lock),
.lock = __SPIN_LOCK_UNLOCKED(blocking_pool.lock),
.pool = blocking_pool_data
};

static struct entropy_store nonblocking_pool = {
.poolinfo = &poolinfo_table[1],
.name = "nonblocking",
.pull = &input_pool,
.lock = __SPIN_LOCK_UNLOCKED(&nonblocking_pool.lock),
.lock = __SPIN_LOCK_UNLOCKED(nonblocking_pool.lock),
.pool = nonblocking_pool_data
};

Expand Down
8 changes: 4 additions & 4 deletions drivers/idle/i7300_idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static unsigned long past_skip;

static struct pci_dev *fbd_dev;

static spinlock_t i7300_idle_lock;
static raw_spinlock_t i7300_idle_lock;
static int i7300_idle_active;

static u8 i7300_idle_thrtctl_saved;
Expand Down Expand Up @@ -457,7 +457,7 @@ static int i7300_idle_notifier(struct notifier_block *nb, unsigned long val,
idle_begin_time = ktime_get();
}

spin_lock_irqsave(&i7300_idle_lock, flags);
raw_spin_lock_irqsave(&i7300_idle_lock, flags);
if (val == IDLE_START) {

cpumask_set_cpu(smp_processor_id(), idle_cpumask);
Expand Down Expand Up @@ -506,7 +506,7 @@ static int i7300_idle_notifier(struct notifier_block *nb, unsigned long val,
}
}
end:
spin_unlock_irqrestore(&i7300_idle_lock, flags);
raw_spin_unlock_irqrestore(&i7300_idle_lock, flags);
return 0;
}

Expand Down Expand Up @@ -548,7 +548,7 @@ struct debugfs_file_info {

static int __init i7300_idle_init(void)
{
spin_lock_init(&i7300_idle_lock);
raw_spin_lock_init(&i7300_idle_lock);
total_us = 0;

if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev, forceload))
Expand Down
2 changes: 1 addition & 1 deletion drivers/usb/chipidea/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ static struct {
} dbg_data = {
.idx = 0,
.tty = 0,
.lck = __RW_LOCK_UNLOCKED(lck)
.lck = __RW_LOCK_UNLOCKED(dbg_data.lck)
};

/**
Expand Down
2 changes: 1 addition & 1 deletion fs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ struct files_struct init_files = {
.close_on_exec = init_files.close_on_exec_init,
.open_fds = init_files.open_fds_init,
},
.file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock),
.file_lock = __SPIN_LOCK_UNLOCKED(init_files.file_lock),
};

/*
Expand Down
8 changes: 4 additions & 4 deletions include/asm-generic/cmpxchg-local.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static inline unsigned long __cmpxchg_local_generic(volatile void *ptr,
if (size == 8 && sizeof(unsigned long) != 8)
wrong_size_cmpxchg(ptr);

local_irq_save(flags);
raw_local_irq_save(flags);
switch (size) {
case 1: prev = *(u8 *)ptr;
if (prev == old)
Expand All @@ -42,7 +42,7 @@ static inline unsigned long __cmpxchg_local_generic(volatile void *ptr,
default:
wrong_size_cmpxchg(ptr);
}
local_irq_restore(flags);
raw_local_irq_restore(flags);
return prev;
}

Expand All @@ -55,11 +55,11 @@ static inline u64 __cmpxchg64_local_generic(volatile void *ptr,
u64 prev;
unsigned long flags;

local_irq_save(flags);
raw_local_irq_save(flags);
prev = *(u64 *)ptr;
if (prev == old)
*(u64 *)ptr = new;
local_irq_restore(flags);
raw_local_irq_restore(flags);
return prev;
}

Expand Down
2 changes: 1 addition & 1 deletion include/linux/idr.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ struct ida {
struct ida_bitmap *free_bitmap;
};

#define IDA_INIT(name) { .idr = IDR_INIT(name), .free_bitmap = NULL, }
#define IDA_INIT(name) { .idr = IDR_INIT((name).idr), .free_bitmap = NULL, }
#define DEFINE_IDA(name) struct ida name = IDA_INIT(name)

int ida_pre_get(struct ida *ida, gfp_t gfp_mask);
Expand Down
2 changes: 1 addition & 1 deletion include/linux/lockdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ struct lock_class_key { };

#define lockdep_depth(tsk) (0)

#define lockdep_assert_held(l) do { } while (0)
#define lockdep_assert_held(l) do { (void)(l); } while (0)

#define lockdep_recursing(tsk) (0)

Expand Down
193 changes: 91 additions & 102 deletions include/linux/seqlock.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,92 +30,12 @@
#include <linux/preempt.h>
#include <asm/processor.h>

typedef struct {
unsigned sequence;
spinlock_t lock;
} seqlock_t;

/*
* These macros triggered gcc-3.x compile-time problems. We think these are
* OK now. Be cautious.
*/
#define __SEQLOCK_UNLOCKED(lockname) \
{ 0, __SPIN_LOCK_UNLOCKED(lockname) }

#define seqlock_init(x) \
do { \
(x)->sequence = 0; \
spin_lock_init(&(x)->lock); \
} while (0)

#define DEFINE_SEQLOCK(x) \
seqlock_t x = __SEQLOCK_UNLOCKED(x)

/* Lock out other writers and update the count.
* Acts like a normal spin_lock/unlock.
* Don't need preempt_disable() because that is in the spin_lock already.
*/
static inline void write_seqlock(seqlock_t *sl)
{
spin_lock(&sl->lock);
++sl->sequence;
smp_wmb();
}

static inline void write_sequnlock(seqlock_t *sl)
{
smp_wmb();
sl->sequence++;
spin_unlock(&sl->lock);
}

static inline int write_tryseqlock(seqlock_t *sl)
{
int ret = spin_trylock(&sl->lock);

if (ret) {
++sl->sequence;
smp_wmb();
}
return ret;
}

/* Start of read calculation -- fetch last complete writer token */
static __always_inline unsigned read_seqbegin(const seqlock_t *sl)
{
unsigned ret;

repeat:
ret = ACCESS_ONCE(sl->sequence);
if (unlikely(ret & 1)) {
cpu_relax();
goto repeat;
}
smp_rmb();

return ret;
}

/*
* Test if reader processed invalid data.
*
* If sequence value changed then writer changed data while in section.
*/
static __always_inline int read_seqretry(const seqlock_t *sl, unsigned start)
{
smp_rmb();

return unlikely(sl->sequence != start);
}


/*
* Version using sequence counter only.
* This can be used when code has its own mutex protecting the
* updating starting before the write_seqcountbeqin() and ending
* after the write_seqcount_end().
*/

typedef struct seqcount {
unsigned sequence;
} seqcount_t;
Expand Down Expand Up @@ -218,7 +138,6 @@ static inline int __read_seqcount_retry(const seqcount_t *s, unsigned start)
static inline int read_seqcount_retry(const seqcount_t *s, unsigned start)
{
smp_rmb();

return __read_seqcount_retry(s, start);
}

Expand Down Expand Up @@ -252,31 +171,101 @@ static inline void write_seqcount_barrier(seqcount_t *s)
s->sequence+=2;
}

typedef struct {
struct seqcount seqcount;
spinlock_t lock;
} seqlock_t;

/*
* Possible sw/hw IRQ protected versions of the interfaces.
* These macros triggered gcc-3.x compile-time problems. We think these are
* OK now. Be cautious.
*/
#define write_seqlock_irqsave(lock, flags) \
do { local_irq_save(flags); write_seqlock(lock); } while (0)
#define write_seqlock_irq(lock) \
do { local_irq_disable(); write_seqlock(lock); } while (0)
#define write_seqlock_bh(lock) \
do { local_bh_disable(); write_seqlock(lock); } while (0)
#define __SEQLOCK_UNLOCKED(lockname) \
{ \
.seqcount = SEQCNT_ZERO, \
.lock = __SPIN_LOCK_UNLOCKED(lockname) \
}

#define seqlock_init(x) \
do { \
seqcount_init(&(x)->seqcount); \
spin_lock_init(&(x)->lock); \
} while (0)

#define write_sequnlock_irqrestore(lock, flags) \
do { write_sequnlock(lock); local_irq_restore(flags); } while(0)
#define write_sequnlock_irq(lock) \
do { write_sequnlock(lock); local_irq_enable(); } while(0)
#define write_sequnlock_bh(lock) \
do { write_sequnlock(lock); local_bh_enable(); } while(0)
#define DEFINE_SEQLOCK(x) \
seqlock_t x = __SEQLOCK_UNLOCKED(x)

#define read_seqbegin_irqsave(lock, flags) \
({ local_irq_save(flags); read_seqbegin(lock); })
/*
* Read side functions for starting and finalizing a read side section.
*/
static inline unsigned read_seqbegin(const seqlock_t *sl)
{
return read_seqcount_begin(&sl->seqcount);
}

#define read_seqretry_irqrestore(lock, iv, flags) \
({ \
int ret = read_seqretry(lock, iv); \
local_irq_restore(flags); \
ret; \
})
static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start)
{
return read_seqcount_retry(&sl->seqcount, start);
}

/*
* Lock out other writers and update the count.
* Acts like a normal spin_lock/unlock.
* Don't need preempt_disable() because that is in the spin_lock already.
*/
static inline void write_seqlock(seqlock_t *sl)
{
spin_lock(&sl->lock);
write_seqcount_begin(&sl->seqcount);
}

static inline void write_sequnlock(seqlock_t *sl)
{
write_seqcount_end(&sl->seqcount);
spin_unlock(&sl->lock);
}

static inline void write_seqlock_bh(seqlock_t *sl)
{
spin_lock_bh(&sl->lock);
write_seqcount_begin(&sl->seqcount);
}

static inline void write_sequnlock_bh(seqlock_t *sl)
{
write_seqcount_end(&sl->seqcount);
spin_unlock_bh(&sl->lock);
}

static inline void write_seqlock_irq(seqlock_t *sl)
{
spin_lock_irq(&sl->lock);
write_seqcount_begin(&sl->seqcount);
}

static inline void write_sequnlock_irq(seqlock_t *sl)
{
write_seqcount_end(&sl->seqcount);
spin_unlock_irq(&sl->lock);
}

static inline unsigned long __write_seqlock_irqsave(seqlock_t *sl)
{
unsigned long flags;

spin_lock_irqsave(&sl->lock, flags);
write_seqcount_begin(&sl->seqcount);
return flags;
}

#define write_seqlock_irqsave(lock, flags) \
do { flags = __write_seqlock_irqsave(lock); } while (0)

static inline void
write_sequnlock_irqrestore(seqlock_t *sl, unsigned long flags)
{
write_seqcount_end(&sl->seqcount);
spin_unlock_irqrestore(&sl->lock, flags);
}

#endif /* __LINUX_SEQLOCK_H */
2 changes: 0 additions & 2 deletions kernel/futex.c
Original file line number Diff line number Diff line change
Expand Up @@ -2472,8 +2472,6 @@ SYSCALL_DEFINE3(get_robust_list, int, pid,
if (!futex_cmpxchg_enabled)
return -ENOSYS;

WARN_ONCE(1, "deprecated: get_robust_list will be deleted in 2013.\n");

rcu_read_lock();

ret = -ESRCH;
Expand Down
2 changes: 0 additions & 2 deletions kernel/futex_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr,
if (!futex_cmpxchg_enabled)
return -ENOSYS;

WARN_ONCE(1, "deprecated: get_robust_list will be deleted in 2013.\n");

rcu_read_lock();

ret = -ESRCH;
Expand Down
Loading

0 comments on commit 3b5d851

Please sign in to comment.