From: Peter Zijlstra <peterz@infradead.org>
To: Sasha Levin <sasha.levin@oracle.com>
Cc: torvalds@linux-foundation.org, mingo@kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 2/9] liblockdep: Wrap kernel/lockdep.c to allow usage from userspace
Date: Wed, 8 May 2013 12:01:43 +0200 [thread overview]
Message-ID: <20130508100143.GA6131@dyad.programming.kicks-ass.net> (raw)
In-Reply-To: <1367348080-4680-3-git-send-email-sasha.levin@oracle.com>
On Tue, Apr 30, 2013 at 02:54:33PM -0400, Sasha Levin wrote:
> diff --git a/tools/lib/lockdep/common.c b/tools/lib/lockdep/common.c
> new file mode 100644
> index 0000000..eb5e481
> --- /dev/null
> +++ b/tools/lib/lockdep/common.c
> @@ -0,0 +1,33 @@
> +#include <stddef.h>
> +#include <stdbool.h>
> +#include <linux/compiler.h>
> +#include <linux/lockdep.h>
> +#include <unistd.h>
> +#include <sys/syscall.h>
> +
> +static struct task_struct current_obj;
> +
> +/* lockdep wants these */
> +bool debug_locks = true;
> +bool debug_locks_silent;
> +
> +__attribute__((constructor)) static void liblockdep_init(void)
> +{
> + lockdep_init();
> +}
> +
> +__attribute__((destructor)) static void liblockdep_exit(void)
> +{
> + debug_check_no_locks_held(¤t_obj);
> +}
> +
> +struct task_struct *__curr(void)
> +{
> + if (current_obj.pid == 0) {
> + /* Makes lockdep output pretty */
> + prctl(PR_GET_NAME, current_obj.comm);
> + current_obj.pid = syscall(__NR_gettid);
> + }
> +
> + return ¤t_obj;
> +}
> diff --git a/tools/lib/lockdep/uinclude/linux/lockdep.h b/tools/lib/lockdep/uinclude/linux/lockdep.h
> new file mode 100644
> index 0000000..8e9a5c4
> --- /dev/null
> +++ b/tools/lib/lockdep/uinclude/linux/lockdep.h
> @@ -0,0 +1,58 @@
> +#ifndef _LIBLOCKDEP_LOCKDEP_H_
> +#define _LIBLOCKDEP_LOCKDEP_H_
> +
> +#include <sys/prctl.h>
> +#include <sys/syscall.h>
> +#include <string.h>
> +#include <limits.h>
> +#include <linux/utsname.h>
> +
> +
> +#define MAX_LOCK_DEPTH 2000UL
> +
> +#include "../../../include/linux/lockdep.h"
> +
> +struct task_struct {
> + u64 curr_chain_key;
> + int lockdep_depth;
> + unsigned int lockdep_recursion;
> + struct held_lock held_locks[MAX_LOCK_DEPTH];
> + gfp_t lockdep_reclaim_gfp;
> + int pid;
> + char comm[17];
> +};
> +
> +extern struct task_struct *__curr(void);
> +
> +#define current (__curr())
> +
> +#define debug_locks_off() 1
> +#define task_pid_nr(tsk) ((tsk)->pid)
> +
> +#define KSYM_NAME_LEN 128
> +#define printk printf
> +
> +#define KERN_ERR
> +#define KERN_CONT
> +
> +#define list_del_rcu list_del
> +
> +#define atomic_t unsigned long
> +#define atomic_inc(x) ((*(x))++)
> +
> +static struct new_utsname *init_utsname(void)
> +{
> + static struct new_utsname n = (struct new_utsname) {
> + .release = "liblockdep",
> + .version = LIBLOCKDEP_VERSION,
> + };
> +
> + return &n;
> +}
> +
> +#define print_tainted() ""
> +#define static_obj(x) 1
> +
> +#define debug_show_all_locks()
> +
> +#endif
I don't see how this could possible work for threaded programs; you only have a
single task_struct instance. Wouldn't you need something like the below?
---
static int (*pthread_create_orig)(pthread_t *__restrict,
__const pthread_attr_t *__restrict,
void *(*)(void *),
void *__restrict) = NULL;
static __thread struct task_struct __current;
#define current (&__current)
static void sched_fork(void)
{
/* init __current */
}
__attribute__((constructor)) static void sched_init(void)
{
pthread_create_orig = dlsym(RTLD_NEXT, "pthread_create");
if (!pthread_create_orig) {
char *error = dlerror();
if (!error)
error = "pthread_create is NULL";
die("%s\n", error);
}
sched_fork(); /* main thread */
}
__attribute__((destructor)) static void sched_exit(void)
{
/* */
}
struct tramp_data {
void *(*func)(void *);
void *arg;
pthread_mutex_t lock;
pthread_cond_t wait;
};
static void *tramp_func(void *data)
{
struct tramp_data *tramp_data = data;
void *(*func)(void *) = tramp_data->func;
void *arg = tramp_data->arg;
sched_fork();
pthread_mutex_lock(&tramp_data->lock);
pthread_cond_signal(&tramp_data->wait);
pthread_mutex_unlock(&tramp_data->lock);
return func(arg);
}
/* hijack pthread_create() */
int pthread_create(pthread_t *__restrict thread,
__const pthread_attr_t *__restrict attr,
void *(*func)(void *),
void *__restrict arg)
{
struct tramp_data tramp_data = {
.func = func,
.arg = arg,
};
int ret;
pthread_cond_init(&tramp_data.wait, NULL);
pthread_mutex_init(&tramp_data.lock, NULL);
pthread_mutex_lock(&tramp_data.lock);
ret = pthread_create_orig(thread, attr, &tramp_func, &tramp_data);
if (!ret)
pthread_cond_wait(&tramp_data.wait, &tramp_data.lock);
pthread_mutex_unlock(&tramp_data.lock);
pthread_mutex_destroy(&tramp_data.lock);
pthread_cond_destroy(&tramp_data.wait);
return ret;
}
next prev parent reply other threads:[~2013-05-08 10:03 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-30 18:54 [PATCH 0/9] liblockdep: userspace lockdep Sasha Levin
2013-04-30 18:54 ` [PATCH 1/9] lockdep: Be nice about building from userspace Sasha Levin
2013-04-30 18:54 ` [PATCH 2/9] liblockdep: Wrap kernel/lockdep.c to allow usage " Sasha Levin
2013-05-08 10:01 ` Peter Zijlstra [this message]
2013-05-08 13:27 ` Sasha Levin
2013-05-08 13:35 ` Peter Zijlstra
2013-05-08 13:53 ` Sasha Levin
2013-04-30 18:54 ` [PATCH 3/9] liblockdep: Add public headers for pthread_mutex_t implementation Sasha Levin
2013-04-30 18:54 ` [PATCH 4/9] liblockdep: Add pthread_mutex_t test suite Sasha Levin
2013-04-30 18:54 ` [PATCH 5/9] liblockdep: Add public headers for pthread_rwlock_t implementation Sasha Levin
2013-04-30 18:54 ` [PATCH 6/9] liblockdep: Add pthread_rwlock_t test suite Sasha Levin
2013-04-30 18:54 ` [PATCH 7/9] liblockdep: Support using LD_PRELOAD Sasha Levin
2013-05-08 10:22 ` Peter Zijlstra
2013-05-08 13:29 ` Sasha Levin
2013-04-30 18:54 ` [PATCH 8/9] liblockdep: Add the 'lockdep' user-space utility Sasha Levin
2013-04-30 18:54 ` [PATCH 9/9] liblockdep: Add a MAINTAINERS entry Sasha Levin
2013-05-07 16:15 ` [PATCH 0/9] liblockdep: userspace lockdep Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130508100143.GA6131@dyad.programming.kicks-ass.net \
--to=peterz@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=sasha.levin@oracle.com \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox