projects/linux·commit 892ad5ac

Merge branch 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

892ad5ac · Linus Torvalds <[email protected]> · 2017-07-03 12:14:18 -07:00

Pull locking updates from Ingo Molnar:
 "The main changes in this cycle were:

   - Add CONFIG_REFCOUNT_FULL=y to allow the disabling of the 'full'
     (robustness checked) refcount_t implementation with slightly lower
     runtime overhead. (Kees Cook)

     The lighter weight variant is the default. The two variants use the
     same API. Having this variant was a precondition by some
     maintainers to merge refcount_t cleanups.

   - Add lockdep support for rtmutexes (Peter Zijlstra)

   - liblockdep fixes and improvements (Sasha Levin, Ben Hutchings)

   - ... misc fixes and improvements"

* 'locking-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (30 commits)
  locking/refcount: Remove the half-implemented refcount_sub() API
  locking/refcount: Create unchecked atomic_t implementation
  locking/rtmutex: Don't initialize lockdep when not required
  locking/selftest: Add RT-mutex support
  locking/selftest: Remove the bad unlock ordering test
  rt_mutex: Add lockdep annotations
  MAINTAINERS: Claim atomic*_t maintainership
  locking/x86: Remove the unused atomic_inc_short() methd
  tools/lib/lockdep: Remove private kernel headers
  tools/lib/lockdep: Hide liblockdep output from test results
  tools/lib/lockdep: Add dummy current_gfp_context()
  tools/include: Add IS_ERR_OR_NULL to err.h
  tools/lib/lockdep: Add empty __is_[module,kernel]_percpu_address
  tools/lib/lockdep: Include err.h
  tools/include: Add (mostly) empty include/linux/sched/mm.h
  tools/lib/lockdep: Use LDFLAGS
  tools/lib/lockdep: Remove double-quotes from soname
  tools/lib/lockdep: Fix object file paths used in an out-of-tree build
  tools/lib/lockdep: Fix compilation for 4.11
  tools/lib/lockdep: Don't mix fd-based and stream IO
  ...
Commit
892ad5acca0b2ddb514fae63fa4686bf726d2471
Parents
162b246e · 5d6dec6f

Merge commit. Changes below are compared with the first parent: 162b246e.

Changes

72 files changed · +641 −234

FileStatusAddDelContent
MAINTAINERSmodified+10−1View file
arch/Kconfigmodified+9−0View file
arch/tile/lib/atomic_asm_32.Smodified+1−2View file
arch/x86/include/asm/atomic.hmodified+0−13View file
include/linux/refcount.hmodified+37−1View file
include/linux/rtmutex.hmodified+21−4View file
kernel/locking/rtmutex-debug.cmodified+5−1View file
kernel/locking/rtmutex-debug.hmodified+1−1View file
kernel/locking/rtmutex.cmodified+30−7View file
kernel/locking/rtmutex.hmodified+1−1View file
lib/Kconfig.debugmodified+3−0View file
lib/locking-selftest-rtmutex.hadded+11−0View file
lib/locking-selftest.cmodified+105−28View file
lib/refcount.cmodified+3−0View file
tools/Makefilemodified+6−2View file
tools/include/asm/sections.hadded+4−0View file
tools/include/linux/bitops.hmodified+10−0View file
tools/include/linux/compiler.hmodified+12−0View file
tools/lib/lockdep/uinclude/linux/debug_locks.h → tools/include/linux/debug_locks.hrenamed+2−1View file
tools/include/linux/delay.hadded+4−0View file
tools/include/linux/err.hmodified+5−0View file
tools/include/linux/ftrace.hadded+4−0View file
tools/include/linux/gfp.hadded+4−0View file
tools/lib/lockdep/uinclude/linux/hardirq.h → tools/include/linux/hardirq.hrenamed+0−0View file
tools/include/linux/interrupt.hadded+4−0View file
tools/lib/lockdep/uinclude/linux/irqflags.h → tools/include/linux/irqflags.hrenamed+4−4View file
tools/include/linux/jhash.hadded+175−0View file
tools/lib/lockdep/uinclude/linux/kallsyms.h → tools/include/linux/kallsyms.hrenamed+2−1View file
tools/lib/lockdep/uinclude/linux/kern_levels.h → tools/include/linux/kern_levels.hrenamed+0−0View file
tools/include/linux/kernel.hmodified+4−0View file
tools/lib/lockdep/uinclude/linux/kmemcheck.h → tools/include/linux/kmemcheck.hrenamed+0−0View file
tools/include/linux/linkage.hadded+4−0View file
tools/lib/lockdep/uinclude/linux/lockdep.h → tools/include/linux/lockdep.hrenamed+21−13View file
tools/lib/lockdep/uinclude/linux/module.h → tools/include/linux/module.hrenamed+5−0View file
tools/include/linux/mutex.hadded+4−0View file
tools/include/linux/proc_fs.hadded+4−0View file
tools/lib/lockdep/uinclude/linux/rcu.h → tools/include/linux/rcu.hrenamed+3−0View file
tools/include/linux/sched/clock.hadded+4−0View file
tools/include/linux/sched/mm.hadded+4−0View file
tools/include/linux/sched/task.hadded+4−0View file
tools/include/linux/seq_file.hadded+4−0View file
tools/include/linux/spinlock.hmodified+26−0View file
tools/lib/lockdep/uinclude/linux/stacktrace.h → tools/include/linux/stacktrace.hrenamed+0−0View file
tools/include/linux/unaligned/packed_struct.hadded+46−0View file
tools/include/trace/events/lock.hadded+4−0View file
tools/lib/lockdep/Makefilemodified+5−4View file
tools/lib/lockdep/lockdep.cmodified+19−0View file
tools/lib/lockdep/preload.cmodified+2−3View file
tools/lib/lockdep/rbtree.cmodified+1−1View file
tools/lib/lockdep/run_tests.shmodified+4−4View file
tools/lib/lockdep/uinclude/asm/hash.hdeleted+0−6View before deletion
tools/lib/lockdep/uinclude/asm/hweight.hdeleted+0−3View before deletion
tools/lib/lockdep/uinclude/asm/sections.hdeleted+0−3View before deletion
tools/lib/lockdep/uinclude/linux/bitops.hdeleted+0−3View before deletion
tools/lib/lockdep/uinclude/linux/compiler.hdeleted+0−10View before deletion
tools/lib/lockdep/uinclude/linux/delay.hdeleted+0−3View before deletion
tools/lib/lockdep/uinclude/linux/ftrace.hdeleted+0−3View before deletion
tools/lib/lockdep/uinclude/linux/gfp.hdeleted+0−3View before deletion
tools/lib/lockdep/uinclude/linux/hash.hdeleted+0−1View before deletion
tools/lib/lockdep/uinclude/linux/interrupt.hdeleted+0−3View before deletion
tools/lib/lockdep/uinclude/linux/kernel.hdeleted+0−47View before deletion
tools/lib/lockdep/uinclude/linux/linkage.hdeleted+0−3View before deletion
tools/lib/lockdep/uinclude/linux/list.hdeleted+0−1View before deletion
tools/lib/lockdep/uinclude/linux/mutex.hdeleted+0−3View before deletion
tools/lib/lockdep/uinclude/linux/poison.hdeleted+0−1View before deletion
tools/lib/lockdep/uinclude/linux/prefetch.hdeleted+0−6View before deletion
tools/lib/lockdep/uinclude/linux/proc_fs.hdeleted+0−3View before deletion
tools/lib/lockdep/uinclude/linux/rbtree_augmented.hdeleted+0−2View before deletion
tools/lib/lockdep/uinclude/linux/seq_file.hdeleted+0−3View before deletion
tools/lib/lockdep/uinclude/linux/spinlock.hdeleted+0−25View before deletion
tools/lib/lockdep/uinclude/linux/stringify.hdeleted+0−7View before deletion
tools/lib/lockdep/uinclude/trace/events/lock.hdeleted+0−3View before deletion

Only the first 600 diff lines are shown. Download the complete patch.

MAINTAINERS

View file
diff --git a/MAINTAINERS b/MAINTAINERS
index 503f80a..d357695 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2322,6 +2322,15 @@ F: Documentation/devicetree/bindings/input/atmel,maxtouch.txt
F: drivers/input/touchscreen/atmel_mxt_ts.c
F: include/linux/platform_data/atmel_mxt_ts.h
+ATOMIC INFRASTRUCTURE
+M: Will Deacon <[email protected]>
+M: Peter Zijlstra <[email protected]>
+R: Boqun Feng <[email protected]>
+S: Maintained
+F: arch/*/include/asm/atomic*.h
+F: include/*/atomic*.h
+
ATTO EXPRESSSAS SAS/SATA RAID SCSI DRIVER
M: Bradley Grove <[email protected]>
@@ -7555,7 +7564,7 @@ S: Maintained
F: drivers/ata/sata_promise.*
LIBLOCKDEP
-M: Sasha Levin <[email protected]>
+M: Sasha Levin <[email protected]>
S: Maintained
F: tools/lib/lockdep/

arch/Kconfig

View file
diff --git a/arch/Kconfig b/arch/Kconfig
index 6c00e5b..f76b214 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -867,4 +867,13 @@ config STRICT_MODULE_RWX
config ARCH_WANT_RELAX_ORDER
bool
+config REFCOUNT_FULL
+ bool "Perform full reference count validation at the expense of speed"
+ help
+ Enabling this switches the refcounting infrastructure from a fast
+ unchecked atomic_t implementation to a fully state checked
+ implementation, which can be (slightly) slower but provides protections
+ against various use-after-free conditions that can be used in
+ security flaw exploits.
+
source "kernel/gcov/Kconfig"

arch/tile/lib/atomic_asm_32.S

View file
diff --git a/arch/tile/lib/atomic_asm_32.S b/arch/tile/lib/atomic_asm_32.S
index 1a70e6c..94709ab 100644
--- a/arch/tile/lib/atomic_asm_32.S
+++ b/arch/tile/lib/atomic_asm_32.S
@@ -24,8 +24,7 @@
* has an opportunity to return -EFAULT to the user if needed.
* The 64-bit routines just return a "long long" with the value,
* since they are only used from kernel space and don't expect to fault.
- * Support for 16-bit ops is included in the framework but we don't provide
- * any (x86_64 has an atomic_inc_short(), so we might want to some day).
+ * Support for 16-bit ops is included in the framework but we don't provide any.
*
* Note that the caller is advised to issue a suitable L1 or L2
* prefetch on the address being manipulated to avoid extra stalls.

arch/x86/include/asm/atomic.h

View file
diff --git a/arch/x86/include/asm/atomic.h b/arch/x86/include/asm/atomic.h
index caa5798..33380b8 100644
--- a/arch/x86/include/asm/atomic.h
+++ b/arch/x86/include/asm/atomic.h
@@ -246,19 +246,6 @@ static __always_inline int __atomic_add_unless(atomic_t *v, int a, int u)
return c;
}
-/**
- * atomic_inc_short - increment of a short integer
- * @v: pointer to type int
- *
- * Atomically adds 1 to @v
- * Returns the new value of @u
- */
-static __always_inline short int atomic_inc_short(short int *v)
-{
- asm(LOCK_PREFIX "addw $1, %0" : "+m" (*v));
- return *v;
-}
-
#ifdef CONFIG_X86_32
# include <asm/atomic64_32.h>
#else

include/linux/refcount.h

View file
diff --git a/include/linux/refcount.h b/include/linux/refcount.h
index b34aa64..591792c 100644
--- a/include/linux/refcount.h
+++ b/include/linux/refcount.h
@@ -41,6 +41,7 @@ static inline unsigned int refcount_read(const refcount_t *r)
return atomic_read(&r->refs);
}
+#ifdef CONFIG_REFCOUNT_FULL
extern __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r);
extern void refcount_add(unsigned int i, refcount_t *r);
@@ -48,10 +49,45 @@ extern __must_check bool refcount_inc_not_zero(refcount_t *r);
extern void refcount_inc(refcount_t *r);
extern __must_check bool refcount_sub_and_test(unsigned int i, refcount_t *r);
-extern void refcount_sub(unsigned int i, refcount_t *r);
extern __must_check bool refcount_dec_and_test(refcount_t *r);
extern void refcount_dec(refcount_t *r);
+#else
+static inline __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r)
+{
+ return atomic_add_unless(&r->refs, i, 0);
+}
+
+static inline void refcount_add(unsigned int i, refcount_t *r)
+{
+ atomic_add(i, &r->refs);
+}
+
+static inline __must_check bool refcount_inc_not_zero(refcount_t *r)
+{
+ return atomic_add_unless(&r->refs, 1, 0);
+}
+
+static inline void refcount_inc(refcount_t *r)
+{
+ atomic_inc(&r->refs);
+}
+
+static inline __must_check bool refcount_sub_and_test(unsigned int i, refcount_t *r)
+{
+ return atomic_sub_and_test(i, &r->refs);
+}
+
+static inline __must_check bool refcount_dec_and_test(refcount_t *r)
+{
+ return atomic_dec_and_test(&r->refs);
+}
+
+static inline void refcount_dec(refcount_t *r)
+{
+ atomic_dec(&r->refs);
+}
+#endif /* CONFIG_REFCOUNT_FULL */
extern __must_check bool refcount_dec_if_one(refcount_t *r);
extern __must_check bool refcount_dec_not_one(refcount_t *r);

include/linux/rtmutex.h

View file
diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h
index 1abba5c..44fd002 100644
--- a/include/linux/rtmutex.h
+++ b/include/linux/rtmutex.h
@@ -37,6 +37,9 @@ struct rt_mutex {
int line;
void *magic;
#endif
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ struct lockdep_map dep_map;
+#endif
};
struct rt_mutex_waiter;
@@ -58,19 +61,33 @@ struct hrtimer_sleeper;
#ifdef CONFIG_DEBUG_RT_MUTEXES
# define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \
, .name = #mutexname, .file = __FILE__, .line = __LINE__
-# define rt_mutex_init(mutex) __rt_mutex_init(mutex, __func__)
+
+# define rt_mutex_init(mutex) \
+do { \
+ static struct lock_class_key __key; \
+ __rt_mutex_init(mutex, __func__, &__key); \
+} while (0)
+
extern void rt_mutex_debug_task_free(struct task_struct *tsk);
#else
# define __DEBUG_RT_MUTEX_INITIALIZER(mutexname)
-# define rt_mutex_init(mutex) __rt_mutex_init(mutex, NULL)
+# define rt_mutex_init(mutex) __rt_mutex_init(mutex, NULL, NULL)
# define rt_mutex_debug_task_free(t) do { } while (0)
#endif
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+#define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname) \
+ , .dep_map = { .name = #mutexname }
+#else
+#define __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname)
+#endif
+
#define __RT_MUTEX_INITIALIZER(mutexname) \
{ .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(mutexname.wait_lock) \
, .waiters = RB_ROOT \
, .owner = NULL \
- __DEBUG_RT_MUTEX_INITIALIZER(mutexname)}
+ __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \
+ __DEP_MAP_RT_MUTEX_INITIALIZER(mutexname)}
#define DEFINE_RT_MUTEX(mutexname) \
struct rt_mutex mutexname = __RT_MUTEX_INITIALIZER(mutexname)
@@ -86,7 +103,7 @@ static inline int rt_mutex_is_locked(struct rt_mutex *lock)
return lock->owner != NULL;
}
-extern void __rt_mutex_init(struct rt_mutex *lock, const char *name);
+extern void __rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key);
extern void rt_mutex_destroy(struct rt_mutex *lock);
extern void rt_mutex_lock(struct rt_mutex *lock);

kernel/locking/rtmutex-debug.c

