mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH RT 0/6] lockstat measurement extensions
@ 2008-03-14  0:03 Bill Huey (hui)
  2008-03-14  0:07 ` [PATCH RT 1/6] " Bill Huey (hui)
  2008-03-14  0:26 ` [PATCH RT 0/6] " Bill Huey (hui)
  0 siblings, 2 replies; 9+ messages in thread
From: Bill Huey (hui) @ 2008-03-14  0:03 UTC (permalink / raw)
  To: Gregory Haskins, mingo
  Cc: a.p.zijlstra, tglx, rostedt, linux-rt-users, linux-kernel, kevin,
	cminyard, dsingleton, dwalker, npiggin, dsaxena, ak, pavel, acme,
	gregkh, sdietrich, pmorreale, mkohari

Hello,

I'd like to announce extensions to the lockstat/lockdep framework to
measure the possibility of whether or not adaptive spins and/or lock
steals can happen within the rtmutex implementation's slow path. This
extends the common rtmutex functions to pass the depmap and friends so
that the lock_note_contention function can determine whether a
rtmutex->owner is live on another run queue. If so, then it logs it in
per cpu storage with the peterz's lockstat framework.

I had to extend a lot of function headers using some preprocessor
definitions to minimize the ifdef complexity, but it's still rather
complex even with some of the reductions. With that said and done, I'd
like suggest that a better method would be to add fields in the struct
rtmutex to pass values down to the lock_note_contention() function and
to contain state/events that can be post processed by
LOCK_CONTENDED*() macros instead. This was originally proposed by
Peter Zijlstra, but I had already decided to complete this track just
to see where it would take me.

This is a reimplementation of my own lockstat work into Peter's stuff.
I hope to pass it over to the Novell folks so that they can maintain
and take over development of this feature which will shine a light on
whether adaptive locks and lateral steals are useful in -rt.

Some results here:
----

lock_stat version 0.2
spinnables_total = 320571
contentions_total = 1670097
stolen_total = 1161888
cpu range error = 0
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                              class name    con-bounces contentions
[adapt,steals]   waittime-min   waittime-max waittime-total
acq-bounces   acquisitions   holdtime-min   holdtime-max
holdtime-total
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

                &type->i_mutex_dir_key#2:        273392         659581
[172517, 658744] 18446744073709      580800.58   524881532.33
315374        1050378 18446744073709      605616.37   107058004.06
                ------------------------
                &type->i_mutex_dir_key#2         659581
[<ffffffff802a785b>] vfs_readdir+0x52/0xaf
                &type->i_mutex_dir_key#2              0
[<ffffffff802a2917>] do_lookup+0x84/0x1b4

...............................................................................................................................................................................................

                              irq_desc#1:        305009         305009
[1, 0]           0.51          13.55     1120626.91         620872
   1783324           0.23          36.62     8316839.04
                              ----------
                              irq_desc#1         304949
[<ffffffff8026c3bf>] do_irqd+0x86/0x2c7
                              irq_desc#1             39
[<ffffffff8026cfc8>] handle_fasteoi_irq+0x2a/0x10a

...............................................................................................................................................................................................

    (raw_spinlock_t *)(&lock->wait_lock):         77005          77561
[623, 0]           0.32          44.14       93979.97         743444
    10998216           0.24          53.89     4278155.20
    ------------------------------------
    (raw_spinlock_t *)(&lock->wait_lock)          14706
[<ffffffff804ff9bd>] rt_spin_lock_slowunlock+0xf/0x5c
    (raw_spinlock_t *)(&lock->wait_lock)          15631
[<ffffffff804ffa19>] rt_mutex_slowunlock+0xf/0x59
    (raw_spinlock_t *)(&lock->wait_lock)             61
[<ffffffff804ffe8e>] rt_mutex_slowlock+0x1f7/0x2d5
    (raw_spinlock_t *)(&lock->wait_lock)              9
[<ffffffff804ffbf0>] rt_spin_lock_slowlock+0x128/0x1cf

...............................................................................................................................................................................................

                   dcache_lock.wait_lock:         69559          72424
[34806, 0]           0.36          13.90       87260.09         379404
       1234745           0.29          27.01     1749680.84
                   ---------------------
                   dcache_lock.wait_lock          12618
[<ffffffff804ff9bd>] rt_spin_lock_slowunlock+0xf/0x5c
                   dcache_lock.wait_lock          51591
[<ffffffff804ffbf0>] rt_spin_lock_slowlock+0x128/0x1cf
                   dcache_lock.wait_lock           8072
[<ffffffff804ffb02>] rt_spin_lock_slowlock+0x3a/0x1cf
                   dcache_lock.wait_lock            143
[<ffffffff802623b7>] task_blocks_on_rt_mutex+0x1aa/0x1bf

----

I measure the total number of contention events printed out at the
very top of the listing and spin/steals within "[]" to the right of
the contention number for that lock. It's interesting how many steals
actually happen in that the percentage is quite substantial. This was
against a load of "find /" commands which hit inode locks pretty
heavily. irq_desc is interesting as well.

Patches can be found here:
http://mmlinux.sourceforge.net/public/lockstat/patch?.diff

More of the output can be found here
http://mmlinux.sourceforge.net/public/lockstat/output

bill

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RT 1/6] lockstat measurement extensions
  2008-03-14  0:03 [PATCH RT 0/6] lockstat measurement extensions Bill Huey (hui)
