linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/11] lockdep: LD_PRELOAD support
@ 2013-02-06 22:11 Sasha Levin
  2013-02-06 22:11 ` [PATCH 01/11] liblockdep: remove the need for liblockdep_init Sasha Levin
                   ` (11 more replies)
  0 siblings, 12 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

This patch series adds in LD_PRELOAD support for liblockdep.

We store lockdep_map in an rb-tree and hook the pthread_mutex/
pthread_rwlock calls, allowing us to add lockdep testing on
any program without touching it's source code.

The first couple of patches remove the need for lockdep_init
and lockdep_set_thread, as well as some fixes for several
tests.

The other patches add rbtree and LD_PRELOAD support, along
with testing for that.

The last patch adds a small script that wraps all of it, making
testing really simple:

	liblockdep perf [perf command line]

There is a case where it won't work well: some programs, such
as firefox, hook malloc() and add a pthread_mutex lock in the
allocation path, which recurses back into our liblockdep code.

To solve that I'm planning to add a local cache to allocate
from when liblockdep detects recursion onto itself, but that's
outside of the scope of this patch.

Instead of taking the perf in this series another option would
be to just revert the existing perf patch from me in core/locking,
which would mean perf would just work with the new LD_PRELOAD
feature.


Sasha Levin (11):
  liblockdep: remove the need for liblockdep_init
  liblockdep: remove the need for liblockdep_set_thread
  perf: stop using liblockdep_init and liblockdep_set_thread
  liblockdep: fix AA test
  liblockdep: correct the ABCDBCDA test
  liblockdep: rbtree support
  liblockdep: prevent multiple declarations of CALLER_ADDR0
  liblockdep: keep headers declarations even if lib is disabled
  liblockdep: support using LD_PRELOAD
  liblockdep: add tests for the LD_PRELOAD feature
  liblockdep: preload helper

 tools/lib/lockdep/Makefile                         |  16 +-
 tools/lib/lockdep/common.c                         |  10 +-
 tools/lib/lockdep/include/liblockdep/common.h      |   5 +-
 tools/lib/lockdep/include/liblockdep/mutex.h       |   4 +-
 tools/lib/lockdep/include/liblockdep/rwlock.h      |   4 +-
 tools/lib/lockdep/lockdep                          |   3 +
 tools/lib/lockdep/preload.c                        | 184 +++++++++++++++++++++
 tools/lib/lockdep/rbtree.c                         |   1 +
 tools/lib/lockdep/run_tests.sh                     |  12 ++
 tools/lib/lockdep/tests/AA.c                       |   5 +-
 tools/lib/lockdep/tests/ABBA.c                     |   3 -
 tools/lib/lockdep/tests/ABBCCA.c                   |   3 -
 tools/lib/lockdep/tests/ABBCCDDA.c                 |   3 -
 tools/lib/lockdep/tests/ABCABC.c                   |   3 -
 tools/lib/lockdep/tests/ABCDBCDA.c                 |  13 +-
 tools/lib/lockdep/tests/ABCDBDDA.c                 |   3 -
 tools/lib/lockdep/tests/WW.c                       |   3 -
 tools/lib/lockdep/tests/unlock_balance.c           |   3 -
 tools/lib/lockdep/uinclude/linux/kernel.h          |   2 +
 tools/lib/lockdep/uinclude/linux/lockdep.h         |   5 +-
 tools/lib/lockdep/uinclude/linux/rbtree.h          |   1 +
 .../lib/lockdep/uinclude/linux/rbtree_augmented.h  |   2 +
 tools/perf/builtin-sched.c                         |   2 -
 tools/perf/builtin-top.c                           |   4 -
 tools/perf/config/feature-tests.mak                |   1 -
 tools/perf/perf.c                                  |   3 -
 tools/perf/util/liblockdep.h                       |   2 -
 27 files changed, 236 insertions(+), 64 deletions(-)
 create mode 100755 tools/lib/lockdep/lockdep
 create mode 100644 tools/lib/lockdep/preload.c
 create mode 100644 tools/lib/lockdep/rbtree.c
 create mode 100644 tools/lib/lockdep/uinclude/linux/rbtree.h
 create mode 100644 tools/lib/lockdep/uinclude/linux/rbtree_augmented.h

-- 
1.8.1.2


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

* [PATCH 01/11] liblockdep: remove the need for liblockdep_init
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
@ 2013-02-06 22:11 ` Sasha Levin
  2013-02-06 22:11 ` [PATCH 02/11] liblockdep: remove the need for liblockdep_set_thread Sasha Levin
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

Use a constructor in the library instead of making the user manually
call liblockdep_init().

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 tools/lib/lockdep/common.c                    | 2 +-
 tools/lib/lockdep/include/liblockdep/common.h | 1 -
 tools/lib/lockdep/tests/AA.c                  | 1 -
 tools/lib/lockdep/tests/ABBA.c                | 1 -
 tools/lib/lockdep/tests/ABBCCA.c              | 1 -
 tools/lib/lockdep/tests/ABBCCDDA.c            | 1 -
 tools/lib/lockdep/tests/ABCABC.c              | 1 -
 tools/lib/lockdep/tests/ABCDBCDA.c            | 1 -
 tools/lib/lockdep/tests/ABCDBDDA.c            | 1 -
 tools/lib/lockdep/tests/WW.c                  | 1 -
 tools/lib/lockdep/tests/unlock_balance.c      | 1 -
 tools/lib/lockdep/uinclude/linux/lockdep.h    | 1 -
 12 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/tools/lib/lockdep/common.c b/tools/lib/lockdep/common.c
index 99d3b4b..d2946e0 100644
--- a/tools/lib/lockdep/common.c
+++ b/tools/lib/lockdep/common.c
@@ -10,7 +10,7 @@ __thread struct task_struct current_obj;
 bool debug_locks = true;
 bool debug_locks_silent;
 
-void liblockdep_init(void)
+__attribute__((constructor)) static void liblockdep_init(void)
 {
 	lockdep_init();
 }
diff --git a/tools/lib/lockdep/include/liblockdep/common.h b/tools/lib/lockdep/include/liblockdep/common.h
index b72f9c1..f6f7fec8 100644
--- a/tools/lib/lockdep/include/liblockdep/common.h
+++ b/tools/lib/lockdep/include/liblockdep/common.h
@@ -26,7 +26,6 @@ struct lockdep_map {
 #endif
 };
 
-void liblockdep_init(void);
 void liblockdep_set_thread(void);
 void lockdep_init_map(struct lockdep_map *lock, const char *name,
 			struct lock_class_key *key, int subclass);