View file
diff --git a/kernel/locking/rtmutex-debug.c b/kernel/locking/rtmutex-debug.c
index 58e366a..ac35e64 100644
--- a/kernel/locking/rtmutex-debug.c
+++ b/kernel/locking/rtmutex-debug.c
@@ -166,12 +166,16 @@ void debug_rt_mutex_free_waiter(struct rt_mutex_waiter *waiter)
memset(waiter, 0x22, sizeof(*waiter));
}
-void debug_rt_mutex_init(struct rt_mutex *lock, const char *name)
+void debug_rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key)
{
/*
* Make sure we are not reinitializing a held lock:
*/
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
lock->name = name;
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ lockdep_init_map(&lock->dep_map, name, key, 0);
+#endif
}

kernel/locking/rtmutex-debug.h

View file
diff --git a/kernel/locking/rtmutex-debug.h b/kernel/locking/rtmutex-debug.h
index b585af9..5078c6d 100644
--- a/kernel/locking/rtmutex-debug.h
+++ b/kernel/locking/rtmutex-debug.h
@@ -11,7 +11,7 @@
extern void debug_rt_mutex_init_waiter(struct rt_mutex_waiter *waiter);
extern void debug_rt_mutex_free_waiter(struct rt_mutex_waiter *waiter);
-extern void debug_rt_mutex_init(struct rt_mutex *lock, const char *name);
+extern void debug_rt_mutex_init(struct rt_mutex *lock, const char *name, struct lock_class_key *key);
extern void debug_rt_mutex_lock(struct rt_mutex *lock);
extern void debug_rt_mutex_unlock(struct rt_mutex *lock);
extern void debug_rt_mutex_proxy_lock(struct rt_mutex *lock,

kernel/locking/rtmutex.c

View file
diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
index 28cd09e..7806989 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -1481,6 +1481,7 @@ void __sched rt_mutex_lock(struct rt_mutex *lock)
{
might_sleep();
+ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_);
rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, rt_mutex_slowlock);
}
EXPORT_SYMBOL_GPL(rt_mutex_lock);
@@ -1496,9 +1497,16 @@ EXPORT_SYMBOL_GPL(rt_mutex_lock);
*/
int __sched rt_mutex_lock_interruptible(struct rt_mutex *lock)
{
+ int ret;
+
might_sleep();
- return rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, rt_mutex_slowlock);
+ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_);
+ ret = rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE, rt_mutex_slowlock);
+ if (ret)
+ mutex_release(&lock->dep_map, 1, _RET_IP_);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible);
@@ -1526,11 +1534,18 @@ int __sched rt_mutex_futex_trylock(struct rt_mutex *lock)
int
rt_mutex_timed_lock(struct rt_mutex *lock, struct hrtimer_sleeper *timeout)
{
+ int ret;
+
might_sleep();
- return rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout,
+ mutex_acquire(&lock->dep_map, 0, 0, _RET_IP_);
+ ret = rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout,
RT_MUTEX_MIN_CHAINWALK,
rt_mutex_slowlock);
+ if (ret)
+ mutex_release(&lock->dep_map, 1, _RET_IP_);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(rt_mutex_timed_lock);
@@ -1547,10 +1562,16 @@ EXPORT_SYMBOL_GPL(rt_mutex_timed_lock);
*/
int __sched rt_mutex_trylock(struct rt_mutex *lock)
{
+ int ret;
+
if (WARN_ON_ONCE(in_irq() || in_nmi() || in_serving_softirq()))
return 0;
- return rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock);
+ ret = rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock);
+ if (ret)
+ mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(rt_mutex_trylock);
@@ -1561,6 +1582,7 @@ EXPORT_SYMBOL_GPL(rt_mutex_trylock);
*/
void __sched rt_mutex_unlock(struct rt_mutex *lock)
{
+ mutex_release(&lock->dep_map, 1, _RET_IP_);
rt_mutex_fastunlock(lock, rt_mutex_slowunlock);
}
EXPORT_SYMBOL_GPL(rt_mutex_unlock);
@@ -1620,7 +1642,6 @@ void rt_mutex_destroy(struct rt_mutex *lock)
lock->magic = NULL;
#endif
}
-
EXPORT_SYMBOL_GPL(rt_mutex_destroy);
/**
@@ -1632,14 +1653,16 @@ EXPORT_SYMBOL_GPL(rt_mutex_destroy);
*
* Initializing of a locked rt lock is not allowed
*/
-void __rt_mutex_init(struct rt_mutex *lock, const char *name)
+void __rt_mutex_init(struct rt_mutex *lock, const char *name,
+ struct lock_class_key *key)
{
lock->owner = NULL;
raw_spin_lock_init(&lock->wait_lock);
lock->waiters = RB_ROOT;
lock->waiters_leftmost = NULL;
- debug_rt_mutex_init(lock, name);
+ if (name && key)
+ debug_rt_mutex_init(lock, name, key);
}
EXPORT_SYMBOL_GPL(__rt_mutex_init);
@@ -1660,7 +1683,7 @@ EXPORT_SYMBOL_GPL(__rt_mutex_init);
void rt_mutex_init_proxy_locked(struct rt_mutex *lock,
struct task_struct *proxy_owner)
{
- __rt_mutex_init(lock, NULL);
+ __rt_mutex_init(lock, NULL, NULL);
debug_rt_mutex_proxy_lock(lock, proxy_owner);
rt_mutex_set_owner(lock, proxy_owner);
}