@ 2008-03-14  0:07 ` Bill Huey (hui)
  2008-03-14  0:09   ` [PATCH RT 2/6] " Bill Huey (hui)
  2008-03-14  0:26 ` [PATCH RT 0/6] " Bill Huey (hui)
  1 sibling, 1 reply; 9+ messages in thread
From: Bill Huey (hui) @ 2008-03-14  0:07 UTC (permalink / raw)
  To: Gregory Haskins, mingo
  Cc: a.p.zijlstra, tglx, rostedt, linux-rt-users, linux-kernel, kevin,
	cminyard, dsingleton, dwalker, npiggin, dsaxena, ak, pavel, acme,
	gregkh, sdietrich, pmorreale, mkohari

[-- Attachment #1: Type: text/plain, Size: 80 bytes --]

Function parameter extension macros and function prototype redefinitions.

bill

[-- Attachment #2: patch0.diff --]
[-- Type: application/octet-stream, Size: 7020 bytes --]

--- linux-2.6.24/include/linux/lockdep.h	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/include/linux/lockdep.h	2008-03-13 14:02:43.000000000 -0700
@@ -19,6 +19,8 @@
 #include <linux/debug_locks.h>
 #include <linux/stacktrace.h>
 
+//#include <linux/rtmutex_common.h>
+
 /*
  * Lock-class usage-state bits:
  */
@@ -143,6 +145,10 @@
 
 struct lock_class_stats {
 	unsigned long			contention_point[4];
+#ifdef CONFIG_LOCK_STAT
+	unsigned long			spinnable;
+	unsigned long			stolen;
+#endif
 	struct lock_time		read_waittime;
 	struct lock_time		write_waittime;
 	struct lock_time		read_holdtime;
@@ -347,57 +353,190 @@
 
 #endif /* !LOCKDEP */
 
-#ifdef CONFIG_LOCK_STAT
+/*
+ * lockstat contention tracking is pushed down into the rtmutex implementation
+ * CONFIG_PREEMPT_RT instead.
+ */
+#if !defined(CONFIG_PREEMPT_RT) && defined(CONFIG_LOCK_STAT)
+
+extern void lock_note_contended(struct lockdep_map *lock, unsigned long ip);
+extern void lock_note_acquired(struct lockdep_map *lock);
+extern void lock_note_stolen(struct lockdep_map *lock);
+
+#define RET_IP_DECL	unsigned long _ip
+#define __RET_IP_DECL	, RET_IP_DECL
+#define __RET_IP_PARAM	, _ip
 
-extern void lock_contended(struct lockdep_map *lock, unsigned long ip);
-extern void lock_acquired(struct lockdep_map *lock);
+#define DEP_MAP_DECL	struct lockdep_map *_dep_map
+#define __DEP_MAP_DECL	, DEP_MAP_DECL
+#define DEP_MAP_PARAM	_dep_map
+#define __DEP_MAP_PARAM , DEP_MAP_PARAM
+
+#define LOCKDEP_TS_DECL
+#define __LOCKDEP_TS_DECL
+#define __LOCKDEP_TS_PARAM
+#define __LOCKDEP_TS_NULL
+
+#define LOCKDEP_PARAMS DEP_MAP_PARAM __RET_IP_PARAM
+#define __LOCKDEP_PARAMS , LOCKDEP_PARAMS
+#define __LOCKDEP_DECLS , DEP_MAP_DECL __RET_IP_DECL
+
+#define LOCKDEP_PARAMS_L0	NULL, _RET_IP_
+#define __LOCKDEP_PARAMS_L0	, LOCKDEP_PARAMS_L0
+
+#define LOCKDEP_PARAMS_SEM(lock)
+#define __LOCKDEP_PARAMS_SEM(lock)
+
+#define LOCKDEP_PARAMS_RWSEM(lock)
+#define __LOCKDEP_PARAMS_RWSEM(lock)
+
+#define LOCKDEP_PARAMS_MUTEX(lock)
+#define __LOCKDEP_PARAMS_MUTEX(lock)
 
 #define LOCK_CONTENDED(_lock, try, lock)			\
 do {								\
 	if (!try(_lock)) {					\
-		lock_contended(&(_lock)->dep_map, _RET_IP_);	\
+		lock_note_contended(&(_lock)->dep_map, _RET_IP_);	\
 		lock(_lock);					\
 	}							\
-	lock_acquired(&(_lock)->dep_map);			\
+	lock_note_acquired(&(_lock)->dep_map);			\
 } while (0)
 
-#define LOCK_CONTENDED_RT(_lock, f_try, f_lock)			\
+#define LOCK_CONTENDED_COMPAT(_lock, try, lock)			\
+do {								\
+	if (!try(_lock)) {					\
+		lock_note_contended(&(_lock)->dep_map, _RET_IP_);	\
+		lock(_lock);					\
+	}							\
+	lock_note_acquired(&(_lock)->dep_map);			\
+} while (0)
+
+#define LOCK_CONTENDED_RT(_lock, f_try, f_lock, ip)		\
 do {								\
 	if (!f_try(&(_lock)->lock)) {				\
-		lock_contended(&(_lock)->dep_map, _RET_IP_);	\
+		lock_note_contended(&(_lock)->dep_map, _RET_IP_);	\
 		f_lock(&(_lock)->lock);				\
 	}							\
-	lock_acquired(&(_lock)->dep_map);			\
+	lock_note_acquired(&(_lock)->dep_map);			\
 } while (0)
 
 
-#define LOCK_CONTENDED_RT_RET(_lock, f_try, f_lock)		\
+#define LOCK_CONTENDED_RT_RET(_lock, f_try, f_lock, ip)		\
 ({								\
  	int ret = 0;						\
 	if (!f_try(&(_lock)->lock)) {				\
-		lock_contended(&(_lock)->dep_map, _RET_IP_);	\
+		lock_note_contended(&(_lock)->dep_map, _RET_IP_);	\
 		ret = f_lock(&(_lock)->lock);			\
 	}							\
 	if (!ret)						\
-		lock_acquired(&(_lock)->dep_map);		\
+		lock_note_acquired(&(_lock)->dep_map);		\
  	ret;							\
 })
 
-#else /* CONFIG_LOCK_STAT */
+#else /* !defined(CONFIG_PREEMPT_RT) && defined(CONFIG_LOCK_STAT) */
+
+#if defined(CONFIG_PREEMPT_RT) && defined(CONFIG_LOCK_STAT)
+
+extern void lock_note_contended(struct lockdep_map *_dep_map, unsigned long _ip, struct task_struct *_owner);
+extern void lock_note_acquired(struct lockdep_map *lock);
+extern void lock_note_stolen(struct lockdep_map *lock);
+
+#define RET_IP_DECL	unsigned long _ip
+#define __RET_IP_DECL	, RET_IP_DECL
+#define __RET_IP_PARAM	, ip
+
+#define DEP_MAP_DECL	struct lockdep_map *_dep_map
+#define __DEP_MAP_DECL	, DEP_MAP_DECL
+#define DEP_MAP_PARAM	_dep_map
+#define __DEP_MAP_PARAM , DEP_MAP_PARAM
+
+#define LOCKDEP_TS_DECL		struct task_struct *_owner
+#define __LOCKDEP_TS_DECL	, LOCKDEP_TS_DECL
+#define __LOCKDEP_TS_PARAM	, _owner
+#define __LOCKDEP_TS_NULL	, NULL
+
+//#define LOCKDEP_PARAMS	 (struct task_struct *) ((unsigned long)_owner & (unsigned long) ~0x3), _dep_map, _ip
+#define LOCKDEP_PARAMS	 rt_mutex_real_owner(lock), _dep_map, _ip
+
+#define __LOCKDEP_PARAMS , LOCKDEP_PARAMS
+//#define __LOCKDEP_DECLS  , DEP_MAP_DECL, RET_IP_DECL
+#define __LOCKDEP_DECLS  , struct task_struct *_owner, DEP_MAP_DECL, RET_IP_DECL
+
+#define LOCKDEP_PARAMS_L0		current, NULL, _RET_IP_
+#define __LOCKDEP_PARAMS_L0		, LOCKDEP_PARAMS_L0
+
+#define LOCKDEP_PARAMS_SEM(lock)	LOCKDEP_PARAMS_L0
+#define __LOCKDEP_PARAMS_SEM(lock)	, LOCKDEP_PARAMS_L0
 
-#define lock_contended(lockdep_map, ip) do {} while (0)
-#define lock_acquired(lockdep_map) do {} while (0)
+#define LOCKDEP_PARAMS_RWSEM(lock)	LOCKDEP_PARAMS_L0
+#define __LOCKDEP_PARAMS_RWSEM(lock)	, LOCKDEP_PARAMS_L0
+
+#define LOCKDEP_PARAMS_MUTEX(lock)	LOCKDEP_PARAMS_L0
+#define __LOCKDEP_PARAMS_MUTEX(lock)	, LOCKDEP_PARAMS_L0
+
+#define LOCK_CONTENDED(_lock, try, lock)			\
+do {								\
+	if (!try(_lock)) {					\
+		lock_note_contended((struct task_struct *) &(_lock)->owner, \
+						&(_lock)->dep_map, \
+						_RET_IP_); \
+		lock(_lock);					\
+	}							\
+	lock_note_acquired(&(_lock)->dep_map);			\
+} while (0)
+
+#define LOCK_CONTENDED_COMPAT(_lock, try, lock)			\
+do {								\
+	if (!try(_lock)) {					\
+		lock_note_contended(NULL, &(_lock)->dep_map, _RET_IP_); \
+		lock(_lock);					\
+	}							\
+	lock_note_acquired(&(_lock)->dep_map);			\
+} while (0)
+
+#define LOCK_CONTENDED_RT(_lock, f_try, f_lock) \
+	f_lock(&(_lock)->lock, NULL, &(_lock)->dep_map, _RET_IP_)
+
+#define LOCK_CONTENDED_RT_RET(_lock, f_try, f_lock) \
+	f_lock(&(_lock)->lock, NULL, NULL, _RET_IP_)
+
+#elif /*defined(CONFIG_PREEMPT_RT) && */!defined(CONFIG_LOCK_STAT)
+/*#elif !defined(CONFIG_PREEMPT_RT) && !defined(CONFIG_LOCK_STAT) */
+
+#define lock_note_contended(lockdep_map, ip) do {} while (0)
+#define lock_note_acquired(lockdep_map) do {} while (0)
+
+#define __RET_IP_DECL
+#define __RET_IP_PARAM
+
+#define __TASK_STRUCT_LOCK_DECL
+#define __TASK_STRUCT_LOCK_PARAM
+#define __TASK_STRUCT_LOCK_PARAM2 lock,
 
 #define LOCK_CONTENDED(_lock, try, lock) \
 	lock(_lock)
 
+#define LOCK_CONTENDED_COMPAT(_lock, try, lock) \
+	lock(_lock)
+
 #define LOCK_CONTENDED_RT(_lock, f_try, f_lock) \
 	f_lock(&(_lock)->lock)
 
 #define LOCK_CONTENDED_RT_RET(_lock, f_try, f_lock) \
 	f_lock(&(_lock)->lock)
 
-#endif /* CONFIG_LOCK_STAT */
+#else
+#error
+#endif
+
+/*
+ * ac	(c1)
+ * a	(c2)
+ * ab	(c2)
+ * abc	(c2)
+ */
+
+#endif /* !defined(CONFIG_PREEMPT_RT) && defined(CONFIG_LOCK_STAT) */
 
 #if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_GENERIC_HARDIRQS)
 extern void early_init_irq_lock_class(void);

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RT 2/6] lockstat measurement extensions
  2008-03-14  0:07 ` [PATCH RT 1/6] " Bill Huey (hui)
