diff options
| author | Merlin Scholz <merlin@scholz.ruhr> | 2022-12-10 18:00:09 +0100 |
|---|---|---|
| committer | Merlin Scholz <merlin@scholz.ruhr> | 2022-12-10 18:00:09 +0100 |
| commit | e4e98eb0d351245fe2cbe30a14ab09e03f56beab (patch) | |
| tree | 60e99e9e32964aa2e64cf154754dd9a28c716778 | |
| parent | 581e25b0c29a3c4db7a4118648c2c9fd19847258 (diff) | |
First concept for lock counting
| -rw-r--r-- | sys/Makefile | 2 | ||||
| -rw-r--r-- | sys/arch/i386/conf/LOCKCOUNT (renamed from sys/arch/i386/conf/LOCKDOC) | 3 | ||||
| -rw-r--r-- | sys/arch/i386/conf/files.i386 | 2 | ||||
| -rw-r--r-- | sys/arch/x86/include/cpufunc.h | 17 | ||||
| -rw-r--r-- | sys/lockcount/log.c | 13 | ||||
| -rw-r--r-- | sys/lockdoc/log.c | 73 | ||||
| -rw-r--r-- | sys/sys/Makefile | 2 | ||||
| -rw-r--r-- | sys/sys/lockcount.h | 20 | ||||
| -rw-r--r-- | sys/sys/lockdebug.h | 64 | ||||
| -rw-r--r-- | sys/sys/lockdoc.h | 94 | ||||
| -rw-r--r-- | sys/sys/lockdoc_event.h | 72 |
11 files changed, 62 insertions, 300 deletions
diff --git a/sys/Makefile b/sys/Makefile index 7eb25d75486..96ff5bff884 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -2,7 +2,7 @@ .include <bsd.own.mk> -SUBDIR= altq arch compat dev fs lockdoc miscfs \ +SUBDIR= altq arch compat dev fs lockcount miscfs \ net net80211 netatalk netbt netcan netipsec netinet netinet6 \ netmpls netsmb \ nfs opencrypto sys ufs uvm diff --git a/sys/arch/i386/conf/LOCKDOC b/sys/arch/i386/conf/LOCKCOUNT index 14d7556a892..4c639327ab2 100644 --- a/sys/arch/i386/conf/LOCKDOC +++ b/sys/arch/i386/conf/LOCKCOUNT @@ -113,7 +113,7 @@ options BUFQ_PRIOCSCAN # XXX to be commented out on release branch options DEBUG # expensive debugging checks/support #options LOCKDEBUG # expensive locking checks/support -options LOCKDOC # LOCKDOC test support +options LOCKCOUNT # LOCKCOUNT support #options DDB # in-kernel debugger #options DDB_ONPANIC=1 # see also sysctl(7): `ddb.onpanic' #options DDB_HISTORY_SIZE=512 # enable history editing in DDB @@ -139,6 +139,7 @@ include "conf/compat_netbsd09.config" #options COMPAT_OSSAUDIO # OSS (Voxware) audio driver compatibility options COMPAT_LINUX # binary compatibility with Linux #options COMPAT_FREEBSD # binary compatibility with FreeBSD +options EXEC_ELF32 # Wedge support options DKWEDGE_AUTODISCOVER # Automatically add dk(4) instances diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index 8614c7696ab..ad14836d36d 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -48,7 +48,7 @@ defparam opt_beep.h BEEP_ONHALT_PITCH=1500 defparam opt_beep.h BEEP_ONHALT_PERIOD=250 -file lockdoc/log.c lockdoc +file lockcount/log.c lockcount # Multiboot support defflag opt_multiboot.h MULTIBOOT diff --git a/sys/arch/x86/include/cpufunc.h b/sys/arch/x86/include/cpufunc.h index 5fe30d0b48a..8cb04526210 100644 --- a/sys/arch/x86/include/cpufunc.h +++ b/sys/arch/x86/include/cpufunc.h @@ -375,34 +375,17 @@ void x86_disable_intr(void); void x86_enable_intr(void); #else -#ifdef LOCKDOC - -#define x86_disable_intr() __x86_disable_intr(__FILE__, __LINE__, __func__) -void __x86_disable_intr(const char *file, int line, const char *func); -void lockdoc_x86_disable_intr(void); - -#else - static inline void x86_disable_intr(void) { __asm volatile ("cli" ::: "memory"); } -#endif /* LOCKDOC */ -#ifdef LOCKDOC -#define x86_enable_intr() __x86_enable_intr(__FILE__, __LINE__, __func__) -void __x86_enable_intr(const char *file, int line, const char *func); -void lockdoc_x86_enable_intr(void); - -#else static inline void x86_enable_intr(void) { __asm volatile ("sti" ::: "memory"); } -#endif /* LOCKDOC */ - #endif /* XENPV */ /* Use read_psl, write_psl when saving and restoring interrupt state. */ diff --git a/sys/lockcount/log.c b/sys/lockcount/log.c new file mode 100644 index 00000000000..ecda3313100 --- /dev/null +++ b/sys/lockcount/log.c @@ -0,0 +1,13 @@ +#include <arch/x86/include/cpufunc.h> +#include <sys/lockdebug.h> +#include <sys/lockcount.h> + +#ifdef LOCKCOUNT + +u_int64_t lockcounter; + +void lockcount_locked(void){ + lockcounter += 1; +} + +#endif /* LOCKCOUNT */
\ No newline at end of file diff --git a/sys/lockdoc/log.c b/sys/lockdoc/log.c deleted file mode 100644 index 28c99ad8bdf..00000000000 --- a/sys/lockdoc/log.c +++ /dev/null @@ -1,73 +0,0 @@ -#include <arch/x86/include/cpufunc.h> -#include <sys/lockdebug.h> -#include <sys/lockdoc.h> - -#ifdef LOCKDOC - -struct log_action la_buffer; - -void lockdoc_alloc(const char *func, const char *file, size_t line, volatile void *lock, lockops_t *lo, uintptr_t initaddr){ - // TODO Actually log things -} -void lockdoc_free(const char *func, const char *file, size_t line, volatile void *lock){ - // TODO Actually log things -} -void lockdoc_wantlock(const char *func, const char *file, size_t line, const volatile void *lock, uintptr_t where, int shared){ - // TODO Actually log things -} -void lockdoc_locked(const char *func, const char *file, size_t line, volatile void *lock, void *cvlock, uintptr_t where, int shared){ - // shared == 0 means exclusive (write) lock; shared > 0 means shared (read) lock - if(shared > 0) { - // TODO Check if LOCK_NONE is appropriate - log_lock(P_READ, lock, file, line, LOCK_NONE); - } else if (shared == 0){ - log_lock(P_WRITE, lock, file, line, LOCK_NONE); - } -} -void lockdoc_unlocked(const char *func, const char *file, size_t line, volatile void *lock, uintptr_t where, int shared){ - // shared == 0 means exclusive (write) lock; shared > 0 means shared (read) lock - if(shared > 0) { - // TODO Check if LOCK_NONE is appropriate - log_lock(V_READ, lock, file, line, LOCK_NONE); - } else if (shared == 0){ - log_lock(V_WRITE, lock, file, line, LOCK_NONE); - } -} -void lockdoc_barrier(const char *func, const char *file, size_t line, volatile void *spinlock, int slplocks){ - // TODO Actually log things -} -void lockdoc_mem_check(const char *func, const char *file, size_t line, void *base, size_t sz){ - // TODO Actually log things -} -void lockdoc_wakeup(const char *func, const char *file, size_t line, volatile void *lock, uintptr_t where){ - // TODO Actually log things -} - -void __x86_disable_intr(const char *file, int line, const char *func){ - u_long eflags; - - eflags = x86_read_flags(); - if (eflags & (1 << 9)){ // Check if interrupts were enabled in the first place - log_lock(P_WRITE, (void*)PSEUDOLOCK_ADDR_HARDIRQ, file, line, LOCK_NONE); - } - lockdoc_x86_disable_intr(); -} - -void lockdoc_x86_disable_intr(void){ - __asm volatile ("cli" ::: "memory"); -} - -void __x86_enable_intr(const char *file, int line, const char *func){ - u_long eflags; - - eflags = x86_read_flags(); - if (!(eflags & (1 << 9))){ // Check if interrupts were disabled in the first place - log_lock(V_WRITE, (void*)PSEUDOLOCK_ADDR_HARDIRQ, file, line, LOCK_NONE); - } - lockdoc_x86_enable_intr(); -} - -void lockdoc_x86_enable_intr(void){ - __asm volatile ("sti" ::: "memory"); -} -#endif /* LOCKDOC */
\ No newline at end of file diff --git a/sys/sys/Makefile b/sys/sys/Makefile index 00b64960abb..5e78687f2ee 100644 --- a/sys/sys/Makefile +++ b/sys/sys/Makefile @@ -26,7 +26,7 @@ INCS= acct.h agpio.h aio.h ansi.h aout_mids.h ataio.h atomic.h \ ioctl_compat.h iostat.h ipc.h ipmi.h \ joystick.h \ kcore.h kcov.h kcpuset.h kgdb.h kmem.h ksem.h ksyms.h ktrace.h \ - localcount.h localedef.h lock.h lockdoc.h lockdoc_event.h lockf.h lua.h lwp.h lwpctl.h \ + localcount.h localedef.h lock.h lockcount.h lockf.h lua.h lwp.h lwpctl.h \ malloc.h mallocvar.h mbuf.h md4.h md5.h midiio.h \ mman.h module.h mount.h mqueue.h msg.h msgbuf.h mtio.h mutex.h \ namei.h null.h \ diff --git a/sys/sys/lockcount.h b/sys/sys/lockcount.h new file mode 100644 index 00000000000..087e58685be --- /dev/null +++ b/sys/sys/lockcount.h @@ -0,0 +1,20 @@ +#if !defined(__LOCKCOUNT_H__) && !defined(__ASSEMBLER__) +#define __LOCKCOUNT_H__ + +#include <arch/x86/include/cpufunc.h> + +#include <sys/types.h> +#include <sys/systm.h> +#include <sys/lockdebug.h> + +#ifdef LOCKCOUNT + +extern u_int64_t lockcounter; + +// For DEFINEs in lockdebug.h +// Implemented in lockcount/log.c +void lockcount_locked(void); + +#endif /* LOCKCOUNT */ + +#endif /* __LOCKCOUNT_H__ */ diff --git a/sys/sys/lockdebug.h b/sys/sys/lockdebug.h index 020a44d8ee8..54fffcc8f99 100644 --- a/sys/sys/lockdebug.h +++ b/sys/sys/lockdebug.h @@ -52,9 +52,9 @@ typedef struct lockops { void (*lo_dump)(const volatile void *, lockop_printer_t); } lockops_t; -#ifdef LOCKDOC -#include <sys/lockdoc.h> // Has to be included *after* lockops_t definition -#endif /* LOCKDOC */ +#ifdef LOCKCOUNT +#include <sys/lockcount.h> // Has to be included *after* lockops_t definition +#endif /* LOCKCOUNT */ #define LOCKDEBUG_ABORT(f, ln, l, o, m) \ lockdebug_abort(f, ln, l, o, m) @@ -86,34 +86,27 @@ void lockdebug_wakeup(const char *, size_t, volatile void *, uintptr_t); #endif -#if defined(LOCKDEBUG) && defined(LOCKDOC) +#if defined(LOCKDEBUG) && defined(LOCKCOUNT) #define LOCKDEBUG_ALLOC(lock, ops, addr) \ - lockdebug_alloc(__func__, __LINE__, lock, ops, addr); \ - lockdoc_alloc(__func__, __FILE__, __LINE__, lock, ops, addr) + lockdebug_alloc(__func__, __LINE__, lock, ops, addr) #define LOCKDEBUG_FREE(dodebug, lock) \ - if (dodebug) lockdebug_free(__func__, __LINE__, lock); \ - lockdoc_free(__func__, __FILE__, __LINE__, lock) + if (dodebug) lockdebug_free(__func__, __LINE__, lock) #define LOCKDEBUG_WANTLOCK(dodebug, lock, where, s) \ - if (dodebug) lockdebug_wantlock(__func__, __LINE__, lock, where, s); \ - lockdoc_wantlock(__func__, __FILE__, __LINE__, lock, where, s) + if (dodebug) lockdebug_wantlock(__func__, __LINE__, lock, where, s) #define LOCKDEBUG_LOCKED(dodebug, lock, al, where, s) \ if (dodebug) lockdebug_locked(__func__, __LINE__, lock, al, where, s); \ - lockdoc_locked(__func__, __FILE__, __LINE__, lock, al, where, s) + lockcount_locked() #define LOCKDEBUG_UNLOCKED(dodebug, lock, where, s) \ - if (dodebug) lockdebug_unlocked(__func__, __LINE__, lock, where, s); \ - lockdoc_unlocked(__func__, __FILE__, __LINE__, lock, where, s) + if (dodebug) lockdebug_unlocked(__func__, __LINE__, lock, where, s) #define LOCKDEBUG_BARRIER(lock, slp) \ - lockdebug_barrier(__func__, __LINE__, lock, slp); \ - lockdoc_barrier(__func__, __FILE__, __LINE__, lock, slp) + lockdebug_barrier(__func__, __LINE__, lock, slp) #define LOCKDEBUG_MEM_CHECK(base, sz) \ - lockdebug_mem_check(__func__, __LINE__, base, sz); \ - lockdoc_mem_check(__func__, __FILE__, __LINE__, base, sz) + lockdebug_mem_check(__func__, __LINE__, base, sz) #define LOCKDEBUG_WAKEUP(dodebug, lock, where) \ - if (dodebug) lockdebug_wakeup(__func__, __LINE__, lock, where); \ - lockdoc_wakeup(__func__, __FILE__, __LINE__, lock, where) + if (dodebug) lockdebug_wakeup(__func__, __LINE__, lock, where) -#elif defined(LOCKDEBUG) && !defined(LOCKDOC) +#elif defined(LOCKDEBUG) && !defined(LOCKCOUNT) #define LOCKDEBUG_ALLOC(lock, ops, addr) \ lockdebug_alloc(__func__, __LINE__, lock, ops, addr) @@ -132,27 +125,18 @@ void lockdebug_wakeup(const char *, size_t, volatile void *, uintptr_t); #define LOCKDEBUG_WAKEUP(dodebug, lock, where) \ if (dodebug) lockdebug_wakeup(__func__, __LINE__, lock, where) -#elif !defined(LOCKDEBUG) && defined(LOCKDOC) +#elif !defined(LOCKDEBUG) && defined(LOCKCOUNT) -#define LOCKDEBUG_ALLOC(lock, ops, addr) \ - false; \ - lockdoc_alloc(__func__, __FILE__, __LINE__, lock, ops, addr) -#define LOCKDEBUG_FREE(dodebug, lock) \ - lockdoc_free(__func__, __FILE__, __LINE__, lock) -#define LOCKDEBUG_WANTLOCK(dodebug, lock, where, s) \ - lockdoc_wantlock(__func__, __FILE__, __LINE__, lock, where, s) -#define LOCKDEBUG_LOCKED(dodebug, lock, al, where, s) \ - lockdoc_locked(__func__, __FILE__, __LINE__, lock, al, where, s) -#define LOCKDEBUG_UNLOCKED(dodebug, lock, where, s) \ - lockdoc_unlocked(__func__, __FILE__, __LINE__, lock, where, s) -#define LOCKDEBUG_BARRIER(lock, slp) \ - lockdoc_barrier(__func__, __FILE__, __LINE__, lock, slp) -#define LOCKDEBUG_MEM_CHECK(base, sz) \ - lockdoc_mem_check(__func__, __FILE__, __LINE__, base, sz) -#define LOCKDEBUG_WAKEUP(dodebug, lock, where) \ - lockdoc_wakeup(__func__, __FILE__, __LINE__, lock, where) +#define LOCKDEBUG_ALLOC(lock, ops, addr) false +#define LOCKDEBUG_FREE(dodebug, lock) +#define LOCKDEBUG_WANTLOCK(dodebug, lock, where, s) +#define LOCKDEBUG_LOCKED(dodebug, lock, al, where, s) lockcount_locked() +#define LOCKDEBUG_UNLOCKED(dodebug, lock, where, s) +#define LOCKDEBUG_BARRIER(lock, slp) +#define LOCKDEBUG_MEM_CHECK(base, sz) +#define LOCKDEBUG_WAKEUP(dodebug, lock, where) -#else /* !LOCKDEBUG && !LOCKDOC */ +#else /* !LOCKDEBUG && !LOCKCOUNT */ #define LOCKDEBUG_ALLOC(lock, ops, addr) false #define LOCKDEBUG_FREE(dodebug, lock) /* nothing */ @@ -163,6 +147,6 @@ void lockdebug_wakeup(const char *, size_t, volatile void *, uintptr_t); #define LOCKDEBUG_MEM_CHECK(base, sz) /* nothing */ #define LOCKDEBUG_WAKEUP(dodebug, lock, where) /* nothing */ -#endif /* LOCKDEBUG && LOCKDOC */ +#endif /* LOCKDEBUG && LOCKCOUNT */ #endif /* __SYS_LOCKDEBUG_H__ */ diff --git a/sys/sys/lockdoc.h b/sys/sys/lockdoc.h deleted file mode 100644 index 9f8b2ef387a..00000000000 --- a/sys/sys/lockdoc.h +++ /dev/null @@ -1,94 +0,0 @@ -#if !defined(__LOCKDOC_H__) && !defined(__ASSEMBLER__) -#define __LOCKDOC_H__ - -#include <arch/x86/include/cpufunc.h> - -#include <sys/types.h> -#include <sys/systm.h> -#include <sys/lockdebug.h> -#include <sys/lockdoc_event.h> - -#define DELIMITER "#" -#define DELIMITER_CHAR '#' -#define PING_CHAR 'p' -#define MK_STRING(x) #x -#define IO_PORT_LOG (0x00e9) - -#ifdef LOCKDOC - -extern struct log_action la_buffer; - - -// For DEFINEs in lockdebug.h -// Implemented in lockdoc/log.c -void lockdoc_alloc(const char *, const char *, size_t, volatile void *, lockops_t *, uintptr_t); -void lockdoc_free(const char *, const char *, size_t, volatile void *); -void lockdoc_wantlock(const char *, const char *, size_t, const volatile void *, uintptr_t, int); -void lockdoc_locked(const char *, const char *, size_t, volatile void *, void *, uintptr_t, int); -void lockdoc_unlocked(const char *, const char *, size_t, volatile void *, uintptr_t, int); -void lockdoc_barrier(const char *, const char *, size_t, volatile void *, int); -void lockdoc_mem_check(const char *, const char *, size_t, void *, size_t); -void lockdoc_wakeup(const char *, const char *, size_t, volatile void *, uintptr_t); - -/* Basic port I/O */ -static inline void outb_(u_int8_t v, u_int16_t port) -{ - __asm __volatile("outb %0,%1" : : "a" (v), "dN" (port)); -} - -static inline void log_memory(int alloc, const char *datatype, const void *ptr, size_t size) { - -} - -static inline void log_lock(int lock_op, const volatile void* ptr, const char *file, int line, int irq_sync) { - u_long eflags; - eflags = x86_read_psl(); - lockdoc_x86_disable_intr(); - - memset(&la_buffer,0,sizeof(la_buffer)); - - // action - la_buffer.action = LOCKDOC_LOCK_OP; - - // operation - la_buffer.lock_op = lock_op; - - // pointer - la_buffer.ptr = (unsigned long)ptr; - - // size only relevant for memory access - - // TODO type - strncpy(la_buffer.type, "dummy", LOG_CHAR_BUFFER_LEN); - la_buffer.type[LOG_CHAR_BUFFER_LEN - 1] = '\0'; - - // TODO lock_member - strncpy(la_buffer.lock_member, "dummy", LOG_CHAR_BUFFER_LEN); - la_buffer.lock_member[LOG_CHAR_BUFFER_LEN - 1] = '\0'; - - // file - strncpy(la_buffer.file,file,LOG_CHAR_BUFFER_LEN); - la_buffer.file[LOG_CHAR_BUFFER_LEN - 1] = '\0'; - - // line - la_buffer.line = line; - - // TODO function - strncpy(la_buffer.function,"dummy",LOG_CHAR_BUFFER_LEN); - la_buffer.function[LOG_CHAR_BUFFER_LEN - 1] = '\0'; - - // TODO preempt_count - // irq_sync - la_buffer.irq_sync = irq_sync; - - outb_(PING_CHAR,IO_PORT_LOG); - - x86_write_flags(eflags); -} -#else -#define log_memory(a, b, c, d) -#define log_lock(a, b, c, d, e) - -#endif /* LOCKDOC */ - -#endif /* __LOCKDOC_H__ */ diff --git a/sys/sys/lockdoc_event.h b/sys/sys/lockdoc_event.h deleted file mode 100644 index c1672345b3c..00000000000 --- a/sys/sys/lockdoc_event.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef __LOCKDOC_EVENT_H__ -#define __LOCKDOC_EVENT_H__ - -#ifdef LOCKDOC - -#define LOG_CHAR_BUFFER_LEN 100 -#define PSEUDOLOCK_ADDR_RCU 0x42 -#define PSEUDOLOCK_ADDR_PREEMPT 0x43 -#define PSEUDOLOCK_ADDR_SOFTIRQ 0x45 -#define PSEUDOLOCK_ADDR_HARDIRQ 0x44 -#define PSEUDOLOCK_NAME_RCU "rcu" -#define PSEUDOLOCK_NAME_HARDIRQ "hardirq" -#define PSEUDOLOCK_NAME_SOFTIRQ "softirq" -#define PSEUDOLOCK_NAME_PREEMPT "preempt" -#define PSEUDOLOCK_VAR "static" -#define PSEUDOLOCK_VAR_RCU PSEUDOLOCK_VAR -#define PSEUDOLOCK_VAR_HARDIRQ PSEUDOLOCK_VAR -#define PSEUDOLOCK_VAR_SOFTIRQ PSEUDOLOCK_VAR -#define PSEUDOLOCK_VAR_PREEMPT PSEUDOLOCK_VAR - -// Lock flags -#define LOCK_FLAGS_RECURSIVE 0x1 - -/* - * When altered, this file - * has to be copied to the according fail experiment - * as well as to convert! - */ -enum LOCKDOC_OP { - LOCKDOC_ALLOC = 'a', - LOCKDOC_FREE = 'f', - LOCKDOC_LOCK_OP = 'l', - LOCKDOC_CURRENT_TASK = 't', - LOCKDOC_PREEMPT_COUNT = 'p', - LOCKDOC_PID_OFFSET = 'o', - LOCKDOC_KERNEL_VERSION = 'v', - LOCKDOC_READ = 'r', - LOCKDOC_WRITE = 'w' -}; - -enum LOCK_OP { - P_READ = 0, // Take shared lock - P_WRITE, // Take excl. lock - V_READ, // Free shared lock - V_WRITE // Free excl. lock -}; - -enum IRQ_SYNC { - LOCK_NONE = 0, - LOCK_IRQ, - LOCK_IRQ_NESTED, /* aka irqsave and irqrestore */ - LOCK_BH -}; - -struct log_action { - enum LOCKDOC_OP action; - uint32_t lock_op; - uint32_t ptr; - uint32_t size; - char type[LOG_CHAR_BUFFER_LEN]; // allocated data_type or lock type - char lock_member[LOG_CHAR_BUFFER_LEN]; - char file[LOG_CHAR_BUFFER_LEN]; - int32_t line; - char function[LOG_CHAR_BUFFER_LEN]; - int32_t preempt_count; - int32_t irq_sync; - int32_t flags; -}__attribute__((packed)); - -#endif /* LOCKDOC */ - -#endif /* __LOCKDOC_EVENT_H__ */ |