kernel/locking/rtmutex.h

View file
diff --git a/kernel/locking/rtmutex.h b/kernel/locking/rtmutex.h
index 6607802..5c253ca 100644
--- a/kernel/locking/rtmutex.h
+++ b/kernel/locking/rtmutex.h
@@ -17,7 +17,7 @@
#define debug_rt_mutex_proxy_lock(l,p) do { } while (0)
#define debug_rt_mutex_proxy_unlock(l) do { } while (0)
#define debug_rt_mutex_unlock(l) do { } while (0)
-#define debug_rt_mutex_init(m, n) do { } while (0)
+#define debug_rt_mutex_init(m, n, k) do { } while (0)
#define debug_rt_mutex_deadlock(d, a ,l) do { } while (0)
#define debug_rt_mutex_print_deadlock(w) do { } while (0)
#define debug_rt_mutex_reset_waiter(w) do { } while (0)

lib/Kconfig.debug

View file
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index a7a751a..9c5d40a 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1052,6 +1052,7 @@ config DEBUG_LOCK_ALLOC
depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
select DEBUG_SPINLOCK
select DEBUG_MUTEXES
+ select DEBUG_RT_MUTEXES if RT_MUTEXES
select LOCKDEP
help
This feature will check whether any held lock (spinlock, rwlock,
@@ -1067,6 +1068,7 @@ config PROVE_LOCKING
select LOCKDEP
select DEBUG_SPINLOCK
select DEBUG_MUTEXES
+ select DEBUG_RT_MUTEXES if RT_MUTEXES
select DEBUG_LOCK_ALLOC
select TRACE_IRQFLAGS
default n
@@ -1121,6 +1123,7 @@ config LOCK_STAT
select LOCKDEP
select DEBUG_SPINLOCK
select DEBUG_MUTEXES
+ select DEBUG_RT_MUTEXES if RT_MUTEXES
select DEBUG_LOCK_ALLOC
default n
help

lib/locking-selftest-rtmutex.h

View file
diff --git a/lib/locking-selftest-rtmutex.h b/lib/locking-selftest-rtmutex.h
new file mode 100644
index 0000000..e3cb839
--- /dev/null
+++ b/lib/locking-selftest-rtmutex.h
@@ -0,0 +1,11 @@
+#undef LOCK
+#define LOCK RTL
+
+#undef UNLOCK
+#define UNLOCK RTU
+
+#undef RLOCK
+#undef WLOCK
+
+#undef INIT
+#define INIT RTI

lib/locking-selftest.c

View file
diff --git a/lib/locking-selftest.c b/lib/locking-selftest.c
index f3a217e..6f2b135 100644
--- a/lib/locking-selftest.c
+++ b/lib/locking-selftest.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/debug_locks.h>
#include <linux/irqflags.h>
+#include <linux/rtmutex.h>
/*
* Change this to 1 if you want to see the failure printouts:
@@ -46,6 +47,7 @@ __setup("debug_locks_verbose=", setup_debug_locks_verbose);
#define LOCKTYPE_MUTEX 0x4
#define LOCKTYPE_RWSEM 0x8
#define LOCKTYPE_WW 0x10
+#define LOCKTYPE_RTMUTEX 0x20
static struct ww_acquire_ctx t, t2;
static struct ww_mutex o, o2, o3;
@@ -74,6 +76,15 @@ static DECLARE_RWSEM(rwsem_B);
static DECLARE_RWSEM(rwsem_C);
static DECLARE_RWSEM(rwsem_D);
+#ifdef CONFIG_RT_MUTEXES
+
+static DEFINE_RT_MUTEX(rtmutex_A);
+static DEFINE_RT_MUTEX(rtmutex_B);
+static DEFINE_RT_MUTEX(rtmutex_C);
+static DEFINE_RT_MUTEX(rtmutex_D);
+
+#endif
+
/*
* Locks that we initialize dynamically as well so that
* e.g. X1 and X2 becomes two instances of the same class,
@@ -108,6 +119,17 @@ static DECLARE_RWSEM(rwsem_Y2);
static DECLARE_RWSEM(rwsem_Z1);
static DECLARE_RWSEM(rwsem_Z2);
+#ifdef CONFIG_RT_MUTEXES
+
+static DEFINE_RT_MUTEX(rtmutex_X1);
+static DEFINE_RT_MUTEX(rtmutex_X2);
+static DEFINE_RT_MUTEX(rtmutex_Y1);
+static DEFINE_RT_MUTEX(rtmutex_Y2);
+static DEFINE_RT_MUTEX(rtmutex_Z1);
+static DEFINE_RT_MUTEX(rtmutex_Z2);
+
+#endif
+
/*
* non-inlined runtime initializers, to let separate locks share
* the same lock-class:
@@ -129,6 +151,17 @@ INIT_CLASS_FUNC(Z)
static void init_shared_classes(void)
{
+#ifdef CONFIG_RT_MUTEXES
+ static struct lock_class_key rt_X, rt_Y, rt_Z;
+
+ __rt_mutex_init(&rtmutex_X1, __func__, &rt_X);
+ __rt_mutex_init(&rtmutex_X2, __func__, &rt_X);
+ __rt_mutex_init(&rtmutex_Y1, __func__, &rt_Y);
+ __rt_mutex_init(&rtmutex_Y2, __func__, &rt_Y);
+ __rt_mutex_init(&rtmutex_Z1, __func__, &rt_Z);
+ __rt_mutex_init(&rtmutex_Z2, __func__, &rt_Z);
+#endif
+
init_class_X(&lock_X1, &rwlock_X1, &mutex_X1, &rwsem_X1);
init_class_X(&lock_X2, &rwlock_X2, &mutex_X2, &rwsem_X2);
@@ -193,6 +226,10 @@ static void init_shared_classes(void)
#define MU(x) mutex_unlock(&mutex_##x)
#define MI(x) mutex_init(&mutex_##x)
+#define RTL(x) rt_mutex_lock(&rtmutex_##x)
+#define RTU(x) rt_mutex_unlock(&rtmutex_##x)
+#define RTI(x) rt_mutex_init(&rtmutex_##x)
+
#define WSL(x) down_write(&rwsem_##x)
#define WSU(x) up_write(&rwsem_##x)
@@ -264,6 +301,11 @@ GENERATE_TESTCASE(AA_wsem)
#include "locking-selftest-rsem.h"
GENERATE_TESTCASE(AA_rsem)
+#ifdef CONFIG_RT_MUTEXES
+#include "locking-selftest-rtmutex.h"
+GENERATE_TESTCASE(AA_rtmutex);
+#endif
+
#undef E
/*
@@ -345,6 +387,11 @@ GENERATE_TESTCASE(ABBA_wsem)
#include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABBA_rsem)
+#ifdef CONFIG_RT_MUTEXES
+#include "locking-selftest-rtmutex.h"
+GENERATE_TESTCASE(ABBA_rtmutex);
+#endif
+
#undef E
/*
@@ -373,6 +420,11 @@ GENERATE_TESTCASE(ABBCCA_wsem)
#include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABBCCA_rsem)
+#ifdef CONFIG_RT_MUTEXES
+#include "locking-selftest-rtmutex.h"
+GENERATE_TESTCASE(ABBCCA_rtmutex);
+#endif
+
#undef E
/*
@@ -401,6 +453,11 @@ GENERATE_TESTCASE(ABCABC_wsem)
#include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABCABC_rsem)
+#ifdef CONFIG_RT_MUTEXES
+#include "locking-selftest-rtmutex.h"
+GENERATE_TESTCASE(ABCABC_rtmutex);
+#endif
+
#undef E
/*
@@ -430,6 +487,11 @@ GENERATE_TESTCASE(ABBCCDDA_wsem)
#include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABBCCDDA_rsem)
+#ifdef CONFIG_RT_MUTEXES
+#include "locking-selftest-rtmutex.h"
+GENERATE_TESTCASE(ABBCCDDA_rtmutex);
+#endif
+
#undef E
/*
@@ -458,6 +520,11 @@ GENERATE_TESTCASE(ABCDBDDA_wsem)
#include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABCDBDDA_rsem)
+#ifdef CONFIG_RT_MUTEXES
+#include "locking-selftest-rtmutex.h"
+GENERATE_TESTCASE(ABCDBDDA_rtmutex);
+#endif
+
#undef E
/*
@@ -486,6 +553,11 @@ GENERATE_TESTCASE(ABCDBCDA_wsem)
#include "locking-selftest-rsem.h"
GENERATE_TESTCASE(ABCDBCDA_rsem)
+#ifdef CONFIG_RT_MUTEXES
+#include "locking-selftest-rtmutex.h"
+GENERATE_TESTCASE(ABCDBCDA_rtmutex);
+#endif
+
#undef E
/*
@@ -513,33 +585,10 @@ GENERATE_TESTCASE(double_unlock_wsem)
#include "locking-selftest-rsem.h"
GENERATE_TESTCASE(double_unlock_rsem)
-#undef E
-
-/*
- * Bad unlock ordering:
- */
-#define E() \
- \
- LOCK(A); \
- LOCK(B); \
- UNLOCK(A); /* fail */ \
- UNLOCK(B);
-
-/*
- * 6 testcases:
- */
-#include "locking-selftest-spin.h"
-GENERATE_TESTCASE(bad_unlock_order_spin)
-#include "locking-selftest-wlock.h"
-GENERATE_TESTCASE(bad_unlock_order_wlock)
-#include "locking-selftest-rlock.h"

This diff is incomplete. Download the complete patch.

lib/refcount.c

View file

This diff is incomplete. Download the complete patch.

tools/Makefile

View file

This diff is incomplete. Download the complete patch.

tools/include/asm/sections.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/bitops.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/compiler.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/debug_locks.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/delay.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/err.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/ftrace.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/gfp.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/hardirq.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/interrupt.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/irqflags.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/jhash.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/kallsyms.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/kern_levels.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/kernel.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/kmemcheck.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/linkage.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/lockdep.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/module.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/mutex.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/proc_fs.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/rcu.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/sched/clock.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/sched/mm.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/sched/task.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/seq_file.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/spinlock.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/stacktrace.h

View file

This diff is incomplete. Download the complete patch.

tools/include/linux/unaligned/packed_struct.h

View file

This diff is incomplete. Download the complete patch.

tools/include/trace/events/lock.h

View file

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/Makefile

View file

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/lockdep.c

View file

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/preload.c

View file

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/rbtree.c

View file

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/run_tests.sh

View file

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/asm/hash.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/asm/hweight.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/asm/sections.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/bitops.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/compiler.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/delay.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/ftrace.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/gfp.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/hash.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/interrupt.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/kernel.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/linkage.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/list.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/mutex.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/poison.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/prefetch.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/proc_fs.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/rbtree_augmented.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/seq_file.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/spinlock.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/linux/stringify.h

View before deletion

This diff is incomplete. Download the complete patch.

tools/lib/lockdep/uinclude/trace/events/lock.h

View before deletion

This diff is incomplete. Download the complete patch.