@ 2008-03-14  0:09   ` Bill Huey (hui)
  2008-03-14  0:12     ` [PATCH RT 3/6] " Bill Huey (hui)
  0 siblings, 1 reply; 9+ messages in thread
From: Bill Huey (hui) @ 2008-03-14  0:09 UTC (permalink / raw)
  To: Gregory Haskins, mingo
  Cc: a.p.zijlstra, tglx, rostedt, linux-rt-users, linux-kernel, kevin,
	cminyard, dsingleton, dwalker, npiggin, dsaxena, ak, pavel, acme,
	gregkh, sdietrich, pmorreale, mkohari

[-- Attachment #1: Type: text/plain, Size: 40 bytes --]

Function prototype redefinitions.

bill

[-- Attachment #2: patch1.diff --]
[-- Type: application/octet-stream, Size: 1974 bytes --]

--- linux-2.6.24/include/linux/rtmutex.h	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/include/linux/rtmutex.h	2008-03-04 01:01:06.000000000 -0800
@@ -85,14 +85,15 @@
 extern void __rt_mutex_init(struct rt_mutex *lock, const char *name);
 extern void rt_mutex_destroy(struct rt_mutex *lock);
 
-extern void rt_mutex_lock(struct rt_mutex *lock);
+extern void rt_mutex_lock(struct rt_mutex *lock __LOCKDEP_DECLS);
 extern int rt_mutex_lock_interruptible(struct rt_mutex *lock,
-						int detect_deadlock);
+						int detect_deadlock __LOCKDEP_DECLS);
 extern int rt_mutex_timed_lock(struct rt_mutex *lock,
 					struct hrtimer_sleeper *timeout,
 					int detect_deadlock);
 
 extern int rt_mutex_trylock(struct rt_mutex *lock);
+extern int __rt_mutex_trylock(struct rt_mutex *lock __LOCKDEP_DECLS);
 
 extern void rt_mutex_unlock(struct rt_mutex *lock);
 
--- linux-2.6.24/include/linux/sched.h	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/include/linux/sched.h	2008-03-13 00:40:02.000000000 -0700
@@ -2093,10 +2093,17 @@
 extern void signal_wake_up(struct task_struct *t, int resume_stopped);
 
 /*
+ * lockstat support
+ */
+extern int task_spinnable(struct task_struct *p);
+
+/*
  * Wrappers for p->thread_info->cpu access. No-op on UP.
  */
 #ifdef CONFIG_SMP
 
+extern atomic_t cpu_range_error;
+
 static inline unsigned int task_cpu(const struct task_struct *p)
 {
 	return task_thread_info(p)->cpu;
--- linux-2.6.24/include/linux/spinlock.h	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/include/linux/spinlock.h	2008-03-03 14:01:48.000000000 -0800
@@ -169,7 +169,7 @@
  * lockdep-less calls, for derived types like rwlock:
  * (for trylock they can use rt_mutex_trylock() directly.
  */
-extern void __lockfunc __rt_spin_lock(struct rt_mutex *lock);
+extern void __lockfunc __rt_spin_lock(struct rt_mutex *lock __LOCKDEP_DECLS);
 extern void __lockfunc __rt_spin_unlock(struct rt_mutex *lock);
 
 #ifdef CONFIG_PREEMPT_RT

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RT 3/6] lockstat measurement extensions
  2008-03-14  0:09   ` [PATCH RT 2/6] " Bill Huey (hui)
@ 2008-03-14  0:12     ` Bill Huey (hui)
  2008-03-14  0:15       ` [PATCH RT 4/6] " Bill Huey (hui)
  0 siblings, 1 reply; 9+ messages in thread
From: Bill Huey (hui) @ 2008-03-14  0:12 UTC (permalink / raw)
  To: Gregory Haskins, mingo
  Cc: a.p.zijlstra, tglx, rostedt, linux-rt-users, linux-kernel, kevin,
	cminyard, dsingleton, dwalker, npiggin, dsaxena, ak, pavel, acme,
	gregkh, sdietrich, pmorreale, mkohari

[-- Attachment #1: Type: text/plain, Size: 351 bytes --]

lock_contention/lock_acquire() refactor to put common code searching
for an hlock into a common function. A function pointer is pass to ths
common function which can do lock_note* specific functionality. gcc
4.3 will inline this so this will not effect codegen quality for that
compiler version (it's now hitting ubuntu and other distributions)

bill

[-- Attachment #2: patch2.diff --]
[-- Type: application/octet-stream, Size: 8490 bytes --]

--- linux-2.6.24/kernel/lockdep.c	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/kernel/lockdep.c	2008-03-13 14:02:14.000000000 -0700
@@ -40,6 +40,7 @@
 #include <linux/utsname.h>
 #include <linux/hash.h>
 #include <linux/ftrace.h>
+#include <linux/sched.h>
 
 #include <asm/sections.h>
 
@@ -179,6 +180,9 @@
 		lock_time_add(&pcs->read_holdtime, &stats.read_holdtime);
 		lock_time_add(&pcs->write_holdtime, &stats.write_holdtime);
 
+		stats.stolen += pcs->stolen;
+		stats.spinnable += pcs->spinnable;
+
 		for (i = 0; i < ARRAY_SIZE(stats.bounces); i++)
 			stats.bounces[i] += pcs->bounces[i];
 	}
@@ -2854,13 +2858,21 @@
 }
 
 static void
-__lock_contended(struct lockdep_map *lock, unsigned long ip)
+__lock_note_common(struct lockdep_map *dep_map,
+		   void (*blockfn) (struct lockdep_map *dep_map,
+				    struct held_lock *hlock,
+				    unsigned long ip, int i
+				    __LOCKDEP_TS_DECL),
+		    unsigned long ip
+		    __LOCKDEP_TS_DECL)
 {
 	struct task_struct *curr = current;
 	struct held_lock *hlock, *prev_hlock;
-	struct lock_class_stats *stats;
 	unsigned int depth;
-	int i, point;
+	int i;
+
+	if (!dep_map)
+		return;
 
 	depth = curr->lockdep_depth;
 	if (DEBUG_LOCKS_WARN_ON(!depth))
@@ -2874,14 +2886,30 @@
 		 */
 		if (prev_hlock && prev_hlock->irq_context != hlock->irq_context)
 			break;
-		if (hlock->instance == lock)
+		if (hlock->instance == dep_map)
 			goto found_it;
 		prev_hlock = hlock;
 	}
-	print_lock_contention_bug(curr, lock, ip);
+	print_lock_contention_bug(curr, dep_map, ip);
 	return;
 
 found_it:
+	blockfn(dep_map, hlock, ip, i __LOCKDEP_TS_PARAM);
+}
+
+atomic_t spinnables_total = {.counter = 0},
+	contentions_total = {.counter = 0},
+	stolen_total = {.counter = 0};
+
+static void
+___lock_note_contended(struct lockdep_map *dep_map,
+		       struct held_lock *hlock,
+		       unsigned long ip, int i
+		       __LOCKDEP_TS_DECL)
+{
+	struct lock_class_stats *stats;
+	int point;
+
 	hlock->waittime_stamp = sched_clock();
 
 	point = lock_contention_point(hlock->class, ip);
@@ -2889,42 +2917,38 @@
 	stats = get_lock_stats(hlock->class);
 	if (point < ARRAY_SIZE(stats->contention_point))
 		stats->contention_point[i]++;
-	if (lock->cpu != smp_processor_id())
+	if (dep_map->cpu != smp_processor_id())
 		stats->bounces[bounce_contended + !!hlock->read]++;
+#ifdef CONFIG_PREEMPT_RT
+	if (likely(_owner) && task_spinnable(_owner)) {
+		stats->spinnable++;
+		atomic_inc(&spinnables_total);
+	}
+
+	atomic_inc(&contentions_total);
+#endif
 	put_lock_stats(stats);
 }
 
 static void
-__lock_acquired(struct lockdep_map *lock)
+__lock_note_contended(struct lockdep_map *dep_map,
+		      unsigned long ip
+		      __LOCKDEP_TS_DECL)
+{
+	__lock_note_common(dep_map, ___lock_note_contended, ip __LOCKDEP_TS_PARAM);
+}
+
+static void
+___lock_note_acquired(struct lockdep_map *lock,
+		      struct held_lock *hlock,
+		      unsigned long ip, int i
+		      __LOCKDEP_TS_DECL)
 {
-	struct task_struct *curr = current;
-	struct held_lock *hlock, *prev_hlock;
 	struct lock_class_stats *stats;
-	unsigned int depth;
 	u64 now;
 	s64 waittime = 0;
-	int i, cpu;
-
-	depth = curr->lockdep_depth;
-	if (DEBUG_LOCKS_WARN_ON(!depth))
-		return;
-
-	prev_hlock = NULL;
-	for (i = depth-1; i >= 0; i--) {
-		hlock = curr->held_locks + i;
-		/*
-		 * We must not cross into another context:
-		 */
-		if (prev_hlock && prev_hlock->irq_context != hlock->irq_context)
-			break;
-		if (hlock->instance == lock)
-			goto found_it;
-		prev_hlock = hlock;
-	}
-	print_lock_contention_bug(curr, lock, _RET_IP_);
-	return;
+	int cpu;
 
-found_it:
 	cpu = smp_processor_id();
 	if (hlock->waittime_stamp) {
 		now = sched_clock();
@@ -2946,7 +2970,58 @@
 	lock->cpu = cpu;
 }
 
-void lock_contended(struct lockdep_map *lock, unsigned long ip)
+static void
+__lock_note_acquired(struct lockdep_map *lock,
+		     unsigned long ip
+		     __LOCKDEP_TS_DECL)
+{
+	__lock_note_common(lock, ___lock_note_acquired, ip __LOCKDEP_TS_PARAM);
+	//__lock_note_common(lock, ___lock_note_acquired, _RET_IP_ __LOCKDEP_TS_PARAM);
+}
+
+static void
+___lock_note_stolen(struct lockdep_map *lock,
+		      struct held_lock *hlock,
+		      unsigned long ip, int i
+		      __LOCKDEP_TS_DECL)
+{
+	struct lock_class_stats *stats;
+
+	stats = get_lock_stats(hlock->class);
+	stats->stolen++;
+	atomic_inc(&stolen_total);
+	put_lock_stats(stats);
+}
+
+static void
+__lock_note_stolen(struct lockdep_map *lock,
+		     unsigned long ip
+		     __LOCKDEP_TS_DECL)
+{
+	__lock_note_common(lock, ___lock_note_stolen, _RET_IP_ __LOCKDEP_TS_PARAM);
+}
+
+void lock_note_stolen(struct lockdep_map *dep_map)
+{
+	unsigned long flags;
+
+	if (unlikely(!lock_stat))
+		return;
+
+	if (unlikely(current->lockdep_recursion))
+		return;
+
+	raw_local_irq_save(flags);
+	check_flags(flags);
+	current->lockdep_recursion = 1;
+	__lock_note_stolen(dep_map, 0 __LOCKDEP_TS_NULL);
+	current->lockdep_recursion = 0;
+	raw_local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(lock_note_stolen);
+
+void lock_note_contended( struct lockdep_map *dep_map,
+			unsigned long ip __LOCKDEP_TS_DECL)
 {
 	unsigned long flags;
 
@@ -2959,13 +3034,13 @@
 	raw_local_irq_save(flags);
 	check_flags(flags);
 	current->lockdep_recursion = 1;
-	__lock_contended(lock, ip);
+	__lock_note_contended(dep_map, ip __LOCKDEP_TS_PARAM);
 	current->lockdep_recursion = 0;
 	raw_local_irq_restore(flags);
 }
-EXPORT_SYMBOL_GPL(lock_contended);
+EXPORT_SYMBOL_GPL(lock_note_contended);
 
-void lock_acquired(struct lockdep_map *lock)
+void lock_note_acquired(struct lockdep_map *lock)
 {
 	unsigned long flags;
 
@@ -2978,11 +3053,11 @@
 	raw_local_irq_save(flags);
 	check_flags(flags);
 	current->lockdep_recursion = 1;
-	__lock_acquired(lock);
+	__lock_note_acquired(lock, 0 __LOCKDEP_TS_NULL);
 	current->lockdep_recursion = 0;
 	raw_local_irq_restore(flags);
 }
-EXPORT_SYMBOL_GPL(lock_acquired);
+EXPORT_SYMBOL_GPL(lock_note_acquired);
 #endif
 
 /*
--- linux-2.6.24/kernel/lockdep_proc.c	2008-01-24 14:58:37.000000000 -0800
+++ linux-2.6.24.working/kernel/lockdep_proc.c	2008-03-13 00:08:32.000000000 -0700
@@ -418,9 +418,12 @@
 	seq_printf(m, " %14s", num);
 }
 
-static void seq_lock_time(struct seq_file *m, struct lock_time *lt)
+static void seq_lock_time(struct seq_file *m, struct lock_time *lt, int header, unsigned long spinnables, unsigned long steals)
 {
 	seq_printf(m, "%14lu", lt->nr);
+	if (header) {
+		seq_printf(m, " [%lu, %lu]", spinnables, steals);
+	}
 	seq_time(m, lt->min);
 	seq_time(m, lt->max);
 	seq_time(m, lt->total);
@@ -432,6 +435,7 @@
 	struct lock_class *class;
 	struct lock_class_stats *stats;
 	int i, namelen;
+	int spinnables = 1;
 
 	class = data->class;
 	stats = &data->stats;
@@ -468,18 +472,21 @@
 			seq_printf(m, "%40s:", name);
 
 		seq_printf(m, "%14lu ", stats->bounces[bounce_contended_write]);
-		seq_lock_time(m, &stats->write_waittime);
+		seq_lock_time(m, &stats->write_waittime, spinnables, stats->spinnable, stats->stolen);
+		if (spinnables) {
+			spinnables = 0;
+		}
 		seq_printf(m, " %14lu ", stats->bounces[bounce_acquired_write]);
-		seq_lock_time(m, &stats->write_holdtime);
+		seq_lock_time(m, &stats->write_holdtime, 0, 0, 0);
 		seq_puts(m, "\n");
 	}
 
 	if (stats->read_holdtime.nr) {
 		seq_printf(m, "%38s-R:", name);
 		seq_printf(m, "%14lu ", stats->bounces[bounce_contended_read]);
-		seq_lock_time(m, &stats->read_waittime);
+		seq_lock_time(m, &stats->read_waittime, spinnables, stats->spinnable, stats->stolen);
 		seq_printf(m, " %14lu ", stats->bounces[bounce_acquired_read]);
-		seq_lock_time(m, &stats->read_holdtime);
+		seq_lock_time(m, &stats->read_holdtime, 0, 0, 0);
 		seq_puts(m, "\n");
 	}
 
@@ -513,15 +520,22 @@
 	}
 }
 
+extern atomic_t spinnables_total, contentions_total, stolen_total;
+atomic_t cpu_range_error = {.counter = 0};
+
 static void seq_header(struct seq_file *m)
 {
 	seq_printf(m, "lock_stat version 0.2\n");
+	seq_printf(m, "spinnables_total = %u\n", atomic_read(&spinnables_total));
+	seq_printf(m, "contentions_total = %u\n", atomic_read(&contentions_total));
+	seq_printf(m, "stolen_total = %u\n", atomic_read(&stolen_total));
+	seq_printf(m, "cpu range error = %u\n", atomic_read(&cpu_range_error));
 	seq_line(m, '-', 0, 40 + 1 + 10 * (14 + 1));
 	seq_printf(m, "%40s %14s %14s %14s %14s %14s %14s %14s %14s "
 			"%14s %14s\n",
 			"class name",
 			"con-bounces",
-			"contentions",
+			"contentions [adapt,steals]",
 			"waittime-min",
 			"waittime-max",
 			"waittime-total",

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RT 4/6] lockstat measurement extensions
  2008-03-14  0:12     ` [PATCH RT 3/6] " Bill Huey (hui)
@ 2008-03-14  0:15       ` Bill Huey (hui)
  2008-03-14  0:18         ` [PATCH RT 5/6] " Bill Huey (hui)
  0 siblings, 1 reply; 9+ messages in thread
From: Bill Huey (hui) @ 2008-03-14  0:15 UTC (permalink / raw)
  To: Gregory Haskins, mingo
  Cc: a.p.zijlstra, tglx, rostedt, linux-rt-users, linux-kernel, kevin,
	cminyard, dsingleton, dwalker, npiggin, dsaxena, ak, pavel, acme,
	gregkh, sdietrich, pmorreale, mkohari

[-- Attachment #1: Type: text/plain, Size: 251 bytes --]

rtmutex.c push down of lock_note_contention()/lock_acquire() and new
functions lock_note_stolen() into the rtmutex.c common code itself
from LOCK_CONTENTION() top level macros. This is so that I can note
events at the specific points it occurs.

bill

[-- Attachment #2: patch3.diff --]
[-- Type: application/octet-stream, Size: 8804 bytes --]

--- linux-2.6.24/kernel/rtmutex.c	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/kernel/rtmutex.c	2008-03-12 01:07:45.000000000 -0700
@@ -318,7 +318,7 @@
  * assigned pending owner [which might not have taken the
  * lock yet]:
  */
-static inline int try_to_steal_lock(struct rt_mutex *lock)
+static inline int try_to_steal_lock(struct rt_mutex *lock __DEP_MAP_DECL)
 {
 	struct task_struct *pendowner = rt_mutex_owner(lock);
 	struct rt_mutex_waiter *next;
@@ -327,7 +327,7 @@
 		return 0;
 
 	if (pendowner == current)
-		return 1;
+		goto stolen;
 
 	spin_lock(&pendowner->pi_lock);
 	if (current->prio >= pendowner->prio) {
@@ -342,7 +342,7 @@
 	 */
 	if (likely(!rt_mutex_has_waiters(lock))) {
 		spin_unlock(&pendowner->pi_lock);
-		return 1;
+		goto stolen;
 	}
 
 	/* No chain handling, pending owner is not blocked on anything: */
@@ -356,7 +356,7 @@
 	 * enqueued on the pending owners pi_waiters queue. So
 	 * we have to enqueue this waiter into
 	 * current->pi_waiters list. This covers the case,
-	 * where current is boosted because it holds another
+	 * where current is priority boosted because it holds another
 	 * lock and gets unboosted because the booster is
 	 * interrupted, so we would delay a waiter with higher
 	 * priority as current->normal_prio.
@@ -371,6 +371,9 @@
 		__rt_mutex_adjust_prio(current);
 		spin_unlock(&current->pi_lock);
 	}
+
+stolen:
+	lock_note_stolen(DEP_MAP_PARAM);
 	return 1;
 }
 
@@ -383,7 +386,7 @@
  *
  * Must be called with lock->wait_lock held.
  */
-static int try_to_take_rt_mutex(struct rt_mutex *lock)
+static int try_to_take_rt_mutex(struct rt_mutex *lock __DEP_MAP_DECL)
 {
 	/*
 	 * We have to be careful here if the atomic speedups are
@@ -406,7 +409,7 @@
 	 */
 	mark_rt_mutex_waiters(lock);
 
-	if (rt_mutex_owner(lock) && !try_to_steal_lock(lock))
+	if (rt_mutex_owner(lock) && !try_to_steal_lock(lock __DEP_MAP_PARAM))
 		return 0;
 
 	/* We got the lock. */
@@ -631,7 +634,7 @@
 
 static inline void
 rt_spin_lock_fastlock(struct rt_mutex *lock,
-		void fastcall (*slowfn)(struct rt_mutex *lock))
+		void fastcall (*slowfn)(struct rt_mutex *lock __LOCKDEP_DECLS) __LOCKDEP_DECLS)
 {
 	/* Temporary HACK! */
 	if (!current->in_printk)
@@ -643,7 +646,7 @@
 	if (likely(rt_mutex_cmpxchg(lock, NULL, current)))
 		rt_mutex_deadlock_account_lock(lock, current);
 	else
-		slowfn(lock);
+		slowfn(lock __LOCKDEP_PARAMS);
 }
 
 static inline void
@@ -672,7 +675,7 @@
  * sleep/wakeup event loops.
  */
 static void fastcall noinline __sched
-rt_spin_lock_slowlock(struct rt_mutex *lock)
+rt_spin_lock_slowlock(struct rt_mutex *lock __LOCKDEP_DECLS)
 {
 	struct rt_mutex_waiter waiter;
 	unsigned long saved_state, state, flags;
@@ -680,13 +683,15 @@
 	debug_rt_mutex_init_waiter(&waiter);
 	waiter.task = NULL;
 
+	lock_note_contended(LOCKDEP_PARAMS);
+
 	spin_lock_irqsave(&lock->wait_lock, flags);
 	init_lists(lock);
 
 	/* Try to acquire the lock again: */
-	if (try_to_take_rt_mutex(lock)) {
+	if (try_to_take_rt_mutex(lock __DEP_MAP_PARAM)) {
 		spin_unlock_irqrestore(&lock->wait_lock, flags);
-		return;
+		goto acquired;
 	}
 
 	BUG_ON(rt_mutex_owner(lock) == current);
@@ -707,8 +712,9 @@
 		int saved_lock_depth = current->lock_depth;
 
 		/* Try to acquire the lock */
-		if (try_to_take_rt_mutex(lock))
+		if (try_to_take_rt_mutex(lock __DEP_MAP_PARAM))
 			break;
+
 		/*
 		 * waiter.task is NULL the first time we come here and
 		 * when we have been woken up by the previous owner
@@ -763,6 +769,9 @@
 	spin_unlock_irqrestore(&lock->wait_lock, flags);
 
 	debug_rt_mutex_free_waiter(&waiter);
+
+acquired:
+	lock_note_acquired(_dep_map);
 }
 
 /*
@@ -800,9 +809,9 @@
 }
 EXPORT_SYMBOL(rt_spin_lock);
 
-void __lockfunc __rt_spin_lock(struct rt_mutex *lock)
+void __lockfunc __rt_spin_lock(struct rt_mutex *lock __LOCKDEP_DECLS)
 {
-	rt_spin_lock_fastlock(lock, rt_spin_lock_slowlock);
+	rt_spin_lock_fastlock(lock, rt_spin_lock_slowlock __LOCKDEP_PARAMS);
 }
 EXPORT_SYMBOL(__rt_spin_lock);
 
@@ -934,7 +943,8 @@
 static int __sched
 rt_mutex_slowlock(struct rt_mutex *lock, int state,
 		  struct hrtimer_sleeper *timeout,
-		  int detect_deadlock)
+		  int detect_deadlock
+		  __LOCKDEP_DECLS)
 {
 	int ret = 0, saved_lock_depth = -1;
 	struct rt_mutex_waiter waiter;
@@ -943,13 +953,16 @@
 	debug_rt_mutex_init_waiter(&waiter);
 	waiter.task = NULL;
 
+	lock_note_contended(LOCKDEP_PARAMS);
+
 	spin_lock_irqsave(&lock->wait_lock, flags);
 	init_lists(lock);
 
 	/* Try to acquire the lock again: */
-	if (try_to_take_rt_mutex(lock)) {
+	if (try_to_take_rt_mutex(lock __DEP_MAP_PARAM)) {
 		spin_unlock_irqrestore(&lock->wait_lock, flags);
-		return 0;
+		ret = 0;
+		goto acquired;
 	}
 
 	/*
@@ -970,8 +983,9 @@
 		unsigned long saved_flags;
 
 		/* Try to acquire the lock: */
-		if (try_to_take_rt_mutex(lock))
+		if (try_to_take_rt_mutex(lock __DEP_MAP_PARAM)) {
 			break;
+		}
 
 		/*
 		 * TASK_INTERRUPTIBLE checks for signals and
@@ -1060,6 +1074,9 @@
 
 	debug_rt_mutex_free_waiter(&waiter);
 
+acquired:
+	lock_note_acquired(_dep_map);
+
 	return ret;
 }
 
@@ -1067,7 +1084,7 @@
  * Slow path try-lock function:
  */
 static inline int
-rt_mutex_slowtrylock(struct rt_mutex *lock)
+rt_mutex_slowtrylock(struct rt_mutex *lock __LOCKDEP_DECLS)
 {
 	unsigned long flags;
 	int ret = 0;
@@ -1078,7 +1095,10 @@
 
 		init_lists(lock);
 
-		ret = try_to_take_rt_mutex(lock);
+		lock_note_contended(LOCKDEP_PARAMS);
+
+		ret = try_to_take_rt_mutex(lock __DEP_MAP_PARAM);
+
 		/*
 		 * try_to_take_rt_mutex() sets the lock waiters
 		 * bit unconditionally. Clean this up.
@@ -1088,6 +1108,9 @@
 
 	spin_unlock_irqrestore(&lock->wait_lock, flags);
 
+	if (!ret)
+		lock_note_acquired(_dep_map);
+
 	return ret;
 }
 
@@ -1130,13 +1153,13 @@
 		  int detect_deadlock,
 		  int (*slowfn)(struct rt_mutex *lock, int state,
 				struct hrtimer_sleeper *timeout,
-				int detect_deadlock))
+				int detect_deadlock __LOCKDEP_DECLS) __LOCKDEP_DECLS)
 {
 	if (!detect_deadlock && likely(rt_mutex_cmpxchg(lock, NULL, current))) {
 		rt_mutex_deadlock_account_lock(lock, current);
 		return 0;
 	} else
-		return slowfn(lock, state, NULL, detect_deadlock);
+		return slowfn(lock, state, NULL, detect_deadlock __LOCKDEP_PARAMS);
 }
 
 static inline int
@@ -1144,24 +1167,24 @@
 			struct hrtimer_sleeper *timeout, int detect_deadlock,
 			int (*slowfn)(struct rt_mutex *lock, int state,
 				      struct hrtimer_sleeper *timeout,
-				      int detect_deadlock))
+				      int detect_deadlock __LOCKDEP_DECLS) __LOCKDEP_DECLS)
 {
 	if (!detect_deadlock && likely(rt_mutex_cmpxchg(lock, NULL, current))) {
 		rt_mutex_deadlock_account_lock(lock, current);
 		return 0;
 	} else
-		return slowfn(lock, state, timeout, detect_deadlock);
+		return slowfn(lock, state, timeout, detect_deadlock __LOCKDEP_PARAMS);
 }
 
 static inline int
 rt_mutex_fasttrylock(struct rt_mutex *lock,
-		     int (*slowfn)(struct rt_mutex *lock))
+		     int (*slowfn)(struct rt_mutex *lock __LOCKDEP_DECLS) __LOCKDEP_DECLS)
 {
 	if (likely(rt_mutex_cmpxchg(lock, NULL, current))) {
 		rt_mutex_deadlock_account_lock(lock, current);
 		return 1;
 	}
-	return slowfn(lock);
+	return slowfn(lock __LOCKDEP_PARAMS);
 }
 
 static inline void
@@ -1179,11 +1202,11 @@
  *
  * @lock: the rt_mutex to be locked
  */
-void __sched rt_mutex_lock(struct rt_mutex *lock)
+void __sched rt_mutex_lock(struct rt_mutex *lock __LOCKDEP_DECLS)
 {
 	might_sleep();
 
-	rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, 0, rt_mutex_slowlock);
+	rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, 0, rt_mutex_slowlock __LOCKDEP_PARAMS);
 }
 EXPORT_SYMBOL_GPL(rt_mutex_lock);
 
@@ -1199,12 +1222,12 @@
  * -EDEADLK	when the lock would deadlock (when deadlock detection is on)
  */
 int __sched rt_mutex_lock_interruptible(struct rt_mutex *lock,
-						 int detect_deadlock)
+						 int detect_deadlock __LOCKDEP_DECLS)
 {
 	might_sleep();
 
 	return rt_mutex_fastlock(lock, TASK_INTERRUPTIBLE,
-				 detect_deadlock, rt_mutex_slowlock);
+				 detect_deadlock, rt_mutex_slowlock __LOCKDEP_PARAMS);
 }
 EXPORT_SYMBOL_GPL(rt_mutex_lock_interruptible);
 
@@ -1230,7 +1253,7 @@
 	might_sleep();
 
 	return rt_mutex_timed_fastlock(lock, TASK_INTERRUPTIBLE, timeout,
-				       detect_deadlock, rt_mutex_slowlock);
+				       detect_deadlock, rt_mutex_slowlock __LOCKDEP_PARAMS_L0);
 }
 EXPORT_SYMBOL_GPL(rt_mutex_timed_lock);
 
@@ -1241,9 +1264,14 @@
  *
  * Returns 1 on success and 0 on contention
  */
+int __rt_mutex_trylock(struct rt_mutex *lock __LOCKDEP_DECLS)
+{
+	return rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock __LOCKDEP_PARAMS);
+}
+
 int __sched rt_mutex_trylock(struct rt_mutex *lock)
 {
-	return rt_mutex_fasttrylock(lock, rt_mutex_slowtrylock);
+	return __rt_mutex_trylock(lock __LOCKDEP_PARAMS_L0);
 }
 EXPORT_SYMBOL_GPL(rt_mutex_trylock);
 

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RT 5/6] lockstat measurement extensions
  2008-03-14  0:15       ` [PATCH RT 4/6] " Bill Huey (hui)
@ 2008-03-14  0:18         ` Bill Huey (hui)
  2008-03-14  0:19           ` [PATCH RT 6/6] " Bill Huey (hui)
  0 siblings, 1 reply; 9+ messages in thread
From: Bill Huey (hui) @ 2008-03-14  0:18 UTC (permalink / raw)
  To: Gregory Haskins, mingo
  Cc: a.p.zijlstra, tglx, rostedt, linux-rt-users, linux-kernel, kevin,
	cminyard, dsingleton, dwalker, npiggin, dsaxena, ak, pavel, acme,
	gregkh, sdietrich, pmorreale, mkohari

[-- Attachment #1: Type: text/plain, Size: 110 bytes --]

Lock function bodies are extended to pass down a struct lockdep_map
and friends for contention logging.

bill

[-- Attachment #2: patch4.diff --]
[-- Type: application/octet-stream, Size: 10929 bytes --]

--- linux-2.6.24/kernel/rt.c	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/kernel/rt.c	2008-03-12 22:40:09.000000000 -0700
@@ -102,9 +102,9 @@
 }
 EXPORT_SYMBOL(_mutex_lock);
 
-static int __lockfunc __rt_mutex_lock_interruptible(struct rt_mutex *lock)
+static int __lockfunc __rt_mutex_lock_interruptible(struct rt_mutex *lock __LOCKDEP_DECLS)
 {
-	return rt_mutex_lock_interruptible(lock, 0);
+	return rt_mutex_lock_interruptible(lock, 0 __LOCKDEP_PARAMS);
 }
 
 int __lockfunc _mutex_lock_interruptible(struct mutex *lock)
@@ -144,7 +144,7 @@
 
 int __lockfunc _mutex_trylock(struct mutex *lock)
 {
-	int ret = rt_mutex_trylock(&lock->lock);
+	int ret = __rt_mutex_trylock(&lock->lock __LOCKDEP_PARAMS_L0);
 
 	if (ret)
 		mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_);
@@ -163,21 +163,28 @@
 /*
  * rwlock_t functions
  */
-int __lockfunc rt_write_trylock(rwlock_t *rwlock)
+static
+int __lockfunc __rt_write_trylock(rwlock_t *rwlock __LOCKDEP_DECLS)
 {
-	int ret = rt_mutex_trylock(&rwlock->lock);
+	//int ret = __rt_mutex_trylock(&rwlock->lock __LOCKDEP_PARAMS);
+	int ret = __rt_mutex_trylock(&rwlock->lock, rt_mutex_real_owner(&rwlock->lock), _dep_map, _ip);
 
 	if (ret)
 		rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_);
 
 	return ret;
 }
+
+int __lockfunc rt_write_trylock(rwlock_t *rwlock)
+{
+	return __rt_write_trylock(rwlock __LOCKDEP_PARAMS_L0);
+}
 EXPORT_SYMBOL(rt_write_trylock);
 
 int __lockfunc rt_write_trylock_irqsave(rwlock_t *rwlock, unsigned long *flags)
 {
 	*flags = 0;
-	return rt_write_trylock(rwlock);
+	return __rt_write_trylock(rwlock __LOCKDEP_PARAMS_L0);
 }
 EXPORT_SYMBOL(rt_write_trylock_irqsave);
 
@@ -453,7 +460,7 @@
 
 void fastcall rt_down(struct semaphore *sem)
 {
-	rt_mutex_lock(&sem->lock);
+	rt_mutex_lock(&sem->lock __LOCKDEP_PARAMS_SEM(sem));
 	__down_complete(sem);
 }
 EXPORT_SYMBOL(rt_down);
@@ -462,7 +469,7 @@
 {
 	int ret;
 
-	ret = rt_mutex_lock_interruptible(&sem->lock, 0);
+	ret = rt_mutex_lock_interruptible(&sem->lock, 0 __LOCKDEP_PARAMS_SEM(sem));
 	if (ret)
 		return ret;
 	__down_complete(sem);
@@ -516,7 +523,7 @@
 	switch (val) {
 	case 0:
 		__rt_mutex_init(&sem->lock, name);
-		rt_mutex_lock(&sem->lock);
+		rt_mutex_lock(&sem->lock __LOCKDEP_PARAMS_SEM(sem));
 		break;
 	default:
 		__rt_mutex_init(&sem->lock, name);
--- linux-2.6.24/kernel/mutex.c	2008-01-24 14:58:37.000000000 -0800
+++ linux-2.6.24.working/kernel/mutex.c	2008-03-13 13:03:06.000000000 -0700
@@ -146,7 +146,7 @@
 	if (old_val == 1)
 		goto done;
 
-	lock_contended(&lock->dep_map, ip);
+//	lock_note_contended(LOCKDEP_PARAMS);
 
 	for (;;) {
 		/*
@@ -184,7 +184,7 @@
 	}
 
 done:
-	lock_acquired(&lock->dep_map);
+//	lock_acquired(&lock->dep_map);
 	/* got the lock - rejoice! */
 	mutex_remove_waiter(lock, &waiter, task_thread_info(task));
 	debug_mutex_set_owner(lock, task_thread_info(task));
--- linux-2.6.24/kernel/rwsem.c	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/kernel/rwsem.c	2008-03-11 02:45:20.000000000 -0700
@@ -21,7 +21,7 @@
 	might_sleep();
 	rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_);
 
-	LOCK_CONTENDED(sem, __down_read_trylock, __down_read);
+	LOCK_CONTENDED_COMPAT(sem, __down_read_trylock, __down_read);
 }
 
 EXPORT_SYMBOL(compat_down_read);
@@ -48,7 +48,7 @@
 	might_sleep();
 	rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
 
-	LOCK_CONTENDED(sem, __down_write_trylock, __down_write);
+	LOCK_CONTENDED_COMPAT(sem, __down_write_trylock, __down_write);
 }
 
 EXPORT_SYMBOL(compat_down_write);
@@ -112,7 +112,7 @@
 	might_sleep();
 	rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_);
 
-	LOCK_CONTENDED(sem, __down_read_trylock, __down_read);
+	LOCK_CONTENDED_COMPAT(sem, __down_read_trylock, __down_read);
 }
 
 EXPORT_SYMBOL(compat_down_read_nested);
@@ -131,7 +131,7 @@
 	might_sleep();
 	rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_);
 
-	LOCK_CONTENDED(sem, __down_write_trylock, __down_write);
+	LOCK_CONTENDED_COMPAT(sem, __down_write_trylock, __down_write);
 }
 
 EXPORT_SYMBOL(compat_down_write_nested);
--- linux-2.6.24/kernel/rt.c	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/kernel/rt.c	2008-03-12 22:40:09.000000000 -0700
@@ -102,9 +102,9 @@
 }
 EXPORT_SYMBOL(_mutex_lock);
 
-static int __lockfunc __rt_mutex_lock_interruptible(struct rt_mutex *lock)
+static int __lockfunc __rt_mutex_lock_interruptible(struct rt_mutex *lock __LOCKDEP_DECLS)
 {
-	return rt_mutex_lock_interruptible(lock, 0);
+	return rt_mutex_lock_interruptible(lock, 0 __LOCKDEP_PARAMS);
 }
 
 int __lockfunc _mutex_lock_interruptible(struct mutex *lock)
@@ -144,7 +144,7 @@
 
 int __lockfunc _mutex_trylock(struct mutex *lock)
 {
-	int ret = rt_mutex_trylock(&lock->lock);
+	int ret = __rt_mutex_trylock(&lock->lock __LOCKDEP_PARAMS_L0);
 
 	if (ret)
 		mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_);
@@ -163,21 +163,28 @@
 /*
  * rwlock_t functions
  */
-int __lockfunc rt_write_trylock(rwlock_t *rwlock)
+static
+int __lockfunc __rt_write_trylock(rwlock_t *rwlock __LOCKDEP_DECLS)
 {
-	int ret = rt_mutex_trylock(&rwlock->lock);
+	//int ret = __rt_mutex_trylock(&rwlock->lock __LOCKDEP_PARAMS);
+	int ret = __rt_mutex_trylock(&rwlock->lock, rt_mutex_real_owner(&rwlock->lock), _dep_map, _ip);
 
 	if (ret)
 		rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_);
 
 	return ret;
 }
+
+int __lockfunc rt_write_trylock(rwlock_t *rwlock)
+{
+	return __rt_write_trylock(rwlock __LOCKDEP_PARAMS_L0);
+}
 EXPORT_SYMBOL(rt_write_trylock);
 
 int __lockfunc rt_write_trylock_irqsave(rwlock_t *rwlock, unsigned long *flags)
 {
 	*flags = 0;
-	return rt_write_trylock(rwlock);
+	return __rt_write_trylock(rwlock __LOCKDEP_PARAMS_L0);
 }
 EXPORT_SYMBOL(rt_write_trylock_irqsave);
 
@@ -453,7 +460,7 @@
 
 void fastcall rt_down(struct semaphore *sem)
 {
-	rt_mutex_lock(&sem->lock);
+	rt_mutex_lock(&sem->lock __LOCKDEP_PARAMS_SEM(sem));
 	__down_complete(sem);
 }
 EXPORT_SYMBOL(rt_down);
@@ -462,7 +469,7 @@
 {
 	int ret;
 
-	ret = rt_mutex_lock_interruptible(&sem->lock, 0);
+	ret = rt_mutex_lock_interruptible(&sem->lock, 0 __LOCKDEP_PARAMS_SEM(sem));
 	if (ret)
 		return ret;
 	__down_complete(sem);
@@ -516,7 +523,7 @@
 	switch (val) {
 	case 0:
 		__rt_mutex_init(&sem->lock, name);
-		rt_mutex_lock(&sem->lock);
+		rt_mutex_lock(&sem->lock __LOCKDEP_PARAMS_SEM(sem));
 		break;
 	default:
 		__rt_mutex_init(&sem->lock, name);
--- linux-2.6.24/kernel/mutex.c	2008-01-24 14:58:37.000000000 -0800
+++ linux-2.6.24.working/kernel/mutex.c	2008-03-13 13:03:06.000000000 -0700
@@ -146,7 +146,7 @@
 	if (old_val == 1)
 		goto done;
 
-	lock_contended(&lock->dep_map, ip);
+//	lock_note_contended(LOCKDEP_PARAMS);
 
 	for (;;) {
 		/*
@@ -184,7 +184,7 @@
 	}
 
 done:
-	lock_acquired(&lock->dep_map);
+//	lock_acquired(&lock->dep_map);
 	/* got the lock - rejoice! */
 	mutex_remove_waiter(lock, &waiter, task_thread_info(task));
 	debug_mutex_set_owner(lock, task_thread_info(task));
--- linux-2.6.24/kernel/rwsem.c	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/kernel/rwsem.c	2008-03-11 02:45:20.000000000 -0700
@@ -21,7 +21,7 @@
 	might_sleep();
 	rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_);
 
-	LOCK_CONTENDED(sem, __down_read_trylock, __down_read);
+	LOCK_CONTENDED_COMPAT(sem, __down_read_trylock, __down_read);
 }
 
 EXPORT_SYMBOL(compat_down_read);
@@ -48,7 +48,7 @@
 	might_sleep();
 	rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
 
-	LOCK_CONTENDED(sem, __down_write_trylock, __down_write);
+	LOCK_CONTENDED_COMPAT(sem, __down_write_trylock, __down_write);
 }
 
 EXPORT_SYMBOL(compat_down_write);
@@ -112,7 +112,7 @@
 	might_sleep();
 	rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_);
 
-	LOCK_CONTENDED(sem, __down_read_trylock, __down_read);
+	LOCK_CONTENDED_COMPAT(sem, __down_read_trylock, __down_read);
 }
 
 EXPORT_SYMBOL(compat_down_read_nested);
@@ -131,7 +131,7 @@
 	might_sleep();
 	rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_);
 
-	LOCK_CONTENDED(sem, __down_write_trylock, __down_write);
+	LOCK_CONTENDED_COMPAT(sem, __down_write_trylock, __down_write);
 }
 
 EXPORT_SYMBOL(compat_down_write_nested);
--- linux-2.6.24/kernel/rt.c	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/kernel/rt.c	2008-03-12 22:40:09.000000000 -0700
@@ -102,9 +102,9 @@
 }
 EXPORT_SYMBOL(_mutex_lock);
 
-static int __lockfunc __rt_mutex_lock_interruptible(struct rt_mutex *lock)
+static int __lockfunc __rt_mutex_lock_interruptible(struct rt_mutex *lock __LOCKDEP_DECLS)
 {
-	return rt_mutex_lock_interruptible(lock, 0);
+	return rt_mutex_lock_interruptible(lock, 0 __LOCKDEP_PARAMS);
 }
 
 int __lockfunc _mutex_lock_interruptible(struct mutex *lock)
@@ -144,7 +144,7 @@
 
 int __lockfunc _mutex_trylock(struct mutex *lock)
 {
-	int ret = rt_mutex_trylock(&lock->lock);
+	int ret = __rt_mutex_trylock(&lock->lock __LOCKDEP_PARAMS_L0);
 
 	if (ret)
 		mutex_acquire(&lock->dep_map, 0, 1, _RET_IP_);
@@ -163,21 +163,28 @@
 /*
  * rwlock_t functions
  */
-int __lockfunc rt_write_trylock(rwlock_t *rwlock)
+static
+int __lockfunc __rt_write_trylock(rwlock_t *rwlock __LOCKDEP_DECLS)
 {
-	int ret = rt_mutex_trylock(&rwlock->lock);
+	//int ret = __rt_mutex_trylock(&rwlock->lock __LOCKDEP_PARAMS);
+	int ret = __rt_mutex_trylock(&rwlock->lock, rt_mutex_real_owner(&rwlock->lock), _dep_map, _ip);
 
 	if (ret)
 		rwlock_acquire(&rwlock->dep_map, 0, 1, _RET_IP_);
 
 	return ret;
 }
+
+int __lockfunc rt_write_trylock(rwlock_t *rwlock)
+{
+	return __rt_write_trylock(rwlock __LOCKDEP_PARAMS_L0);
+}
 EXPORT_SYMBOL(rt_write_trylock);
 
 int __lockfunc rt_write_trylock_irqsave(rwlock_t *rwlock, unsigned long *flags)
 {
 	*flags = 0;
-	return rt_write_trylock(rwlock);
+	return __rt_write_trylock(rwlock __LOCKDEP_PARAMS_L0);
 }
 EXPORT_SYMBOL(rt_write_trylock_irqsave);
 
@@ -453,7 +460,7 @@
 
 void fastcall rt_down(struct semaphore *sem)
 {
-	rt_mutex_lock(&sem->lock);
+	rt_mutex_lock(&sem->lock __LOCKDEP_PARAMS_SEM(sem));
 	__down_complete(sem);
 }
 EXPORT_SYMBOL(rt_down);
@@ -462,7 +469,7 @@
 {
 	int ret;
 
-	ret = rt_mutex_lock_interruptible(&sem->lock, 0);
+	ret = rt_mutex_lock_interruptible(&sem->lock, 0 __LOCKDEP_PARAMS_SEM(sem));
 	if (ret)
 		return ret;
 	__down_complete(sem);
@@ -516,7 +523,7 @@
 	switch (val) {
 	case 0:
 		__rt_mutex_init(&sem->lock, name);
-		rt_mutex_lock(&sem->lock);
+		rt_mutex_lock(&sem->lock __LOCKDEP_PARAMS_SEM(sem));
 		break;
 	default:
 		__rt_mutex_init(&sem->lock, name);
--- linux-2.6.24/kernel/mutex.c	2008-01-24 14:58:37.000000000 -0800
+++ linux-2.6.24.working/kernel/mutex.c	2008-03-13 13:03:06.000000000 -0700
@@ -146,7 +146,7 @@
 	if (old_val == 1)
 		goto done;
 
-	lock_contended(&lock->dep_map, ip);
+//	lock_note_contended(LOCKDEP_PARAMS);
 
 	for (;;) {
 		/*
@@ -184,7 +184,7 @@
 	}
 
 done:
-	lock_acquired(&lock->dep_map);
+//	lock_acquired(&lock->dep_map);
 	/* got the lock - rejoice! */
 	mutex_remove_waiter(lock, &waiter, task_thread_info(task));
 	debug_mutex_set_owner(lock, task_thread_info(task));

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RT 6/6] lockstat measurement extensions
  2008-03-14  0:18         ` [PATCH RT 5/6] " Bill Huey (hui)
