]> git.openpandora.org Git - pandora-kernel.git/commitdiff
liblockdep: Wrap kernel/locking/lockdep.c to allow usage from userspace
authorSasha Levin <sasha.levin@oracle.com>
Thu, 13 Jun 2013 22:41:17 +0000 (18:41 -0400)
committerIngo Molnar <mingo@kernel.org>
Wed, 27 Nov 2013 10:55:21 +0000 (11:55 +0100)
kernel/locking/lockdep.c deals with validating locking scenarios for
various architectures supported by the kernel. There isn't
anything kernel specific going on in lockdep, and when we
compare userspace to other architectures that don't have to deal
with irqs such as s390, they become all too similar.

We wrap kernel/locking/lockdep.c and include/linux/lockdep.h with
several headers which allow us to build and use lockdep from
userspace. We don't touch the kernel code itself which means
that any work done on lockdep in the kernel will automatically
benefit userspace lockdep as well!

Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Cc: torvalds@linux-foundation.org
Link: http://lkml.kernel.org/r/1371163284-6346-3-git-send-email-sasha.levin@oracle.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
40 files changed:
tools/lib/lockdep/Makefile [new file with mode: 0644]
tools/lib/lockdep/common.c [new file with mode: 0644]
tools/lib/lockdep/lockdep.c [new file with mode: 0644]
tools/lib/lockdep/lockdep_internals.h [new file with mode: 0644]
tools/lib/lockdep/lockdep_states.h [new file with mode: 0644]
tools/lib/lockdep/rbtree.c [new file with mode: 0644]
tools/lib/lockdep/uinclude/asm/hweight.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/asm/sections.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/bitops.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/compiler.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/debug_locks.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/delay.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/export.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/ftrace.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/gfp.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/hardirq.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/hash.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/interrupt.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/irqflags.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/kallsyms.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/kern_levels.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/kernel.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/kmemcheck.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/linkage.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/list.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/lockdep.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/module.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/mutex.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/poison.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/prefetch.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/proc_fs.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/rbtree.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/rbtree_augmented.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/rcu.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/seq_file.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/spinlock.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/stacktrace.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/stringify.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/linux/types.h [new file with mode: 0644]
tools/lib/lockdep/uinclude/trace/events/lock.h [new file with mode: 0644]

diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile
new file mode 100644 (file)
index 0000000..da8b7aa
--- /dev/null
@@ -0,0 +1,251 @@
+# liblockdep version
+LL_VERSION = 0
+LL_PATCHLEVEL = 0
+LL_EXTRAVERSION = 1
+
+# file format version
+FILE_VERSION = 1
+
+MAKEFLAGS += --no-print-directory
+
+
+# Makefiles suck: This macro sets a default value of $(2) for the
+# variable named by $(1), unless the variable has been set by
+# environment or command line. This is necessary for CC and AR
+# because make sets default values, so the simpler ?= approach
+# won't work as expected.
+define allow-override
+  $(if $(or $(findstring environment,$(origin $(1))),\
+            $(findstring command line,$(origin $(1)))),,\
+    $(eval $(1) = $(2)))
+endef
+
+# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
+$(call allow-override,CC,$(CROSS_COMPILE)gcc)
+$(call allow-override,AR,$(CROSS_COMPILE)ar)
+
+INSTALL = install
+
+# Use DESTDIR for installing into a different root directory.
+# This is useful for building a package. The program will be
+# installed in this directory as if it was the root directory.
+# Then the build tool can move it later.
+DESTDIR ?=
+DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))'
+
+prefix ?= /usr/local
+libdir_relative = lib
+libdir = $(prefix)/$(libdir_relative)
+bindir_relative = bin
+bindir = $(prefix)/$(bindir_relative)
+
+export DESTDIR DESTDIR_SQ INSTALL
+
+# copy a bit from Linux kbuild
+
+ifeq ("$(origin V)", "command line")
+  VERBOSE = $(V)
+endif
+ifndef VERBOSE
+  VERBOSE = 0
+endif
+
+ifeq ("$(origin O)", "command line")
+  BUILD_OUTPUT := $(O)
+endif
+
+ifeq ($(BUILD_SRC),)
+ifneq ($(BUILD_OUTPUT),)
+
+define build_output
+       $(if $(VERBOSE:1=),@)$(MAKE) -C $(BUILD_OUTPUT) \
+       BUILD_SRC=$(CURDIR) -f $(CURDIR)/Makefile $1
+endef
+
+saved-output := $(BUILD_OUTPUT)
+BUILD_OUTPUT := $(shell cd $(BUILD_OUTPUT) && /bin/pwd)
+$(if $(BUILD_OUTPUT),, \
+     $(error output directory "$(saved-output)" does not exist))
+
+all: sub-make
+
+gui: force
+       $(call build_output, all_cmd)
+
+$(filter-out gui,$(MAKECMDGOALS)): sub-make
+
+sub-make: force
+       $(call build_output, $(MAKECMDGOALS))
+
+
+# Leave processing to above invocation of make
+skip-makefile := 1
+
+endif # BUILD_OUTPUT
+endif # BUILD_SRC
+
+# We process the rest of the Makefile if this is the final invocation of make
+ifeq ($(skip-makefile),)
+
+srctree                := $(if $(BUILD_SRC),$(BUILD_SRC),$(CURDIR))
+objtree                := $(CURDIR)
+src            := $(srctree)
+obj            := $(objtree)
+
+export prefix libdir bindir src obj
+
+# Shell quotes
+libdir_SQ = $(subst ','\'',$(libdir))
+bindir_SQ = $(subst ','\'',$(bindir))
+
+LIB_FILE = liblockdep.a liblockdep.so
+BIN_FILE = lockdep
+
+CONFIG_INCLUDES =
+CONFIG_LIBS    =
+CONFIG_FLAGS   =
+
+OBJ            = $@
+N              =
+
+export Q VERBOSE
+
+LIBLOCKDEP_VERSION = $(LL_VERSION).$(LL_PATCHLEVEL).$(LL_EXTRAVERSION)
+
+INCLUDES = -I. -I/usr/local/include -I./uinclude $(CONFIG_INCLUDES)
+
+# Set compile option CFLAGS if not set elsewhere
+CFLAGS ?= -g -DCONFIG_LOCKDEP -DCONFIG_STACKTRACE -DCONFIG_PROVE_LOCKING -DBITS_PER_LONG=__WORDSIZE -DLIBLOCKDEP_VERSION='"$(LIBLOCKDEP_VERSION)"' -rdynamic -O0 -g
+
+override CFLAGS += $(CONFIG_FLAGS) $(INCLUDES) $(PLUGIN_DIR_SQ)
+
+ifeq ($(VERBOSE),1)
+  Q =
+  print_compile =
+  print_app_build =
+  print_fpic_compile =
+  print_shared_lib_compile =
+  print_install =
+else
+  Q = @
+  print_compile =              echo '  CC                 '$(OBJ);
+  print_app_build =            echo '  BUILD              '$(OBJ);
+  print_fpic_compile =         echo '  CC FPIC            '$(OBJ);
+  print_shared_lib_compile =   echo '  BUILD SHARED LIB   '$(OBJ);
+  print_static_lib_build =     echo '  BUILD STATIC LIB   '$(OBJ);
+  print_install =              echo '  INSTALL     '$1'        to      $(DESTDIR_SQ)$2';
+endif
+
+do_fpic_compile =                                      \
+       ($(print_fpic_compile)                          \
+       $(CC) -c $(CFLAGS) $(EXT) -fPIC $< -o $@)
+
+do_app_build =                                         \
+       ($(print_app_build)                             \
+       $(CC) $^ -rdynamic -o $@ $(CONFIG_LIBS) $(LIBS))
+
+do_compile_shared_library =                    \
+       ($(print_shared_lib_compile)            \
+       $(CC) --shared $^ -o $@ -lpthread -ldl)
+
+do_build_static_lib =                          \
+       ($(print_static_lib_build)              \
+       $(RM) $@;  $(AR) rcs $@ $^)
+
+
+define do_compile
+       $(print_compile)                                                \
+       $(CC) -c $(CFLAGS) $(EXT) $< -o $(obj)/$@;
+endef
+
+$(obj)/%.o: $(src)/%.c
+       $(Q)$(call do_compile)
+
+%.o: $(src)/%.c
+       $(Q)$(call do_compile)
+
+PEVENT_LIB_OBJS = common.o lockdep.o preload.o rbtree.o
+
+ALL_OBJS = $(PEVENT_LIB_OBJS)
+
+CMD_TARGETS = $(LIB_FILE)
+
+TARGETS = $(CMD_TARGETS)
+
+
+all: all_cmd
+
+all_cmd: $(CMD_TARGETS)
+
+liblockdep.so: $(PEVENT_LIB_OBJS)
+       $(Q)$(do_compile_shared_library)
+
+liblockdep.a: $(PEVENT_LIB_OBJS)
+       $(Q)$(do_build_static_lib)
+
+$(PEVENT_LIB_OBJS): %.o: $(src)/%.c
+       $(Q)$(do_fpic_compile)
+
+## make deps
+
+all_objs := $(sort $(ALL_OBJS))
+all_deps := $(all_objs:%.o=.%.d)
+
+# let .d file also depends on the source and header files
+define check_deps
+               @set -e; $(RM) $@; \
+               $(CC) -MM $(CFLAGS) $< > $@.$$$$; \
+               sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+               $(RM) $@.$$$$
+endef
+
+$(all_deps): .%.d: $(src)/%.c
+       $(Q)$(call check_deps)
+
+$(all_objs) : %.o : .%.d
+
+dep_includes := $(wildcard $(all_deps))
+
+ifneq ($(dep_includes),)
+ include $(dep_includes)
+endif
+
+### Detect environment changes
+TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):$(ARCH):$(CROSS_COMPILE)
+
+tags:  force
+       $(RM) tags
+       find . -name '*.[ch]' | xargs ctags --extra=+f --c-kinds=+px \
+       --regex-c++='/_PE\(([^,)]*).*/PEVENT_ERRNO__\1/'
+
+TAGS:  force
+       $(RM) TAGS
+       find . -name '*.[ch]' | xargs etags \
+       --regex='/_PE(\([^,)]*\).*/PEVENT_ERRNO__\1/'
+
+define do_install
+       $(print_install)                                \
+       if [ ! -d '$(DESTDIR_SQ)$2' ]; then             \
+               $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \
+       fi;                                             \
+       $(INSTALL) $1 '$(DESTDIR_SQ)$2'
+endef
+
+install_lib: all_cmd
+       $(Q)$(call do_install,$(LIB_FILE),$(libdir_SQ))
+       $(Q)$(call do_install,$(BIN_FILE),$(bindir_SQ))
+
+install: install_lib
+
+clean:
+       $(RM) *.o *~ $(TARGETS) *.a *.so $(VERSION_FILES) .*.d
+       $(RM) tags TAGS
+
+endif # skip-makefile
+
+PHONY += force
+force:
+
+# Declare the contents of the .PHONY variable as phony.  We keep that
+# information in a variable so we can use it in if_changed and friends.
+.PHONY: $(PHONY)
diff --git a/tools/lib/lockdep/common.c b/tools/lib/lockdep/common.c
new file mode 100644 (file)
index 0000000..8ef602f
--- /dev/null
@@ -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 __thread 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(&current_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 &current_obj;
+}
diff --git a/tools/lib/lockdep/lockdep.c b/tools/lib/lockdep/lockdep.c
new file mode 100644 (file)
index 0000000..f42b7e9
--- /dev/null
@@ -0,0 +1,2 @@
+#include <linux/lockdep.h>
+#include "../../../kernel/locking/lockdep.c"
diff --git a/tools/lib/lockdep/lockdep_internals.h b/tools/lib/lockdep/lockdep_internals.h
new file mode 100644 (file)
index 0000000..29d0c95
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../kernel/locking/lockdep_internals.h"
diff --git a/tools/lib/lockdep/lockdep_states.h b/tools/lib/lockdep/lockdep_states.h
new file mode 100644 (file)
index 0000000..248d235
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../kernel/locking/lockdep_states.h"
diff --git a/tools/lib/lockdep/rbtree.c b/tools/lib/lockdep/rbtree.c
new file mode 100644 (file)
index 0000000..f7f4303
--- /dev/null
@@ -0,0 +1 @@
+#include "../../../lib/rbtree.c"
diff --git a/tools/lib/lockdep/uinclude/asm/hweight.h b/tools/lib/lockdep/uinclude/asm/hweight.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/asm/sections.h b/tools/lib/lockdep/uinclude/asm/sections.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/bitops.h b/tools/lib/lockdep/uinclude/linux/bitops.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+
diff --git a/tools/lib/lockdep/uinclude/linux/compiler.h b/tools/lib/lockdep/uinclude/linux/compiler.h
new file mode 100644 (file)
index 0000000..7ac838a
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _LIBLOCKDEP_LINUX_COMPILER_H_
+#define _LIBLOCKDEP_LINUX_COMPILER_H_
+
+#define __used         __attribute__((__unused__))
+#define unlikely
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/debug_locks.h b/tools/lib/lockdep/uinclude/linux/debug_locks.h
new file mode 100644 (file)
index 0000000..f38eb64
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _LIBLOCKDEP_DEBUG_LOCKS_H_
+#define _LIBLOCKDEP_DEBUG_LOCKS_H_
+
+#include <stddef.h>
+#include <linux/compiler.h>
+
+#define DEBUG_LOCKS_WARN_ON(x) (x)
+
+extern bool debug_locks;
+extern bool debug_locks_silent;
+
+#endif
diff --git a/tools/lib/lockdep/uinclude/linux/delay.h b/tools/lib/lockdep/uinclude/linux/delay.h
new file mode 100644 (file)
index 0000000..fab00ff
--- /dev/null
@@ -0,0 +1,3 @@
+
+/* empty file */
+