diff --git a/tools/lib/lockdep/tests/AA.c b/tools/lib/lockdep/tests/AA.c
index 933d32f..3f71333 100644
--- a/tools/lib/lockdep/tests/AA.c
+++ b/tools/lib/lockdep/tests/AA.c
@@ -4,7 +4,6 @@ void main(void)
 {
 	pthread_mutex_t a, b;
 
-	liblockdep_init();
 	liblockdep_set_thread();
 
 	pthread_mutex_init(&a, NULL);
diff --git a/tools/lib/lockdep/tests/ABBA.c b/tools/lib/lockdep/tests/ABBA.c
index 9f5146b..08d87a7 100644
--- a/tools/lib/lockdep/tests/ABBA.c
+++ b/tools/lib/lockdep/tests/ABBA.c
@@ -5,7 +5,6 @@ void main(void)
 {
 	pthread_mutex_t a, b;
 
-	liblockdep_init();
 	liblockdep_set_thread();
 
 	pthread_mutex_init(&a, NULL);
diff --git a/tools/lib/lockdep/tests/ABBCCA.c b/tools/lib/lockdep/tests/ABBCCA.c
index b7435d7..c5d0e5c 100644
--- a/tools/lib/lockdep/tests/ABBCCA.c
+++ b/tools/lib/lockdep/tests/ABBCCA.c
@@ -5,7 +5,6 @@ void main(void)
 {
 	pthread_mutex_t a, b, c;
 
-	liblockdep_init();
 	liblockdep_set_thread();
 
 	pthread_mutex_init(&a, NULL);
diff --git a/tools/lib/lockdep/tests/ABBCCDDA.c b/tools/lib/lockdep/tests/ABBCCDDA.c
index 2425330..e12dc98 100644
--- a/tools/lib/lockdep/tests/ABBCCDDA.c
+++ b/tools/lib/lockdep/tests/ABBCCDDA.c
@@ -5,7 +5,6 @@ void main(void)
 {
 	pthread_mutex_t a, b, c, d;
 
-	liblockdep_init();
 	liblockdep_set_thread();
 
 	pthread_mutex_init(&a, NULL);
diff --git a/tools/lib/lockdep/tests/ABCABC.c b/tools/lib/lockdep/tests/ABCABC.c
index 2ee30fe..70879c95 100644
--- a/tools/lib/lockdep/tests/ABCABC.c
+++ b/tools/lib/lockdep/tests/ABCABC.c
@@ -5,7 +5,6 @@ void main(void)
 {
 	pthread_mutex_t a, b, c;
 
-	liblockdep_init();
 	liblockdep_set_thread();
 
 	pthread_mutex_init(&a, NULL);
diff --git a/tools/lib/lockdep/tests/ABCDBCDA.c b/tools/lib/lockdep/tests/ABCDBCDA.c
index 32d19d6..00cd676 100644
--- a/tools/lib/lockdep/tests/ABCDBCDA.c
+++ b/tools/lib/lockdep/tests/ABCDBCDA.c
@@ -5,7 +5,6 @@ void main(void)
 {
 	liblockdep_pthread_mutex_t a, b, c, d;
 
-	liblockdep_init();
 	liblockdep_set_thread();
 
 	liblockdep_pthread_mutex_init(&a, NULL);
diff --git a/tools/lib/lockdep/tests/ABCDBDDA.c b/tools/lib/lockdep/tests/ABCDBDDA.c
index 850eaca..19b3ed1 100644
--- a/tools/lib/lockdep/tests/ABCDBDDA.c
+++ b/tools/lib/lockdep/tests/ABCDBDDA.c
@@ -5,7 +5,6 @@ void main(void)
 {
 	pthread_mutex_t a, b, c, d;
 
-	liblockdep_init();
 	liblockdep_set_thread();
 
 	pthread_mutex_init(&a, NULL);
diff --git a/tools/lib/lockdep/tests/WW.c b/tools/lib/lockdep/tests/WW.c
index 4b1be0f..2467b13 100644
--- a/tools/lib/lockdep/tests/WW.c
+++ b/tools/lib/lockdep/tests/WW.c
@@ -4,7 +4,6 @@ void main(void)
 {
 	pthread_rwlock_t a, b;
 
-	liblockdep_init();
 	liblockdep_set_thread();
 
 	pthread_rwlock_init(&a, NULL);
diff --git a/tools/lib/lockdep/tests/unlock_balance.c b/tools/lib/lockdep/tests/unlock_balance.c
index 9dfaf97..07a4c21 100644
--- a/tools/lib/lockdep/tests/unlock_balance.c
+++ b/tools/lib/lockdep/tests/unlock_balance.c
@@ -4,7 +4,6 @@ void main(void)
 {
 	pthread_mutex_t a;
 
-	liblockdep_init();
 	liblockdep_set_thread();
 
 	pthread_mutex_init(&a, NULL);
diff --git a/tools/lib/lockdep/uinclude/linux/lockdep.h b/tools/lib/lockdep/uinclude/linux/lockdep.h
index 1ed83a5..611cb28 100644
--- a/tools/lib/lockdep/uinclude/linux/lockdep.h
+++ b/tools/lib/lockdep/uinclude/linux/lockdep.h
@@ -25,7 +25,6 @@ struct task_struct {
 extern __thread struct task_struct current_obj;
 #define current (&current_obj)
 
-void liblockdep_init(void);
 void liblockdep_set_thread(void);
 
 #define debug_locks_off() 1
-- 
1.8.1.2


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

* [PATCH 02/11] liblockdep: remove the need for liblockdep_set_thread
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
  2013-02-06 22:11 ` [PATCH 01/11] liblockdep: remove the need for liblockdep_init Sasha Levin
@ 2013-02-06 22:11 ` Sasha Levin
  2013-02-06 22:11 ` [PATCH 03/11] perf: stop using liblockdep_init and liblockdep_set_thread Sasha Levin
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

Generate the task_struct data on the fly when needed, instead on on
thread creation.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 tools/lib/lockdep/common.c                    | 8 +++++---
 tools/lib/lockdep/include/liblockdep/common.h | 1 -
 tools/lib/lockdep/tests/AA.c                  | 2 --
 tools/lib/lockdep/tests/ABBA.c                | 2 --
 tools/lib/lockdep/tests/ABBCCA.c              | 2 --
 tools/lib/lockdep/tests/ABBCCDDA.c            | 2 --
 tools/lib/lockdep/tests/ABCABC.c              | 2 --
 tools/lib/lockdep/tests/ABCDBCDA.c            | 2 --
 tools/lib/lockdep/tests/ABCDBDDA.c            | 2 --
 tools/lib/lockdep/tests/WW.c                  | 2 --
 tools/lib/lockdep/tests/unlock_balance.c      | 2 --
 tools/lib/lockdep/uinclude/linux/lockdep.h    | 4 ++--
 12 files changed, 7 insertions(+), 24 deletions(-)

diff --git a/tools/lib/lockdep/common.c b/tools/lib/lockdep/common.c
index d2946e0..c0f1166 100644
--- a/tools/lib/lockdep/common.c
+++ b/tools/lib/lockdep/common.c
@@ -15,8 +15,10 @@ __attribute__((constructor)) static void liblockdep_init(void)
 	lockdep_init();
 }
 
-void liblockdep_set_thread(void)
+struct task_struct *__curr(void)
 {
-	prctl(PR_GET_NAME, current->comm);
-	current->pid = syscall(__NR_gettid);
+	prctl(PR_GET_NAME, current_obj.comm);
+	current_obj.pid = syscall(__NR_gettid);
+
+	return &current_obj;
 }
diff --git a/tools/lib/lockdep/include/liblockdep/common.h b/tools/lib/lockdep/include/liblockdep/common.h
index f6f7fec8..a675ef0 100644
--- a/tools/lib/lockdep/include/liblockdep/common.h
+++ b/tools/lib/lockdep/include/liblockdep/common.h
@@ -26,7 +26,6 @@ struct lockdep_map {
 #endif
 };
 
-void liblockdep_set_thread(void);
 void lockdep_init_map(struct lockdep_map *lock, const char *name,
 			struct lock_class_key *key, int subclass);
 void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
diff --git a/tools/lib/lockdep/tests/AA.c b/tools/lib/lockdep/tests/AA.c
index 3f71333..a443e65 100644
--- a/tools/lib/lockdep/tests/AA.c
+++ b/tools/lib/lockdep/tests/AA.c
@@ -4,8 +4,6 @@ void main(void)
 {
 	pthread_mutex_t a, b;
 
-	liblockdep_set_thread();
-
 	pthread_mutex_init(&a, NULL);
 	pthread_mutex_init(&b, NULL);
 
diff --git a/tools/lib/lockdep/tests/ABBA.c b/tools/lib/lockdep/tests/ABBA.c
index 08d87a7..07f0e29 100644
--- a/tools/lib/lockdep/tests/ABBA.c
+++ b/tools/lib/lockdep/tests/ABBA.c
@@ -5,8 +5,6 @@ void main(void)
 {
 	pthread_mutex_t a, b;
 
-	liblockdep_set_thread();
-
 	pthread_mutex_init(&a, NULL);
 	pthread_mutex_init(&b, NULL);
 
diff --git a/tools/lib/lockdep/tests/ABBCCA.c b/tools/lib/lockdep/tests/ABBCCA.c
index c5d0e5c..843db09 100644
--- a/tools/lib/lockdep/tests/ABBCCA.c
+++ b/tools/lib/lockdep/tests/ABBCCA.c
@@ -5,8 +5,6 @@ void main(void)
 {
 	pthread_mutex_t a, b, c;
 
-	liblockdep_set_thread();
-
 	pthread_mutex_init(&a, NULL);
 	pthread_mutex_init(&b, NULL);
 	pthread_mutex_init(&c, NULL);
diff --git a/tools/lib/lockdep/tests/ABBCCDDA.c b/tools/lib/lockdep/tests/ABBCCDDA.c
index e12dc98..33620e2 100644
--- a/tools/lib/lockdep/tests/ABBCCDDA.c
+++ b/tools/lib/lockdep/tests/ABBCCDDA.c
@@ -5,8 +5,6 @@ void main(void)
 {
 	pthread_mutex_t a, b, c, d;
 
-	liblockdep_set_thread();
-
 	pthread_mutex_init(&a, NULL);
 	pthread_mutex_init(&b, NULL);
 	pthread_mutex_init(&c, NULL);
diff --git a/tools/lib/lockdep/tests/ABCABC.c b/tools/lib/lockdep/tests/ABCABC.c
index 70879c95..3fee51e 100644
--- a/tools/lib/lockdep/tests/ABCABC.c
+++ b/tools/lib/lockdep/tests/ABCABC.c
@@ -5,8 +5,6 @@ void main(void)
 {
 	pthread_mutex_t a, b, c;
 
-	liblockdep_set_thread();
-
 	pthread_mutex_init(&a, NULL);
 	pthread_mutex_init(&b, NULL);
 	pthread_mutex_init(&c, NULL);
diff --git a/tools/lib/lockdep/tests/ABCDBCDA.c b/tools/lib/lockdep/tests/ABCDBCDA.c
index 00cd676..aadf11e 100644
--- a/tools/lib/lockdep/tests/ABCDBCDA.c
+++ b/tools/lib/lockdep/tests/ABCDBCDA.c
@@ -5,8 +5,6 @@ void main(void)
 {
 	liblockdep_pthread_mutex_t a, b, c, d;
 
-	liblockdep_set_thread();
-
 	liblockdep_pthread_mutex_init(&a, NULL);
 	liblockdep_pthread_mutex_init(&b, NULL);
 	liblockdep_pthread_mutex_init(&c, NULL);
diff --git a/tools/lib/lockdep/tests/ABCDBDDA.c b/tools/lib/lockdep/tests/ABCDBDDA.c
index 19b3ed1..680c6cf 100644
--- a/tools/lib/lockdep/tests/ABCDBDDA.c
+++ b/tools/lib/lockdep/tests/ABCDBDDA.c
@@ -5,8 +5,6 @@ void main(void)
 {
 	pthread_mutex_t a, b, c, d;
 
-	liblockdep_set_thread();
-
 	pthread_mutex_init(&a, NULL);
 	pthread_mutex_init(&b, NULL);
 	pthread_mutex_init(&c, NULL);
diff --git a/tools/lib/lockdep/tests/WW.c b/tools/lib/lockdep/tests/WW.c
index 2467b13..d44f77d 100644
--- a/tools/lib/lockdep/tests/WW.c
+++ b/tools/lib/lockdep/tests/WW.c
@@ -4,8 +4,6 @@ void main(void)
 {
 	pthread_rwlock_t a, b;
 
-	liblockdep_set_thread();
-
 	pthread_rwlock_init(&a, NULL);
 	pthread_rwlock_init(&b, NULL);
 
diff --git a/tools/lib/lockdep/tests/unlock_balance.c b/tools/lib/lockdep/tests/unlock_balance.c
index 07a4c21..0bc62de 100644
--- a/tools/lib/lockdep/tests/unlock_balance.c
+++ b/tools/lib/lockdep/tests/unlock_balance.c
@@ -4,8 +4,6 @@ void main(void)
 {
 	pthread_mutex_t a;
 
-	liblockdep_set_thread();
-
 	pthread_mutex_init(&a, NULL);
 
 	pthread_mutex_lock(&a);
diff --git a/tools/lib/lockdep/uinclude/linux/lockdep.h b/tools/lib/lockdep/uinclude/linux/lockdep.h
index 611cb28..52609c5 100644
--- a/tools/lib/lockdep/uinclude/linux/lockdep.h
+++ b/tools/lib/lockdep/uinclude/linux/lockdep.h
@@ -23,9 +23,9 @@ struct task_struct {
 };
 
 extern __thread struct task_struct current_obj;
-#define current (&current_obj)
+extern struct task_struct *__curr(void);
 
-void liblockdep_set_thread(void);
+#define current (__curr())
 
 #define debug_locks_off() 1
 #define task_pid_nr(tsk) ((tsk)->pid)
-- 
1.8.1.2


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

* [PATCH 03/11] perf: stop using liblockdep_init and liblockdep_set_thread
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
  2013-02-06 22:11 ` [PATCH 01/11] liblockdep: remove the need for liblockdep_init Sasha Levin
  2013-02-06 22:11 ` [PATCH 02/11] liblockdep: remove the need for liblockdep_set_thread Sasha Levin
@ 2013-02-06 22:11 ` Sasha Levin
  2013-02-06 22:11 ` [PATCH 04/11] liblockdep: fix AA test Sasha Levin
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

These functions are no longer needed by liblockdep, drop them.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 tools/perf/builtin-sched.c          | 2 --
 tools/perf/builtin-top.c            | 4 ----
 tools/perf/config/feature-tests.mak | 1 -
 tools/perf/perf.c                   | 3 ---
 tools/perf/util/liblockdep.h        | 2 --
 5 files changed, 12 deletions(-)

diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 53d9225..e1f0c44 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -468,8 +468,6 @@ static void *thread_func(void *ctx)
 	char comm2[22];
 	int fd;
 
-	liblockdep_set_thread();
-
 	free(parms);
 
 	sprintf(comm2, ":%s", this_task->comm);
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index c9b99ef..c9ff395 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -588,8 +588,6 @@ static void *display_thread_tui(void *arg)
 		.refresh	= top->delay_secs,
 	};
 
-	liblockdep_set_thread();
-
 	perf_top__sort_new_samples(top);
 
 	/*
@@ -615,8 +613,6 @@ static void *display_thread(void *arg)
 	struct perf_top *top = arg;
 	int delay_msecs, c;
 
-	liblockdep_set_thread();
-
 	tcgetattr(0, &save);
 	tc = save;
 	tc.c_lflag &= ~(ICANON | ECHO);
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak
index 1f5a37e..20f8f7b 100644
--- a/tools/perf/config/feature-tests.mak
+++ b/tools/perf/config/feature-tests.mak
@@ -223,7 +223,6 @@ define SOURCE_LIBLOCKDEP
 
 int main(void)
 {
-	liblockdep_init();
 	return 0;
 }
 endef
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index ddbd315..0f661fb 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -446,9 +446,6 @@ int main(int argc, const char **argv)
 {
 	const char *cmd;
 
-	liblockdep_init();
-	liblockdep_set_thread();
-
 	page_size = sysconf(_SC_PAGE_SIZE);
 
 	cmd = perf_extract_argv0_path(argv[0]);
diff --git a/tools/perf/util/liblockdep.h b/tools/perf/util/liblockdep.h
index 628a2f5..798263f 100644
--- a/tools/perf/util/liblockdep.h
+++ b/tools/perf/util/liblockdep.h
@@ -5,7 +5,5 @@
 #else
 
 #define LIBLOCKDEP_PTHREAD_MUTEX_INITIALIZER(mtx) PTHREAD_MUTEX_INITIALIZER
-#define liblockdep_init()
-#define liblockdep_set_thread()
 
 #endif
-- 
1.8.1.2


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

* [PATCH 04/11] liblockdep: fix AA test
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
                   ` (2 preceding siblings ...)
  2013-02-06 22:11 ` [PATCH 03/11] perf: stop using liblockdep_init and liblockdep_set_thread Sasha Levin
@ 2013-02-06 22:11 ` Sasha Levin
  2013-02-06 22:11 ` [PATCH 05/11] liblockdep: correct the ABCDBCDA test Sasha Levin
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

We were accidently unlocking the dummy mutex in the test, which meant
that we were testing unlock balance instead of AA deadlock.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 tools/lib/lockdep/tests/AA.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/lib/lockdep/tests/AA.c b/tools/lib/lockdep/tests/AA.c
index a443e65..0f782ff 100644
--- a/tools/lib/lockdep/tests/AA.c
+++ b/tools/lib/lockdep/tests/AA.c
@@ -8,6 +8,6 @@ void main(void)
 	pthread_mutex_init(&b, NULL);
 
 	pthread_mutex_lock(&a);
-	pthread_mutex_unlock(&b);
+	pthread_mutex_lock(&b);
 	pthread_mutex_lock(&a);
 }
-- 
1.8.1.2


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

* [PATCH 05/11] liblockdep: correct the ABCDBCDA test
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
                   ` (3 preceding siblings ...)
  2013-02-06 22:11 ` [PATCH 04/11] liblockdep: fix AA test Sasha Levin
@ 2013-02-06 22:11 ` Sasha Levin
  2013-02-06 22:11 ` [PATCH 06/11] liblockdep: rbtree support Sasha Levin
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

There's no need to use liblockdep specific calls, they are wrapped for us.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 tools/lib/lockdep/tests/ABCDBCDA.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/tools/lib/lockdep/tests/ABCDBCDA.c b/tools/lib/lockdep/tests/ABCDBCDA.c
index aadf11e..427ba56 100644
--- a/tools/lib/lockdep/tests/ABCDBCDA.c
+++ b/tools/lib/lockdep/tests/ABCDBCDA.c
@@ -3,12 +3,12 @@
 
 void main(void)
 {
-	liblockdep_pthread_mutex_t a, b, c, d;
+	pthread_mutex_t a, b, c, d;
 
-	liblockdep_pthread_mutex_init(&a, NULL);
-	liblockdep_pthread_mutex_init(&b, NULL);
-	liblockdep_pthread_mutex_init(&c, NULL);
-	liblockdep_pthread_mutex_init(&d, NULL);
+	pthread_mutex_init(&a, NULL);
+	pthread_mutex_init(&b, NULL);
+	pthread_mutex_init(&c, NULL);
+	pthread_mutex_init(&d, NULL);
 
 	LOCK_UNLOCK_2(a, b);
 	LOCK_UNLOCK_2(c, d);
-- 
1.8.1.2


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

* [PATCH 06/11] liblockdep: rbtree support
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
                   ` (4 preceding siblings ...)
  2013-02-06 22:11 ` [PATCH 05/11] liblockdep: correct the ABCDBCDA test Sasha Levin
@ 2013-02-06 22:11 ` Sasha Levin
  2013-02-06 22:11 ` [PATCH 07/11] liblockdep: prevent multiple declarations of CALLER_ADDR0 Sasha Levin
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

We re-use kernel's rbtree structure for the preload improvement in the
following patches.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 tools/lib/lockdep/rbtree.c                          | 1 +
 tools/lib/lockdep/uinclude/linux/rbtree.h           | 1 +
 tools/lib/lockdep/uinclude/linux/rbtree_augmented.h | 2 ++
 3 files changed, 4 insertions(+)
 create mode 100644 tools/lib/lockdep/rbtree.c
 create mode 100644 tools/lib/lockdep/uinclude/linux/rbtree.h
 create mode 100644 tools/lib/lockdep/uinclude/linux/rbtree_augmented.h

diff --git a/tools/lib/lockdep/rbtree.c b/tools/lib/lockdep/rbtree.c
new file mode 100644
index 0000000..f7f4303
--- /dev/null
+++ b/tools/lib/lockdep/rbtree.c
@@ -0,0 +1 @@
+#include "../../../lib/rbtree.c"
diff --git a/tools/lib/lockdep/uinclude/linux/rbtree.h b/tools/lib/lockdep/uinclude/linux/rbtree.h
new file mode 100644
index 0000000..965901d
--- /dev/null
+++ b/tools/lib/lockdep/uinclude/linux/rbtree.h
@@ -0,0 +1 @@
+#include "../../../include/linux/rbtree.h"
diff --git a/tools/lib/lockdep/uinclude/linux/rbtree_augmented.h b/tools/lib/lockdep/uinclude/linux/rbtree_augmented.h
new file mode 100644
index 0000000..c375947
--- /dev/null
+++ b/tools/lib/lockdep/uinclude/linux/rbtree_augmented.h
@@ -0,0 +1,2 @@
+#define __always_inline
+#include "../../../include/linux/rbtree_augmented.h"
-- 
1.8.1.2


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

* [PATCH 07/11] liblockdep: prevent multiple declarations of CALLER_ADDR0
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
                   ` (5 preceding siblings ...)
  2013-02-06 22:11 ` [PATCH 06/11] liblockdep: rbtree support Sasha Levin
@ 2013-02-06 22:11 ` Sasha Levin
  2013-02-06 22:11 ` [PATCH 08/11] liblockdep: keep headers declarations even if lib is disabled Sasha Levin
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

They are declared once in the public and once in the private headers, prevent
declaring them twice if both headers are used.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 tools/lib/lockdep/include/liblockdep/common.h | 3 +++
 tools/lib/lockdep/uinclude/linux/kernel.h     | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/tools/lib/lockdep/include/liblockdep/common.h b/tools/lib/lockdep/include/liblockdep/common.h
index a675ef0..1bad66c 100644
--- a/tools/lib/lockdep/include/liblockdep/common.h
+++ b/tools/lib/lockdep/include/liblockdep/common.h
@@ -3,8 +3,11 @@
 
 #include <pthread.h>
 
+#ifndef CALLER_ADDR0
 #define CALLER_ADDR0 (__builtin_return_address(0))
 #define _THIS_IP_ CALLER_ADDR0
+#endif
+
 #define NR_LOCKDEP_CACHING_CLASSES 2
 #define MAX_LOCKDEP_SUBCLASSES 8UL
 
diff --git a/tools/lib/lockdep/uinclude/linux/kernel.h b/tools/lib/lockdep/uinclude/linux/kernel.h
index da97ce8..af02ac1 100644
--- a/tools/lib/lockdep/uinclude/linux/kernel.h
+++ b/tools/lib/lockdep/uinclude/linux/kernel.h
@@ -28,7 +28,9 @@
 #define noinline
 #define list_add_tail_rcu list_add_tail
 
+#ifndef CALLER_ADDR0
 #define _THIS_IP_ CALLER_ADDR0
 #define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#endif
 
 #endif
-- 
1.8.1.2


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

* [PATCH 08/11] liblockdep: keep headers declarations even if lib is disabled
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
                   ` (6 preceding siblings ...)
  2013-02-06 22:11 ` [PATCH 07/11] liblockdep: prevent multiple declarations of CALLER_ADDR0 Sasha Levin
@ 2013-02-06 22:11 ` Sasha Levin
  2013-02-06 22:11 ` [PATCH 09/11] liblockdep: support using LD_PRELOAD Sasha Levin
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

We need the public headers in the core module code for the preload thing.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 tools/lib/lockdep/include/liblockdep/mutex.h  | 4 ++--
 tools/lib/lockdep/include/liblockdep/rwlock.h | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/tools/lib/lockdep/include/liblockdep/mutex.h b/tools/lib/lockdep/include/liblockdep/mutex.h
index 5154a9d..6ebe733 100644
--- a/tools/lib/lockdep/include/liblockdep/mutex.h
+++ b/tools/lib/lockdep/include/liblockdep/mutex.h
@@ -1,8 +1,6 @@
 #ifndef _LIBLOCKDEP_MUTEX_H
 #define _LIBLOCKDEP_MUTEX_H
 
-#ifdef __USE_LIBLOCKDEP
-
 #include <pthread.h>
 #include "common.h"
 
@@ -61,6 +59,8 @@ static inline int liblockdep_pthread_mutex_destroy(liblockdep_pthread_mutex_t *l
 	return pthread_mutex_destroy(&lock->mutex);
 }
 
+#ifdef __USE_LIBLOCKDEP
+
 #define pthread_mutex_t         liblockdep_pthread_mutex_t
 #define pthread_mutex_init      liblockdep_pthread_mutex_init
 #define pthread_mutex_lock      liblockdep_pthread_mutex_lock
diff --git a/tools/lib/lockdep/include/liblockdep/rwlock.h b/tools/lib/lockdep/include/liblockdep/rwlock.h
index 26f9a68..a1d820b 100644
--- a/tools/lib/lockdep/include/liblockdep/rwlock.h
+++ b/tools/lib/lockdep/include/liblockdep/rwlock.h
@@ -1,8 +1,6 @@
 #ifndef _LIBLOCKDEP_RWLOCK_H
 #define _LIBLOCKDEP_RWLOCK_H
 
-#ifdef __USE_LIBLOCKDEP
-
 #include <pthread.h>
 #include "common.h"
 
@@ -77,6 +75,8 @@ static inline int liblockdep_rwlock_destroy(liblockdep_pthread_rwlock_t *lock)
 	return pthread_rwlock_destroy(&lock->rwlock);
 }
 
+#ifdef __USE_LIBLOCKDEP
+
 #define pthread_rwlock_t		liblockdep_pthread_rwlock_t
 #define pthread_rwlock_init		liblockdep_pthread_rwlock_init
 #define pthread_rwlock_rdlock		liblockdep_pthread_rwlock_rdlock
-- 
1.8.1.2


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

* [PATCH 09/11] liblockdep: support using LD_PRELOAD
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
                   ` (7 preceding siblings ...)
  2013-02-06 22:11 ` [PATCH 08/11] liblockdep: keep headers declarations even if lib is disabled Sasha Levin
@ 2013-02-06 22:11 ` Sasha Levin
  2013-02-07 10:28   ` Jamie Iles
  2013-02-06 22:11 ` [PATCH 10/11] liblockdep: add tests for the LD_PRELOAD feature Sasha Levin
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

This allows lockdep to be used without being compiled in the original program.

Usage is quite simple:

	LD_PRELOAD=/path/to/liblockdep.so /path/to/my/program

And magically, you'll have lockdep in your program!

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 tools/lib/lockdep/Makefile  |   4 +-
 tools/lib/lockdep/preload.c | 184 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 186 insertions(+), 2 deletions(-)
 create mode 100644 tools/lib/lockdep/preload.c

diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile
index e82ffe9..245f8ba 100644
--- a/tools/lib/lockdep/Makefile
+++ b/tools/lib/lockdep/Makefile
@@ -143,7 +143,7 @@ do_app_build =						\
 
 do_compile_shared_library =			\
 	($(print_shared_lib_compile)		\
-	$(CC) --shared $^ -o $@)
+	$(CC) --shared -ldl $^ -o $@)
 
 do_build_static_lib =				\
 	($(print_static_lib_build)		\
@@ -161,7 +161,7 @@ $(obj)/%.o: $(src)/%.c
 %.o: $(src)/%.c
 	$(Q)$(call do_compile)
 
-PEVENT_LIB_OBJS = common.o lockdep.o
+PEVENT_LIB_OBJS = common.o lockdep.o preload.o rbtree.o
 
 ALL_OBJS = $(PEVENT_LIB_OBJS)
 
diff --git a/tools/lib/lockdep/preload.c b/tools/lib/lockdep/preload.c
new file mode 100644
index 0000000..0f71c23
--- /dev/null
+++ b/tools/lib/lockdep/preload.c
@@ -0,0 +1,184 @@
+#define _GNU_SOURCE
+#include <pthread.h>
+#include <stdio.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include "include/liblockdep/mutex.h"
+#include "../../../include/linux/rbtree.h"
+
+struct lock_lookup {
+	void *orig;
+	struct lockdep_map dep_map;
+	struct rb_node node;
+};
+
+struct rb_root locks = RB_ROOT;
+
+int (*ll_pthread_mutex_init)(pthread_mutex_t *mutex,
+			const pthread_mutexattr_t *attr);
+int (*ll_pthread_mutex_lock)(pthread_mutex_t *mutex);
+int (*ll_pthread_mutex_trylock)(pthread_mutex_t *mutex);
+int (*ll_pthread_mutex_unlock)(pthread_mutex_t *mutex);
+int (*ll_pthread_mutex_destroy)(pthread_mutex_t *mutex);
+
+int (*ll_pthread_rwlock_init)(pthread_rwlock_t *rwlock,
+			const pthread_rwlockattr_t *attr);
+int (*ll_pthread_rwlock_destroy)(pthread_rwlock_t *rwlock);
+int (*ll_pthread_rwlock_rdlock)(pthread_rwlock_t *rwlock);
+int (*ll_pthread_rwlock_tryrdlock)(pthread_rwlock_t *rwlock);
+int (*ll_pthread_rwlock_trywrlock)(pthread_rwlock_t *rwlock);
+int (*ll_pthread_rwlock_wrlock)(pthread_rwlock_t *rwlock);
+int (*ll_pthread_rwlock_unlock)(pthread_rwlock_t *rwlock);
+
+static void init_preload();
+
+static struct lock_lookup *__get_lock(void *lock)
+{
+	struct rb_node **node = &locks.rb_node, *parent = NULL;
+	struct lock_lookup *l;
+
+	while (*node) {
+		l = rb_entry(*node, struct lock_lookup, node);
+
+		parent = *node;
+		if (lock < l->orig)
+			node = &l->node.rb_left;
+		else if (lock > l->orig)
+			node = &l->node.rb_right;
+		else
+			return l;
+	}
+
+	l = malloc(sizeof(*l));
+	if (l == NULL)
+		return NULL;
+
+	*l = (struct lock_lookup) {
+		.orig = lock,
+		.dep_map = STATIC_LOCKDEP_MAP_INIT("lock", &l->dep_map),
+	};
+
+	rb_link_node(&l->node, parent, node);
+	rb_insert_color(&l->node, &locks);
+
+	return l;
+}
+
+int pthread_mutex_init(pthread_mutex_t *mutex,
+			const pthread_mutexattr_t *attr)
+{
+	if (ll_pthread_mutex_init == NULL)
+		init_preload();
+
+	__get_lock(mutex);
+	return ll_pthread_mutex_init(mutex, attr);
+}
+
+int pthread_mutex_lock(pthread_mutex_t *mutex)
+{
+	void *ip = _THIS_IP_;
+
+	lock_acquire(&__get_lock(mutex)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)ip);
+	return ll_pthread_mutex_lock(mutex);
+}
+
+int pthread_mutex_trylock(pthread_mutex_t *mutex)
+{
+	void *ip = _THIS_IP_;
+
+	lock_acquire(&__get_lock(mutex)->dep_map, 0, 1, 0, 2, NULL, (unsigned long)ip);
+	return ll_pthread_mutex_trylock(mutex);
+}
+
+int pthread_mutex_unlock(pthread_mutex_t *mutex)
+{
+	void *ip = _THIS_IP_;
+
+	lock_release(&__get_lock(mutex)->dep_map, 0, (unsigned long)ip);
+	return ll_pthread_mutex_unlock(mutex);
+}
+
+int pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+	struct lock_lookup *l = __get_lock(mutex);
+
+	rb_erase(&l->node, &locks);
+	free(l);
+	return ll_pthread_mutex_destroy(mutex);
+}
+
+int pthread_rwlock_init(pthread_rwlock_t *rwlock,
+			const pthread_rwlockattr_t *attr)
+{
+	if (ll_pthread_rwlock_init == NULL)
+		init_preload();
+
+	__get_lock(rwlock);
+	return ll_pthread_rwlock_init(rwlock, attr);
+}
+
+int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
+{
+	struct lock_lookup *l = __get_lock(rwlock);
+
+	rb_erase(&l->node, &locks);
+	free(l);
+	return ll_pthread_rwlock_destroy(rwlock);
+}
+
+int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
+{
+	void *ip = _THIS_IP_;
+
+	lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 2, 2, NULL, (unsigned long)ip);
+	return ll_pthread_rwlock_rdlock(rwlock);
+}
+
+int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
+{
+	void *ip = _THIS_IP_;
+
+	lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 2, 2, NULL, (unsigned long)ip);
+	return ll_pthread_rwlock_tryrdlock(rwlock);
+}
+
+int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
+{
+	void *ip = _THIS_IP_;
+
+	lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 0, 2, NULL, (unsigned long)ip);
+	return ll_pthread_rwlock_trywrlock(rwlock);
+}
+
+int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
+{
+	void *ip = _THIS_IP_;
+
+	lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)ip);
+	return ll_pthread_rwlock_wrlock(rwlock);
+}
+
+int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
+{
+	void *ip = _THIS_IP_;
+
+	lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)ip);
+	return ll_pthread_rwlock_unlock(rwlock);
+}
+
+__attribute__((constructor)) static void init_preload(void)
+{
+	ll_pthread_mutex_init = dlsym(RTLD_NEXT, "pthread_mutex_init");
+	ll_pthread_mutex_lock = dlsym(RTLD_NEXT, "pthread_mutex_lock");
+	ll_pthread_mutex_trylock = dlsym(RTLD_NEXT, "pthread_mutex_trylock");
+	ll_pthread_mutex_unlock = dlsym(RTLD_NEXT, "pthread_mutex_unlock");
+	ll_pthread_mutex_destroy = dlsym(RTLD_NEXT, "pthread_mutex_destroy");
+
+	ll_pthread_rwlock_init = dlsym(RTLD_NEXT, "pthread_rwlock_init");
+	ll_pthread_rwlock_destroy = dlsym(RTLD_NEXT, "pthread_rwlock_destroy");
+	ll_pthread_rwlock_rdlock = dlsym(RTLD_NEXT, "pthread_rwlock_rdlock");
+	ll_pthread_rwlock_tryrdlock = dlsym(RTLD_NEXT, "pthread_rwlock_tryrdlock");
+	ll_pthread_rwlock_wrlock = dlsym(RTLD_NEXT, "pthread_rwlock_wrlock");
+	ll_pthread_rwlock_trywrlock = dlsym(RTLD_NEXT, "pthread_rwlock_trywrlock");
+	ll_pthread_rwlock_unlock = dlsym(RTLD_NEXT, "pthread_rwlock_unlock");
+}
-- 
1.8.1.2


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

* [PATCH 10/11] liblockdep: add tests for the LD_PRELOAD feature
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
                   ` (8 preceding siblings ...)
  2013-02-06 22:11 ` [PATCH 09/11] liblockdep: support using LD_PRELOAD Sasha Levin
@ 2013-02-06 22:11 ` Sasha Levin
  2013-02-06 22:11 ` [PATCH 11/11] liblockdep: preload helper Sasha Levin
  2013-02-07  7:07 ` [PATCH 00/11] lockdep: LD_PRELOAD support Pekka Enberg
  11 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

Use same tests, but without compiling with liblockdep in the first place.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 tools/lib/lockdep/run_tests.sh | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/tools/lib/lockdep/run_tests.sh b/tools/lib/lockdep/run_tests.sh
index 4dd32d1..211e91d 100755
--- a/tools/lib/lockdep/run_tests.sh
+++ b/tools/lib/lockdep/run_tests.sh
@@ -13,3 +13,15 @@ for i in `ls tests/*.c`; do
 	fi
 	rm tests/$testname
 done
+
+for i in `ls tests/*.c`; do
+	testname=$(basename -s .c "$i")
+	gcc -o tests/$testname -lpthread -Iinclude $i &> /dev/null
+	echo -ne "(PRELOAD) $testname... "
+	if [ $(LD_PRELOAD=./liblockdep.so timeout 1 ./tests/$testname | wc -l) -gt 0 ]; then
+		echo "PASSED!"
+	else
+		echo "FAILED!"
+	fi
+	rm tests/$testname
+done
-- 
1.8.1.2


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

* [PATCH 11/11] liblockdep: preload helper
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
                   ` (9 preceding siblings ...)
  2013-02-06 22:11 ` [PATCH 10/11] liblockdep: add tests for the LD_PRELOAD feature Sasha Levin
@ 2013-02-06 22:11 ` Sasha Levin
  2013-02-07  6:19   ` Namhyung Kim
  2013-02-07  6:55   ` Namhyung Kim
  2013-02-07  7:07 ` [PATCH 00/11] lockdep: LD_PRELOAD support Pekka Enberg
  11 siblings, 2 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-06 22:11 UTC (permalink / raw)
  To: mingo, peterz
  Cc: jamie.iles, penberg, acme, paulus, linux-kernel, Sasha Levin

This is a simple wrapper to make using liblockdep on existing applications
much easier.

After running 'make && make install', it becomes quite simple to test things
with liblockdep. For example, to try it on perf:

	liblockdep perf

No other integration required.

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
 tools/lib/lockdep/Makefile | 12 ++++++++----
 tools/lib/lockdep/lockdep  |  3 +++
 2 files changed, 11 insertions(+), 4 deletions(-)
 create mode 100755 tools/lib/lockdep/lockdep

diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile
index 245f8ba..b22122f 100644
--- a/tools/lib/lockdep/Makefile
+++ b/tools/lib/lockdep/Makefile
@@ -34,7 +34,9 @@ DESTDIR ?=
 DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))'
 
 prefix ?= /usr/local
-bindir_relative = lib
+libdir_relative = lib
+libdir = $(prefix)/$(libdir_relative)
+bindir_relative = bin
 bindir = $(prefix)/$(bindir_relative)
 
 export DESTDIR DESTDIR_SQ INSTALL
@@ -90,13 +92,14 @@ objtree		:= $(CURDIR)
 src		:= $(srctree)
 obj		:= $(objtree)
 
-export prefix bindir src obj
+export prefix libdir bindir src obj
 
 # Shell quotes
+libdir_SQ = $(subst ','\'',$(libdir))
 bindir_SQ = $(subst ','\'',$(bindir))
-bindir_relative_SQ = $(subst ','\'',$(bindir_relative))
 
 LIB_FILE = liblockdep.a liblockdep.so
+BIN_FILE = lockdep
 
 CONFIG_INCLUDES =
 CONFIG_LIBS	=
@@ -229,7 +232,8 @@ define do_install
 endef
 
 install_lib: all_cmd
-	$(Q)$(call do_install,$(LIB_FILE),$(bindir_SQ))
+	$(Q)$(call do_install,$(LIB_FILE),$(libdir_SQ))
+	$(Q)$(call do_install,$(BIN_FILE),$(bindir_SQ))
 
 install: install_lib
 
diff --git a/tools/lib/lockdep/lockdep b/tools/lib/lockdep/lockdep
new file mode 100755
index 0000000..616bf9a
--- /dev/null
+++ b/tools/lib/lockdep/lockdep
@@ -0,0 +1,3 @@
+#! /bin/bash
+
+LD_PRELOAD=liblockdep.so "$@"
-- 
1.8.1.2


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

* Re: [PATCH 11/11] liblockdep: preload helper
  2013-02-06 22:11 ` [PATCH 11/11] liblockdep: preload helper Sasha Levin
@ 2013-02-07  6:19   ` Namhyung Kim
  2013-02-07  6:55   ` Namhyung Kim
  1 sibling, 0 replies; 20+ messages in thread
From: Namhyung Kim @ 2013-02-07  6:19 UTC (permalink / raw)
  To: Sasha Levin
  Cc: mingo, peterz, jamie.iles, penberg, acme, paulus, linux-kernel

Hi Sasha,

On Wed,  6 Feb 2013 17:11:34 -0500, Sasha Levin wrote:
> This is a simple wrapper to make using liblockdep on existing applications
> much easier.
>
> After running 'make && make install', it becomes quite simple to test things
> with liblockdep. For example, to try it on perf:
>
> 	liblockdep perf

Shouldn't it be 'lockdep perf ...'?

Thanks,
Namhyung

>
> No other integration required.
>
> Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
> ---
>  tools/lib/lockdep/Makefile | 12 ++++++++----
>  tools/lib/lockdep/lockdep  |  3 +++
>  2 files changed, 11 insertions(+), 4 deletions(-)
>  create mode 100755 tools/lib/lockdep/lockdep
>
> diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile
> index 245f8ba..b22122f 100644
> --- a/tools/lib/lockdep/Makefile
> +++ b/tools/lib/lockdep/Makefile
> @@ -34,7 +34,9 @@ DESTDIR ?=
>  DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))'
>  
>  prefix ?= /usr/local
> -bindir_relative = lib
> +libdir_relative = lib
> +libdir = $(prefix)/$(libdir_relative)
> +bindir_relative = bin
>  bindir = $(prefix)/$(bindir_relative)
>  
>  export DESTDIR DESTDIR_SQ INSTALL
> @@ -90,13 +92,14 @@ objtree		:= $(CURDIR)
>  src		:= $(srctree)
>  obj		:= $(objtree)
>  
> -export prefix bindir src obj
> +export prefix libdir bindir src obj
>  
>  # Shell quotes
> +libdir_SQ = $(subst ','\'',$(libdir))
>  bindir_SQ = $(subst ','\'',$(bindir))
> -bindir_relative_SQ = $(subst ','\'',$(bindir_relative))
>  
>  LIB_FILE = liblockdep.a liblockdep.so
> +BIN_FILE = lockdep
>  
>  CONFIG_INCLUDES =
>  CONFIG_LIBS	=
> @@ -229,7 +232,8 @@ define do_install
>  endef
>  
>  install_lib: all_cmd
> -	$(Q)$(call do_install,$(LIB_FILE),$(bindir_SQ))
> +	$(Q)$(call do_install,$(LIB_FILE),$(libdir_SQ))
> +	$(Q)$(call do_install,$(BIN_FILE),$(bindir_SQ))
>  
>  install: install_lib
>  
> diff --git a/tools/lib/lockdep/lockdep b/tools/lib/lockdep/lockdep
> new file mode 100755
> index 0000000..616bf9a
> --- /dev/null
> +++ b/tools/lib/lockdep/lockdep
> @@ -0,0 +1,3 @@
> +#! /bin/bash
> +
> +LD_PRELOAD=liblockdep.so "$@"

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

* Re: [PATCH 11/11] liblockdep: preload helper
  2013-02-06 22:11 ` [PATCH 11/11] liblockdep: preload helper Sasha Levin
  2013-02-07  6:19   ` Namhyung Kim
@ 2013-02-07  6:55   ` Namhyung Kim
  2013-02-07 14:29     ` Sasha Levin
  1 sibling, 1 reply; 20+ messages in thread
From: Namhyung Kim @ 2013-02-07  6:55 UTC (permalink / raw)
  To: Sasha Levin
  Cc: mingo, peterz, jamie.iles, penberg, acme, paulus, linux-kernel

On Wed,  6 Feb 2013 17:11:34 -0500, Sasha Levin wrote:
> diff --git a/tools/lib/lockdep/lockdep b/tools/lib/lockdep/lockdep
> new file mode 100755
> index 0000000..616bf9a
> --- /dev/null
> +++ b/tools/lib/lockdep/lockdep
> @@ -0,0 +1,3 @@
> +#! /bin/bash
> +
> +LD_PRELOAD=liblockdep.so "$@"

Just try to be more conservative ;-)

  LD_PRELOAD="liblockdep.so $LD_PRELOAD" "$@"

Thanks,
Namhyung

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

* Re: [PATCH 00/11] lockdep: LD_PRELOAD support
  2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
                   ` (10 preceding siblings ...)
  2013-02-06 22:11 ` [PATCH 11/11] liblockdep: preload helper Sasha Levin
@ 2013-02-07  7:07 ` Pekka Enberg
  11 siblings, 0 replies; 20+ messages in thread
From: Pekka Enberg @ 2013-02-07  7:07 UTC (permalink / raw)
  To: Sasha Levin; +Cc: mingo, peterz, jamie.iles, acme, paulus, linux-kernel

On Thu, Feb 7, 2013 at 12:11 AM, Sasha Levin <sasha.levin@oracle.com> wrote:
> This patch series adds in LD_PRELOAD support for liblockdep.

FWIW,

Acked-by: Pekka Enberg <penberg@kernel.org>

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

* Re: [PATCH 09/11] liblockdep: support using LD_PRELOAD
  2013-02-06 22:11 ` [PATCH 09/11] liblockdep: support using LD_PRELOAD Sasha Levin
@ 2013-02-07 10:28   ` Jamie Iles
  2013-02-07 14:31     ` Sasha Levin
  0 siblings, 1 reply; 20+ messages in thread
From: Jamie Iles @ 2013-02-07 10:28 UTC (permalink / raw)
  To: Sasha Levin
  Cc: mingo, peterz, jamie.iles, penberg, acme, paulus, linux-kernel

Hi Sasha,

On Wed, Feb 06, 2013 at 05:11:32PM -0500, Sasha Levin wrote:
> This allows lockdep to be used without being compiled in the original program.
> 
> Usage is quite simple:
> 
> 	LD_PRELOAD=/path/to/liblockdep.so /path/to/my/program
> 
> And magically, you'll have lockdep in your program!
> 
> Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
> ---
> diff --git a/tools/lib/lockdep/preload.c b/tools/lib/lockdep/preload.c
> new file mode 100644
> index 0000000..0f71c23
> --- /dev/null
> +++ b/tools/lib/lockdep/preload.c
...
> +int pthread_rwlock_init(pthread_rwlock_t *rwlock,
> +			const pthread_rwlockattr_t *attr)
> +{
> +	if (ll_pthread_rwlock_init == NULL)
> +		init_preload();

Why is this one special, doesn't init_preload being a constructor make 
this redundant?

Jamie

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

* Re: [PATCH 11/11] liblockdep: preload helper
  2013-02-07  6:55   ` Namhyung Kim
@ 2013-02-07 14:29     ` Sasha Levin
  0 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-07 14:29 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: mingo, peterz, jamie.iles, penberg, acme, paulus, linux-kernel

On 02/07/2013 01:55 AM, Namhyung Kim wrote:
> On Wed,  6 Feb 2013 17:11:34 -0500, Sasha Levin wrote:
>> diff --git a/tools/lib/lockdep/lockdep b/tools/lib/lockdep/lockdep
>> new file mode 100755
>> index 0000000..616bf9a
>> --- /dev/null
>> +++ b/tools/lib/lockdep/lockdep
>> @@ -0,0 +1,3 @@
>> +#! /bin/bash
>> +
>> +LD_PRELOAD=liblockdep.so "$@"
> 
> Just try to be more conservative ;-)
> 
>   LD_PRELOAD="liblockdep.so $LD_PRELOAD" "$@"

Will do, thanks!

And yes, it's supposed to be 'lockdep perf' :


Thanks,
Sasha


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

* Re: [PATCH 09/11] liblockdep: support using LD_PRELOAD
  2013-02-07 10:28   ` Jamie Iles
@ 2013-02-07 14:31     ` Sasha Levin
  2013-02-08 10:43       ` Jamie Iles
  0 siblings, 1 reply; 20+ messages in thread
From: Sasha Levin @ 2013-02-07 14:31 UTC (permalink / raw)
  To: Jamie Iles; +Cc: mingo, peterz, penberg, acme, paulus, linux-kernel

On 02/07/2013 05:28 AM, Jamie Iles wrote:
>> +int pthread_rwlock_init(pthread_rwlock_t *rwlock,
>> > +			const pthread_rwlockattr_t *attr)
>> > +{
>> > +	if (ll_pthread_rwlock_init == NULL)
>> > +		init_preload();
> Why is this one special, doesn't init_preload being a constructor make 
> this redundant?

I was testing it on different things, and stumbled on an interesting case:
when pthread_mutex was taken from the constructor of a different module.

In that case, the other constructor would try to init the mutex and take
a lock, but we would segfault because we haven't resolved the pthread
symbols yet ourselves (since our constructor was yet to be called).


Thanks,
Sasha

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

* Re: [PATCH 09/11] liblockdep: support using LD_PRELOAD
  2013-02-07 14:31     ` Sasha Levin
@ 2013-02-08 10:43       ` Jamie Iles
  2013-02-08 23:55         ` Sasha Levin
  0 siblings, 1 reply; 20+ messages in thread
From: Jamie Iles @ 2013-02-08 10:43 UTC (permalink / raw)
  To: Sasha Levin
  Cc: Jamie Iles, mingo, peterz, penberg, acme, paulus, linux-kernel

On Thu, Feb 07, 2013 at 09:31:22AM -0500, Sasha Levin wrote:
> On 02/07/2013 05:28 AM, Jamie Iles wrote:
> >> +int pthread_rwlock_init(pthread_rwlock_t *rwlock,
> >> > +			const pthread_rwlockattr_t *attr)
> >> > +{
> >> > +	if (ll_pthread_rwlock_init == NULL)
> >> > +		init_preload();
> > Why is this one special, doesn't init_preload being a constructor make 
> > this redundant?
> 
> I was testing it on different things, and stumbled on an interesting case:
> when pthread_mutex was taken from the constructor of a different module.
> 
> In that case, the other constructor would try to init the mutex and take
> a lock, but we would segfault because we haven't resolved the pthread
> symbols yet ourselves (since our constructor was yet to be called).

Okay, that makes sense, but shouldn't we do this for all of the lock 
operations?  pthread locks can be statically initialized and they are 
initializaed lazily on the first access so I think that this could 
happen on any of the lock operations.

Jamie

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

* Re: [PATCH 09/11] liblockdep: support using LD_PRELOAD
  2013-02-08 10:43       ` Jamie Iles
@ 2013-02-08 23:55         ` Sasha Levin
  0 siblings, 0 replies; 20+ messages in thread
From: Sasha Levin @ 2013-02-08 23:55 UTC (permalink / raw)
  To: Jamie Iles; +Cc: mingo, peterz, penberg, acme, paulus, linux-kernel

On 02/08/2013 05:43 AM, Jamie Iles wrote:
> On Thu, Feb 07, 2013 at 09:31:22AM -0500, Sasha Levin wrote:
>> On 02/07/2013 05:28 AM, Jamie Iles wrote:
>>>> +int pthread_rwlock_init(pthread_rwlock_t *rwlock,
>>>>> +			const pthread_rwlockattr_t *attr)
>>>>> +{
>>>>> +	if (ll_pthread_rwlock_init == NULL)
>>>>> +		init_preload();
>>> Why is this one special, doesn't init_preload being a constructor make 
>>> this redundant?
>>
>> I was testing it on different things, and stumbled on an interesting case:
>> when pthread_mutex was taken from the constructor of a different module.
>>
>> In that case, the other constructor would try to init the mutex and take
>> a lock, but we would segfault because we haven't resolved the pthread
>> symbols yet ourselves (since our constructor was yet to be called).
> 
> Okay, that makes sense, but shouldn't we do this for all of the lock 
> operations?  pthread locks can be statically initialized and they are 
> initializaed lazily on the first access so I think that this could 
> happen on any of the lock operations.

hmm... I've had it only in init() because I thought it doesn't make sense
to actually lock/unlock in constructor code, but yeah - better safe than
sorry.


Thanks,
Sasha


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

end of thread, other threads:[~2013-02-08 23:56 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-06 22:11 [PATCH 00/11] lockdep: LD_PRELOAD support Sasha Levin
2013-02-06 22:11 ` [PATCH 01/11] liblockdep: remove the need for liblockdep_init Sasha Levin
2013-02-06 22:11 ` [PATCH 02/11] liblockdep: remove the need for liblockdep_set_thread Sasha Levin
2013-02-06 22:11 ` [PATCH 03/11] perf: stop using liblockdep_init and liblockdep_set_thread Sasha Levin
2013-02-06 22:11 ` [PATCH 04/11] liblockdep: fix AA test Sasha Levin
2013-02-06 22:11 ` [PATCH 05/11] liblockdep: correct the ABCDBCDA test Sasha Levin
2013-02-06 22:11 ` [PATCH 06/11] liblockdep: rbtree support Sasha Levin
2013-02-06 22:11 ` [PATCH 07/11] liblockdep: prevent multiple declarations of CALLER_ADDR0 Sasha Levin
2013-02-06 22:11 ` [PATCH 08/11] liblockdep: keep headers declarations even if lib is disabled Sasha Levin
2013-02-06 22:11 ` [PATCH 09/11] liblockdep: support using LD_PRELOAD Sasha Levin
2013-02-07 10:28   ` Jamie Iles
2013-02-07 14:31     ` Sasha Levin
2013-02-08 10:43       ` Jamie Iles
2013-02-08 23:55         ` Sasha Levin
2013-02-06 22:11 ` [PATCH 10/11] liblockdep: add tests for the LD_PRELOAD feature Sasha Levin
2013-02-06 22:11 ` [PATCH 11/11] liblockdep: preload helper Sasha Levin
2013-02-07  6:19   ` Namhyung Kim
2013-02-07  6:55   ` Namhyung Kim
2013-02-07 14:29     ` Sasha Levin
2013-02-07  7:07 ` [PATCH 00/11] lockdep: LD_PRELOAD support Pekka Enberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).