@ 2008-03-14  0:19           ` Bill Huey (hui)
  0 siblings, 0 replies; 9+ messages in thread
From: Bill Huey (hui) @ 2008-03-14  0:19 UTC (permalink / raw)
  To: Gregory Haskins, mingo
  Cc: a.p.zijlstra, tglx, rostedt, linux-rt-users, linux-kernel, kevin,
	cminyard, dsingleton, dwalker, npiggin, dsaxena, ak, pavel, acme,
	gregkh, sdietrich, pmorreale, mkohari

Last one. Spin checking against the rtmutex->owner's run queue to
determine if an adaptive spin or not is useful.

bill

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RT 0/6] lockstat measurement extensions
  2008-03-14  0:03 [PATCH RT 0/6] lockstat measurement extensions Bill Huey (hui)
  2008-03-14  0:07 ` [PATCH RT 1/6] " Bill Huey (hui)
@ 2008-03-14  0:26 ` Bill Huey (hui)
  2008-03-14  0:40   ` Bill Huey (hui)
  1 sibling, 1 reply; 9+ messages in thread
From: Bill Huey (hui) @ 2008-03-14  0:26 UTC (permalink / raw)
  To: Gregory Haskins, mingo
  Cc: a.p.zijlstra, tglx, rostedt, linux-rt-users, linux-kernel, kevin,
	cminyard, dsingleton, dwalker, npiggin, dsaxena, ak, pavel, acme,
	gregkh, sdietrich, pmorreale, mkohari

