This patch modifies these two initialize sequences
for adding __FILE__ and __LINE__ to lockdep_map.
Signed-off-by: Hitoshi Mitake <mit...@dcl.info.waseda.ac.jp>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
---
include/linux/rwlock.h | 6 ++++--
include/linux/rwlock_types.h | 6 +++++-
lib/spinlock_debug.c | 6 ++++--
3 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/include/linux/rwlock.h b/include/linux/rwlock.h
index 71e0b00..cdef180 100644
--- a/include/linux/rwlock.h
+++ b/include/linux/rwlock.h
@@ -16,12 +16,14 @@
#ifdef CONFIG_DEBUG_SPINLOCK
extern void __rwlock_init(rwlock_t *lock, const char *name,
- struct lock_class_key *key);
+ struct lock_class_key *key,
+ const char *file, unsigned int line);
# define rwlock_init(lock) \
do { \
static struct lock_class_key __key; \
\
- __rwlock_init((lock), #lock, &__key); \
+ __rwlock_init((lock), #lock, &__key, \
+ __FILE__, __LINE__); \
} while (0)
#else
# define rwlock_init(lock) \
diff --git a/include/linux/rwlock_types.h b/include/linux/rwlock_types.h
index bd31808..e5e70c4 100644
--- a/include/linux/rwlock_types.h
+++ b/include/linux/rwlock_types.h
@@ -25,7 +25,11 @@ typedef struct {
#define RWLOCK_MAGIC 0xdeaf1eed
#ifdef CONFIG_DEBUG_LOCK_ALLOC
-# define RW_DEP_MAP_INIT(lockname) .dep_map = { .name = #lockname }
+# define RW_DEP_MAP_INIT(lockname) .dep_map = { \
+ .name = #lockname, \
+ .file = __FILE__, \
+ .line = __LINE__, \
+ }
#else
# define RW_DEP_MAP_INIT(lockname)
#endif
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c
index 81fa789..1cdae8b 100644
--- a/lib/spinlock_debug.c
+++ b/lib/spinlock_debug.c
@@ -34,14 +34,16 @@ void __raw_spin_lock_init(raw_spinlock_t *lock, const char *name,
EXPORT_SYMBOL(__raw_spin_lock_init);
void __rwlock_init(rwlock_t *lock, const char *name,
- struct lock_class_key *key)
+ struct lock_class_key *key,
+ const char *file, unsigned int line)
{
#ifdef CONFIG_DEBUG_LOCK_ALLOC
/*
* Make sure we are not reinitializing a held lock:
*/
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
- lockdep_init_map(&lock->dep_map, name, key, 0);
+ __lockdep_init_map(&lock->dep_map, name, key, 0,
+ file, line);
#endif
lock->raw_lock = (arch_rwlock_t) __ARCH_RW_LOCK_UNLOCKED;
lock->magic = RWLOCK_MAGIC;
--
1.6.5.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
util/include/linuxhash.h includes linux/hash.h, so we can use
hash facilities (e.g. hash_long()) in perf now.
Signed-off-by: Hitoshi Mitake <mit...@dcl.info.waseda.ac.jp>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
---
tools/perf/Makefile | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 9b173e6..b2bce1f 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -333,6 +333,7 @@ LIB_FILE=libperf.a
LIB_H += ../../include/linux/perf_event.h
LIB_H += ../../include/linux/rbtree.h
LIB_H += ../../include/linux/list.h
+LIB_H += ../../include/linux/hash.h
LIB_H += ../../include/linux/stringify.h
LIB_H += util/include/linux/bitmap.h
LIB_H += util/include/linux/bitops.h
Signed-off-by: Hitoshi Mitake <mit...@dcl.info.waseda.ac.jp>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
---
include/linux/rwsem-spinlock.h | 11 ++++++++---
lib/rwsem-spinlock.c | 5 +++--
lib/rwsem.c | 5 +++--
3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/include/linux/rwsem-spinlock.h b/include/linux/rwsem-spinlock.h
index bdfcc25..53f68e6 100644
--- a/include/linux/rwsem-spinlock.h
+++ b/include/linux/rwsem-spinlock.h
@@ -38,7 +38,11 @@ struct rw_semaphore {
};
#ifdef CONFIG_DEBUG_LOCK_ALLOC
-# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname }
+# define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { \
+ .file = __FILE__, \
+ .line = __LINE__, \
+ .name = #lockname, \
+ }
#else
# define __RWSEM_DEP_MAP_INIT(lockname)
#endif
@@ -51,13 +55,14 @@ struct rw_semaphore {
struct rw_semaphore name = __RWSEM_INITIALIZER(name)
extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
- struct lock_class_key *key);
+ struct lock_class_key *key,
+ const char *file, unsigned int line);
#define init_rwsem(sem) \
do { \
static struct lock_class_key __key; \
\
- __init_rwsem((sem), #sem, &__key); \
+ __init_rwsem((sem), #sem, &__key, __FILE__, __LINE__); \
} while (0)
extern void __down_read(struct rw_semaphore *sem);
diff --git a/lib/rwsem-spinlock.c b/lib/rwsem-spinlock.c
index ccf95bf..4aceeb4 100644
--- a/lib/rwsem-spinlock.c
+++ b/lib/rwsem-spinlock.c
@@ -34,14 +34,15 @@ EXPORT_SYMBOL(rwsem_is_locked);
* initialise the semaphore
*/
void __init_rwsem(struct rw_semaphore *sem, const char *name,
- struct lock_class_key *key)
+ struct lock_class_key *key,
+ const char *file, unsigned int line)
{
#ifdef CONFIG_DEBUG_LOCK_ALLOC
/*
* Make sure we are not reinitializing a held semaphore:
*/
debug_check_no_locks_freed((void *)sem, sizeof(*sem));
- lockdep_init_map(&sem->dep_map, name, key, 0);
+ __lockdep_init_map(&sem->dep_map, name, key, 0, file, line);
#endif
sem->activity = 0;
spin_lock_init(&sem->wait_lock);
diff --git a/lib/rwsem.c b/lib/rwsem.c
index 3e3365e..3f8d5cd 100644
--- a/lib/rwsem.c
+++ b/lib/rwsem.c
@@ -12,14 +12,15 @@
* Initialize an rwsem:
*/
void __init_rwsem(struct rw_semaphore *sem, const char *name,
- struct lock_class_key *key)
+ struct lock_class_key *key,
+ const char *file, unsigned int line)
{
#ifdef CONFIG_DEBUG_LOCK_ALLOC
/*
* Make sure we are not reinitializing a held semaphore:
*/
debug_check_no_locks_freed((void *)sem, sizeof(*sem));
- lockdep_init_map(&sem->dep_map, name, key, 0);
+ __lockdep_init_map(&sem->dep_map, name, key, 0, file, line);
#endif
sem->count = RWSEM_UNLOCKED_VALUE;
spin_lock_init(&sem->wait_lock);
Signed-off-by: Hitoshi Mitake <mit...@dcl.info.waseda.ac.jp>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
---
include/trace/events/lock.h | 49 ++++++++++++++++++++++++++++++++++--------
1 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/include/trace/events/lock.h b/include/trace/events/lock.h
index a870ba1..3eef226 100644
--- a/include/trace/events/lock.h
+++ b/include/trace/events/lock.h
@@ -20,16 +20,23 @@ TRACE_EVENT(lock_acquire,
TP_STRUCT__entry(
__field(unsigned int, flags)
__string(name, lock->name)
+ __field(void *, lockdep_addr)
+ __string(file, lock->file)
+ __field(unsigned int, line)
),
TP_fast_assign(
__entry->flags = (trylock ? 1 : 0) | (read ? 2 : 0);
__assign_str(name, lock->name);
+ __entry->lockdep_addr = lock;
+ __assign_str(file, lock->file);
+ __entry->line = lock->line;
),
- TP_printk("%s%s%s", (__entry->flags & 1) ? "try " : "",
+ TP_printk("%p %s%s%s %s:%u", __entry->lockdep_addr,
+ (__entry->flags & 1) ? "try " : "",
(__entry->flags & 2) ? "read " : "",
- __get_str(name))
+ __get_str(name), __get_str(file), __entry->line)
);
TRACE_EVENT(lock_release,
@@ -40,13 +47,21 @@ TRACE_EVENT(lock_release,
TP_STRUCT__entry(
__string(name, lock->name)
+ __field(void *, lockdep_addr)
+ __string(file, lock->file)
+ __field(unsigned int, line)
),
TP_fast_assign(
__assign_str(name, lock->name);
+ __entry->lockdep_addr = lock;
+ __assign_str(file, lock->file);
+ __entry->line = lock->line;
),
- TP_printk("%s", __get_str(name))
+ TP_printk("%p %s %s:%u",
+ __entry->lockdep_addr, __get_str(name),
+ __get_str(file), __entry->line)
);
#ifdef CONFIG_LOCK_STAT
@@ -59,13 +74,21 @@ TRACE_EVENT(lock_contended,
TP_STRUCT__entry(
__string(name, lock->name)
+ __field(void *, lockdep_addr)
+ __string(file, lock->file)
+ __field(unsigned int, line)
),
TP_fast_assign(
__assign_str(name, lock->name);
+ __entry->lockdep_addr = lock;
+ __assign_str(file, lock->file);
+ __entry->line = lock->line;
),
- TP_printk("%s", __get_str(name))
+ TP_printk("%p %s %s:%u",
+ __entry->lockdep_addr, __get_str(name),
+ __get_str(file), __entry->line)
);
TRACE_EVENT(lock_acquired,
@@ -75,16 +98,22 @@ TRACE_EVENT(lock_acquired,
TP_STRUCT__entry(
__string(name, lock->name)
- __field(unsigned long, wait_usec)
- __field(unsigned long, wait_nsec_rem)
+ __field(s64, wait_nsec)
+ __field(void *, lockdep_addr)
+ __string(file, lock->file)
+ __field(unsigned int, line)
),
+
TP_fast_assign(
__assign_str(name, lock->name);
- __entry->wait_nsec_rem = do_div(waittime, NSEC_PER_USEC);
- __entry->wait_usec = (unsigned long) waittime;
+ __entry->wait_nsec = waittime;
+ __entry->lockdep_addr = lock;
+ __assign_str(file, lock->file);
+ __entry->line = lock->line;
),
- TP_printk("%s (%lu.%03lu us)", __get_str(name), __entry->wait_usec,
- __entry->wait_nsec_rem)
+ TP_printk("%p %s %s:%u (%llu ns)", __entry->lockdep_addr,
+ __get_str(name), __get_str(file), __entry->line,
+ __entry->wait_nsec)
);
#endif
At 064739bc4b3d7f424b2f25547e6611bcf0132415 ,
support for the modifier "__data_loc" of format is added.
But, when I wanted to parse format of lock_acquired (or some
event else), raw_field_ptr() did not returned correct pointer.
So I modified raw_field_ptr() like this patch. Then
raw_field_ptr() works well.
Signed-off-by: Hitoshi Mitake <mit...@dcl.info.waseda.ac.jp>
Acked-by: Frederic Weisbecker <fwei...@gmail.com>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Tom Zanussi <tzan...@gmail.com>
Cc: Steven Rostedt <sros...@redhat.com>
---
tools/perf/util/trace-event-parse.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index c5c32be..13aea80 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -1925,6 +1925,13 @@ void *raw_field_ptr(struct event *event, const char *name, void *data)
if (!field)
return NULL;
+ if (field->flags & FIELD_IS_STRING) {
+ int offset;
+ offset = *(int *)(data + field->offset);
+ offset &= 0xffff;
+ return data + offset;
+ }
+
return data + field->offset;
Signed-off-by: Hitoshi Mitake <mit...@dcl.info.waseda.ac.jp>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Frederic Weisbecker <fwei...@gmail.com>
---
include/linux/mutex-debug.h | 2 +-
include/linux/mutex.h | 12 +++++++++---
kernel/mutex-debug.c | 5 +++--
kernel/mutex-debug.h | 3 ++-
kernel/mutex.c | 5 +++--
kernel/mutex.h | 2 +-
6 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/include/linux/mutex-debug.h b/include/linux/mutex-debug.h
index 731d77d..f86bf4e 100644
--- a/include/linux/mutex-debug.h
+++ b/include/linux/mutex-debug.h
@@ -15,7 +15,7 @@
do { \
static struct lock_class_key __key; \
\
- __mutex_init((mutex), #mutex, &__key); \
+ __mutex_init((mutex), #mutex, &__key, __FILE__, __LINE__); \
} while (0)
extern void mutex_destroy(struct mutex *lock);
diff --git a/include/linux/mutex.h b/include/linux/mutex.h
index 878cab4..ce9082a 100644
--- a/include/linux/mutex.h
+++ b/include/linux/mutex.h
@@ -82,14 +82,19 @@ struct mutex_waiter {
do { \
static struct lock_class_key __key; \
\
- __mutex_init((mutex), #mutex, &__key); \
+ __mutex_init((mutex), #mutex, &__key, \
+ __FILE__, __LINE__); \
} while (0)
# define mutex_destroy(mutex) do { } while (0)
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define __DEP_MAP_MUTEX_INITIALIZER(lockname) \
- , .dep_map = { .name = #lockname }
+ , .dep_map = { \
+ .file = __FILE__, \
+ .line = __LINE__, \
+ .name = #lockname, \
+ }
#else
# define __DEP_MAP_MUTEX_INITIALIZER(lockname)
#endif
@@ -105,7 +110,8 @@ do { \
struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
extern void __mutex_init(struct mutex *lock, const char *name,
- struct lock_class_key *key);
+ struct lock_class_key *key,
+ const char *file, unsigned int line);
/**
* mutex_is_locked - is the mutex locked
diff --git a/kernel/mutex-debug.c b/kernel/mutex-debug.c
index ec815a9..4a1321b 100644
--- a/kernel/mutex-debug.c
+++ b/kernel/mutex-debug.c
@@ -81,14 +81,15 @@ void debug_mutex_unlock(struct mutex *lock)
}
void debug_mutex_init(struct mutex *lock, const char *name,
- struct lock_class_key *key)
+ struct lock_class_key *key,
+ const char *file, unsigned int line)
{
#ifdef CONFIG_DEBUG_LOCK_ALLOC
/*
* Make sure we are not reinitializing a held lock:
*/
debug_check_no_locks_freed((void *)lock, sizeof(*lock));
- lockdep_init_map(&lock->dep_map, name, key, 0);
+ __lockdep_init_map(&lock->dep_map, name, key, 0, file, line);
#endif
lock->magic = lock;
}
diff --git a/kernel/mutex-debug.h b/kernel/mutex-debug.h
index 57d527a..154a909 100644
--- a/kernel/mutex-debug.h
+++ b/kernel/mutex-debug.h
@@ -25,7 +25,8 @@ extern void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
struct thread_info *ti);
extern void debug_mutex_unlock(struct mutex *lock);
extern void debug_mutex_init(struct mutex *lock, const char *name,
- struct lock_class_key *key);
+ struct lock_class_key *key,
+ const char *file, unsigned int line);
static inline void mutex_set_owner(struct mutex *lock)
{
diff --git a/kernel/mutex.c b/kernel/mutex.c
index 632f04c..80e3876 100644
--- a/kernel/mutex.c
+++ b/kernel/mutex.c
@@ -46,14 +46,15 @@
* It is not allowed to initialize an already locked mutex.
*/
void
-__mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key)
+__mutex_init(struct mutex *lock, const char *name, struct lock_class_key *key,
+ const char *file, unsigned int line)
{
atomic_set(&lock->count, 1);
spin_lock_init(&lock->wait_lock);
INIT_LIST_HEAD(&lock->wait_list);
mutex_clear_owner(lock);
- debug_mutex_init(lock, name, key);
+ debug_mutex_init(lock, name, key, file, line);
}
EXPORT_SYMBOL(__mutex_init);
diff --git a/kernel/mutex.h b/kernel/mutex.h
index 67578ca..81914e6 100644
--- a/kernel/mutex.h
+++ b/kernel/mutex.h
@@ -40,7 +40,7 @@ static inline void mutex_clear_owner(struct mutex *lock)
#define debug_mutex_free_waiter(waiter) do { } while (0)
#define debug_mutex_add_waiter(lock, waiter, ti) do { } while (0)
#define debug_mutex_unlock(lock) do { } while (0)
-#define debug_mutex_init(lock, name, key) do { } while (0)
+#define debug_mutex_init(lock, name, key, file, line) do { } while (0)
static inline void
debug_mutex_lock_common(struct mutex *lock, struct mutex_waiter *waiter)
This patch is required for making "perf lock rec" work.
The commit f5a2c3dce0 changes write_event() of builtin-record.c .
And changed write_event() sometimes doesn't stop with perf lock rec.
I'm researching what makes write_event() loop infinity,
and noticed that there are some events with event_t->header.size == 0.
But the detail of the problem,
like kind of these events, isn't clear...
If you know something related to this problem,
could you tell me, Arnaldo?
Signed-off-by: Hitoshi Mitake <mit...@dcl.info.waseda.ac.jp>
Cc: Frédéric Weisbecker <fwei...@gmail.com>
Cc: Mike Galbraith <efa...@gmx.de>
Cc: Peter Zijlstra <a.p.zi...@chello.nl>
Cc: Paul Mackerras <pau...@samba.org>
---
tools/perf/builtin-record.c | 28 ++++++++++------------------
1 files changed, 10 insertions(+), 18 deletions(-)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 7bb9ca1..614fa9a 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -113,24 +113,16 @@ static void write_output(void *buf, size_t size)
static void write_event(event_t *buf, size_t size)
{
- size_t processed_size = buf->header.size;
- event_t *ev = buf;
-
- do {
- /*
- * Add it to the list of DSOs, so that when we finish this
- * record session we can pick the available build-ids.
- */
- if (ev->header.type == PERF_RECORD_MMAP) {
- struct list_head *head = &dsos__user;
- if (ev->header.misc == 1)
- head = &dsos__kernel;
- __dsos__findnew(head, ev->mmap.filename);
- }
-
- ev = ((void *)ev) + ev->header.size;
- processed_size += ev->header.size;
- } while (processed_size < size);
+ /*
+ * Add it to the list of DSOs, so that when we finish this
+ * record session we can pick the available build-ids.
+ */
+ if (buf->header.type == PERF_RECORD_MMAP) {
+ struct list_head *head = &dsos__user;
+ if (buf->mmap.header.misc == 1)
+ head = &dsos__kernel;
+ __dsos__findnew(head, buf->mmap.filename);
+ }
write_output(buf, size);
Well, this will have to wait for somebody to remove the need for
intercepting those events, reverting this patch fixes your tool while
breaking others that then won't catch all the events.
I'll get 'perf regtest' out with some initial tests then try to get some
proposal for injecting the buildid, if found in a DSO, via
PERF_RECORD_MMAP, lets see how this goes...
Best Regards,
- Arnaldo
BTW: I took longer to send a response to this question addressed to me
because I wasn't on the CC list :-)
Yes, this patch is too egoistic thing and temporary solution.
I have to consider and modify 'perf lock'.
>
> I'll get 'perf regtest' out with some initial tests then try to get some
> proposal for injecting the buildid, if found in a DSO, via
> PERF_RECORD_MMAP, lets see how this goes...
What does "DSO" mean? Sorry, I'm not good at English...
>
> Best Regards,
>
> - Arnaldo
>
> BTW: I took longer to send a response to this question addressed to me
> because I wasn't on the CC list :-)
>
>
Oh, sorry... I wonder why I didn't add you to Cc or To :(
It is completely my mistake, and thanks for your reply!
Thanks
Hitoshi
Dynamic Shared Object, basically dynamic executables and .so files.
Hey, don't get me wrong, the situation is fragile, either way something
will get broken and that isn't your fault, its just that we need some
sensible and non racy way to inject the buildids at 'perf record' time.
The way I did it, long ago, intercepting events in 'perf record' to
build a DSO list to then at 'perf record' exit to insert a table at the
perf.data file header looks too intrusive now, so we need some other way
that doesn't have this problem and its not racy.
> > I'll get 'perf regtest' out with some initial tests then try to get some
> > proposal for injecting the buildid, if found in a DSO, via
> > PERF_RECORD_MMAP, lets see how this goes...
>
> What does "DSO" mean? Sorry, I'm not good at English...
As Peter said, anything that that is on an executable MMAP.
> >
> > Best Regards,
> >
> > - Arnaldo
> >
> > BTW: I took longer to send a response to this question addressed to me
> > because I wasn't on the CC list :-)
>
> Oh, sorry... I wonder why I didn't add you to Cc or To :(
> It is completely my mistake, and thanks for your reply!
:-) Best Regards,
- Arnaldo
Thanks for correcting my misunderstand :)
>
> The way I did it, long ago, intercepting events in 'perf record' to
> build a DSO list to then at 'perf record' exit to insert a table at the
> perf.data file header looks too intrusive now, so we need some other way
> that doesn't have this problem and its not racy.
I see. I'll look some other way, too.
Or if you find it, could you tell me?
>
>> > I'll get 'perf regtest' out with some initial tests then try to get some
>> > proposal for injecting the buildid, if found in a DSO, via
>> > PERF_RECORD_MMAP, lets see how this goes...
>>
>> What does "DSO" mean? Sorry, I'm not good at English...
>
> As Peter said, anything that that is on an executable MMAP.
I understood :) Thanks, Peter and Arnaldo.
Thanks,
Hitoshi