You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
liblockdep: Wrap kernel/locking/lockdep.c to allow usage from userspace
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>
This commit is contained in:
@@ -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)
|
||||
@@ -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(¤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;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
#include <linux/lockdep.h>
|
||||
#include "../../../kernel/locking/lockdep.c"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../../kernel/locking/lockdep_internals.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../../kernel/locking/lockdep_states.h"
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../../lib/rbtree.c"
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
/* empty file */
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
/* empty file */
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
/* empty file */
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef _LIBLOCKDEP_LINUX_COMPILER_H_
|
||||
#define _LIBLOCKDEP_LINUX_COMPILER_H_
|
||||
|
||||
#define __used __attribute__((__unused__))
|
||||
#define unlikely
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
/* empty file */
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef _LIBLOCKDEP_LINUX_EXPORT_H_
|
||||
#define _LIBLOCKDEP_LINUX_EXPORT_H_
|
||||
|
||||
#define EXPORT_SYMBOL(sym)
|
||||
#define EXPORT_SYMBOL_GPL(sym)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
/* empty file */
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
/* empty file */
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef _LIBLOCKDEP_LINUX_HARDIRQ_H_
|
||||
#define _LIBLOCKDEP_LINUX_HARDIRQ_H_
|
||||
|
||||
#define SOFTIRQ_BITS 0UL
|
||||
#define HARDIRQ_BITS 0UL
|
||||
#define SOFTIRQ_SHIFT 0UL
|
||||
#define HARDIRQ_SHIFT 0UL
|
||||
#define hardirq_count() 0UL
|
||||
#define softirq_count() 0UL
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1 @@
|
||||
#include "../../../include/linux/hash.h"
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
/* empty file */
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef _LIBLOCKDEP_LINUX_TRACE_IRQFLAGS_H_
|
||||
#define _LIBLOCKDEP_LINUX_TRACE_IRQFLAGS_H_
|
||||
|
||||
# define trace_hardirq_context(p) 0
|
||||
# define trace_softirq_context(p) 0
|
||||
# define trace_hardirqs_enabled(p) 0
|
||||
# define trace_softirqs_enabled(p) 0
|
||||
# define trace_hardirq_enter() do { } while (0)
|
||||
# define trace_hardirq_exit() do { } while (0)
|
||||
# define lockdep_softirq_enter() do { } while (0)
|
||||
# define lockdep_softirq_exit() do { } while (0)
|
||||
# define INIT_TRACE_IRQFLAGS
|
||||
|
||||
# define stop_critical_timings() do { } while (0)
|
||||
# define start_critical_timings() do { } while (0)
|
||||
|
||||
#define raw_local_irq_disable() do { } while (0)
|
||||
#define raw_local_irq_enable() do { } while (0)
|
||||
#define raw_local_irq_save(flags) ((flags) = 0)
|
||||
#define raw_local_irq_restore(flags) do { } while (0)
|
||||
#define raw_local_save_flags(flags) ((flags) = 0)
|
||||
#define raw_irqs_disabled_flags(flags) do { } while (0)
|
||||
#define raw_irqs_disabled() 0
|
||||
#define raw_safe_halt()
|
||||
|
||||
#define local_irq_enable() do { } while (0)
|
||||
#define local_irq_disable() do { } while (0)
|
||||
#define local_irq_save(flags) ((flags) = 0)
|
||||
#define local_irq_restore(flags) do { } while (0)
|
||||
#define local_save_flags(flags) ((flags) = 0)
|
||||
#define irqs_disabled() (1)
|
||||
#define irqs_disabled_flags(flags) (0)
|
||||
#define safe_halt() do { } while (0)
|
||||
|
||||
#define trace_lock_release(x, y)
|
||||
#define trace_lock_acquire(a, b, c, d, e, f, g)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef _LIBLOCKDEP_LINUX_KALLSYMS_H_
|
||||
#define _LIBLOCKDEP_LINUX_KALLSYMS_H_
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define KSYM_NAME_LEN 128
|
||||
|
||||
struct module;
|
||||
|
||||
static inline const char *kallsyms_lookup(unsigned long addr,
|
||||
unsigned long *symbolsize,
|
||||
unsigned long *offset,
|
||||
char **modname, char *namebuf)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <stdlib.h>
|
||||
static inline void print_ip_sym(unsigned long ip)
|
||||
{
|
||||
char **name;
|
||||
|
||||
name = backtrace_symbols((void **)&ip, 1);
|
||||
|
||||
printf("%s\n", *name);
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user