Also, this is not meant for inclusion in it's current revision. It'll
need to have various compilation modes
(CONFIG_PREEMPT_RT/CONFIG_LOCK_STAT) combination enabled and such. I'm
handing this over to Peter Morreale and it'll be up to him to decided
what to do next.

However, it does work and should get interesting numbers for the
discussion of whether or not adaptive spins and friends are useful or
not.

bill

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH RT 0/6] lockstat measurement extensions
  2008-03-14  0:26 ` [PATCH RT 0/6] " Bill Huey (hui)
@ 2008-03-14  0:40   ` Bill Huey (hui)
  0 siblings, 0 replies; 9+ messages in thread
From: Bill Huey (hui) @ 2008-03-14  0:40 UTC (permalink / raw)
  To: Gregory Haskins, mingo
  Cc: a.p.zijlstra, tglx, rostedt, linux-rt-users, linux-kernel, kevin,
	cminyard, dsingleton, dwalker, npiggin, dsaxena, ak, pavel, acme,
	gregkh, sdietrich, pmorreale, mkohari

Sorry missing the patch. At Thomas's urging, this is inlined:

--- linux-2.6.24/kernel/sched.c	2008-02-25 15:32:05.000000000 -0800
+++ linux-2.6.24.working/kernel/sched.c	2008-03-13 13:53:24.000000000 -0700
@@ -1175,6 +1175,20 @@
 	return cpu_curr(task_cpu(p)) == p;
 }

+int task_spinnable(struct task_struct *p)
+{
+/*
+ * The use of task_curr can crash the system since the struct
thread_info seems
+ * to disappear when dereferenced arbitrarily, so becareful.
+ */
+#ifdef CONFIG_SMP
+	if (p && p->se.on_rq && task_curr(p))
+		return 1;
+#else
+	return 0;
+#endif
+}
+
 /* Used instead of source_load when we know the type == 0 */
 unsigned long weighted_cpuload(const int cpu)
 {
@@ -1239,6 +1253,11 @@
 		      *new_cfsrq = cpu_cfs_rq(old_cfsrq, new_cpu);
 	u64 clock_offset;

+//--billh
+//	if (old_cpu >= NR_CPUS)
+//		panic("bogus cpu id %u\n", old_cpu);
+//
+//
 	clock_offset = old_rq->clock - new_rq->clock;

 #ifdef CONFIG_SCHEDSTATS

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2008-03-14  0:40 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-14  0:03 [PATCH RT 0/6] lockstat measurement extensions Bill Huey (hui)
2008-03-14  0:07 ` [PATCH RT 1/6] " Bill Huey (hui)
2008-03-14  0:09   ` [PATCH RT 2/6] " Bill Huey (hui)
2008-03-14  0:12     ` [PATCH RT 3/6] " Bill Huey (hui)
2008-03-14  0:15       ` [PATCH RT 4/6] " Bill Huey (hui)
2008-03-14  0:18         ` [PATCH RT 5/6] " Bill Huey (hui)
2008-03-14  0:19           ` [PATCH RT 6/6] " Bill Huey (hui)
2008-03-14  0:26 ` [PATCH RT 0/6] " Bill Huey (hui)
2008-03-14  0:40   ` Bill Huey (hui)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®