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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.