diff options
| author | Merlin Scholz <merlin@scholz.ruhr> | 2023-03-17 20:36:23 +0100 |
|---|---|---|
| committer | Merlin Scholz <merlin@scholz.ruhr> | 2023-03-17 20:36:23 +0100 |
| commit | e2e1b134996638a109eec45981ba651ecef1b952 (patch) | |
| tree | 55d34861aca2b581f7e81976cadf5656e44cbaf3 | |
| parent | 776ee58682b55a490930b73105b3596dde1f16fa (diff) | |
Implement missing Mutex and RW logginglockdoc-9.3-0.4
| -rw-r--r-- | sys/kern/kern_mutex.c | 5 | ||||
| -rw-r--r-- | sys/kern/kern_rwlock.c | 10 | ||||
| -rw-r--r-- | sys/lockdoc/log.c | 83 | ||||
| -rw-r--r-- | sys/sys/lockdoc.h | 66 | ||||
| -rw-r--r-- | sys/sys/mutex.h | 13 | ||||
| -rw-r--r-- | sys/sys/rwlock.h | 15 |
6 files changed, 131 insertions, 61 deletions
diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c index bf40a48246f..183968e34bc 100644 --- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -889,8 +889,13 @@ mutex_ownable(const kmutex_t *mtx) * * Try to acquire the mutex; return non-zero if we did. */ +#ifdef LOCKDOC +int +_mutex_tryenter(kmutex_t *mtx) +#else int mutex_tryenter(kmutex_t *mtx) +#endif { uintptr_t curthread; diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c index 90f2543c138..5b52af91e71 100644 --- a/sys/kern/kern_rwlock.c +++ b/sys/kern/kern_rwlock.c @@ -584,8 +584,13 @@ rw_vector_tryenter(krwlock_t *rw, const krw_t op) * * Downgrade a write lock to a read lock. */ +#ifdef LOCKDOC +void +_rw_downgrade(krwlock_t *rw) +#else void rw_downgrade(krwlock_t *rw) +#endif { uintptr_t owner, curthread, newown, next; turnstile_t *ts; @@ -679,8 +684,13 @@ rw_downgrade(krwlock_t *rw) * Try to upgrade a read lock to a write lock. We must be the * only reader. */ +#ifdef LOCKDOC +int +_rw_tryupgrade(krwlock_t *rw) +#else int rw_tryupgrade(krwlock_t *rw) +#endif { uintptr_t owner, curthread, newown, next; diff --git a/sys/lockdoc/log.c b/sys/lockdoc/log.c index 9269baf2e65..3b5b3e6ade6 100644 --- a/sys/lockdoc/log.c +++ b/sys/lockdoc/log.c @@ -7,49 +7,78 @@ struct log_action la_buffer; -inline void __mutex_enter(kmutex_t * lock, const char* file, int line) { - lockdoc_log_lock(P_WRITE, lock, file, line, LOCK_NONE); +inline void __mutex_enter(kmutex_t * lock, const char* file, int line, const char* func) { _mutex_enter(lock); + lockdoc_log_lock(P_WRITE, lock, file, line, func, LOCK_NONE); } -inline void __mutex_exit(kmutex_t * lock, const char* file, int line) { - lockdoc_log_lock(V_WRITE, lock, file, line, LOCK_NONE); +inline void __mutex_exit(kmutex_t * lock, const char* file, int line, const char* func) { _mutex_exit(lock); + lockdoc_log_lock(V_WRITE, lock, file, line, func, LOCK_NONE); } -inline void __mutex_spin_enter(kmutex_t * lock, const char* file, int line) { - lockdoc_log_lock(P_WRITE, lock, file, line, LOCK_NONE); +inline void __mutex_spin_enter(kmutex_t * lock, const char* file, int line, const char* func) { _mutex_spin_enter(lock); + lockdoc_log_lock(P_WRITE, lock, file, line, func, LOCK_NONE); } -inline void __mutex_spin_exit(kmutex_t * lock, const char* file, int line) { - lockdoc_log_lock(V_WRITE, lock, file, line, LOCK_NONE); +inline void __mutex_spin_exit(kmutex_t * lock, const char* file, int line, const char* func) { _mutex_spin_exit(lock); + lockdoc_log_lock(V_WRITE, lock, file, line, func, LOCK_NONE); } -inline void __rw_enter(krwlock_t * lock, const krw_t type, const char* file, int line) { +inline int __mutex_tryenter(kmutex_t * lock, const char* file, int line, const char* func) { + int enter = _mutex_tryenter(lock); + if(enter != 0) { + lockdoc_log_lock(P_WRITE, lock, file, line, func, LOCK_NONE); + } + return enter; +} + +inline int __rw_tryupgrade(krwlock_t * lock, const char* file, int line, const char* func) { + int upgrade = _rw_tryupgrade(lock); + if(upgrade != 0) { + lockdoc_log_lock(V_READ, lock, file, line, func, LOCK_NONE); + lockdoc_log_lock(P_WRITE, lock, file, line, func, LOCK_NONE); + } + return upgrade; +} + +inline void __rw_downgrade(krwlock_t * lock, const char* file, int line, const char* func) { + _rw_downgrade(lock); + lockdoc_log_lock(V_WRITE, lock, file, line, func, LOCK_NONE); + lockdoc_log_lock(P_READ, lock, file, line, func, LOCK_NONE); +} + +inline void __rw_enter(krwlock_t * lock, const krw_t type, const char* file, int line, const char* func) { + _rw_enter(lock, type); if(type == RW_READER) - lockdoc_log_lock(P_READ, lock, file, line, LOCK_NONE); + lockdoc_log_lock(P_READ, lock, file, line, func, LOCK_NONE); else - lockdoc_log_lock(P_WRITE, lock, file, line, LOCK_NONE); - _rw_enter(lock, type); + lockdoc_log_lock(P_WRITE, lock, file, line, func, LOCK_NONE); } -inline int __rw_tryenter(krwlock_t * lock, const krw_t type, const char* file, int line) { - // TODO Check against other implementations - return _rw_tryenter(lock, type); +inline int __rw_tryenter(krwlock_t * lock, const krw_t type, const char* file, int line, const char* func) { + int enter = _rw_tryenter(lock, type); + if(enter != 0) { + if(type == RW_READER) + lockdoc_log_lock(P_READ, lock, file, line, func, LOCK_NONE); + else + lockdoc_log_lock(P_WRITE, lock, file, line, func, LOCK_NONE); + } + return enter; } -inline void __rw_exit(krwlock_t * lock, const char* file, int line) { - if((lock->rw_owner & 0x02UL) > 0) - lockdoc_log_lock(V_WRITE, lock, file, line, LOCK_NONE); - else - lockdoc_log_lock(V_READ, lock, file, line, LOCK_NONE); +inline void __rw_exit(krwlock_t * lock, const char* file, int line, const char* func) { _rw_exit(lock); + if((lock->rw_owner & 0x04UL) != 0) + lockdoc_log_lock(V_WRITE, lock, file, line, func, LOCK_NONE); + else + lockdoc_log_lock(V_READ, lock, file, line, func, LOCK_NONE); } /* - * Yet to be implemented: Check https://man.netbsd.org/locking.9 + * Yet to be implemented: Check https://man.netbsd.org/locking.9 (esp. IRQ, CVlock and BKL, check issue tracker) */ int32_t lockdoc_get_ctx(void) { @@ -124,9 +153,9 @@ void trace_irqs_on(struct trapframe *frame) { cur_eflags = x86_read_flags(); if ((frame->tf_eflags & (1 << 9)) && !(cur_eflags & (1 << 9))) { #ifdef DEBUG_TRAPS - lockdoc_log_lock(V_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, frame->tf_trapno); + lockdoc_log_lock(V_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, "dummy", frame->tf_trapno); #else - lockdoc_log_lock(V_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, LOCK_NONE); + lockdoc_log_lock(V_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, "dummy", LOCK_NONE); #endif } } @@ -136,9 +165,9 @@ void trace_irqs_off(struct trapframe *frame) { cur_eflags = x86_read_flags(); if ((frame->tf_eflags & (1 << 9)) && !(cur_eflags & (1 << 9))) { #ifdef DEBUG_TRAPS - lockdoc_log_lock(P_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, frame->tf_trapno); + lockdoc_log_lock(P_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, "dummy", frame->tf_trapno); #else - lockdoc_log_lock(P_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, LOCK_NONE); + lockdoc_log_lock(P_WRITE, (struct lock_object*)PSEUDOLOCK_ADDR_HARDIRQ, __FILE__, __LINE__, "dummy", LOCK_NONE); #endif } } @@ -148,7 +177,7 @@ void __x86_disable_intr(const char *file, int line, const char *func){ eflags = x86_read_flags(); if (eflags & (1 << 9)){ // Check if interrupts were enabled in the first place - lockdoc_log_lock(P_WRITE, (void*)PSEUDOLOCK_ADDR_HARDIRQ, file, line, LOCK_NONE); + lockdoc_log_lock(P_WRITE, (void*)PSEUDOLOCK_ADDR_HARDIRQ, file, line, "dummy", LOCK_NONE); } lockdoc_x86_disable_intr(); } @@ -167,7 +196,7 @@ void __x86_enable_intr(const char *file, int line, const char *func){ eflags = x86_read_flags(); if (!(eflags & (1 << 9))){ // Check if interrupts were disabled in the first place - lockdoc_log_lock(V_WRITE, (void*)PSEUDOLOCK_ADDR_HARDIRQ, file, line, LOCK_NONE); + lockdoc_log_lock(V_WRITE, (void*)PSEUDOLOCK_ADDR_HARDIRQ, file, line, "dummy", LOCK_NONE); } lockdoc_x86_enable_intr(); } diff --git a/sys/sys/lockdoc.h b/sys/sys/lockdoc.h index 81c987c2ce5..932afb96fec 100644 --- a/sys/sys/lockdoc.h +++ b/sys/sys/lockdoc.h @@ -21,21 +21,16 @@ int32_t lockdoc_get_ctx(void); void lockdoc_x86_restore_intr(u_long eflags); -void _mutex_enter(kmutex_t *); -void _mutex_exit(kmutex_t *); -void _mutex_spin_enter(kmutex_t *); -void _mutex_spin_exit(kmutex_t *); -void _rw_enter(krwlock_t *, const krw_t); -int _rw_tryenter(krwlock_t *, const krw_t); -void _rw_exit(krwlock_t *); - -void __mutex_enter(kmutex_t *, const char*, int); -void __mutex_exit(kmutex_t *, const char*, int); -void __mutex_spin_enter(kmutex_t *, const char*, int); -void __mutex_spin_exit(kmutex_t *, const char*, int); -void __rw_enter(krwlock_t *, const krw_t, const char*, int); -int __rw_tryenter(krwlock_t *, const krw_t, const char*, int); -void __rw_exit(krwlock_t *, const char*, int); +void __mutex_enter(kmutex_t *, const char*, int, const char*); +void __mutex_exit(kmutex_t *, const char*, int, const char*); +void __mutex_spin_enter(kmutex_t *, const char*, int, const char*); +void __mutex_spin_exit(kmutex_t *, const char*, int, const char*); +int __mutex_tryenter(kmutex_t *, const char*, int, const char*); +int __rw_tryupgrade(krwlock_t *, const char*, int, const char*); +void __rw_downgrade(krwlock_t *, const char*, int, const char*); +void __rw_enter(krwlock_t *, const krw_t, const char*, int, const char*); +int __rw_tryenter(krwlock_t *, const krw_t, const char*, int, const char*); +void __rw_exit(krwlock_t *, const char*, int, const char*); void trace_irqs_on(struct trapframe *frame); void trace_irqs_off(struct trapframe *frame); @@ -45,13 +40,17 @@ extern struct log_action la_buffer; /* * Redefine lock function as macros instead of normal functions, so that __FILE__ etc. will work properly */ -#define mutex_enter(lock) __mutex_enter(lock, __FILE__, __LINE__) -#define mutex_exit(lock) __mutex_exit(lock, __FILE__, __LINE__) -#define mutex_spin_enter(lock) __mutex_spin_enter(lock, __FILE__, __LINE__) -#define mutex_spin_exit(lock) __mutex_spin_exit(lock, __FILE__, __LINE__) -#define rw_enter(lock, type) __rw_enter(lock, type, __FILE__, __LINE__) -#define rw_tryenter(lock, type) __rw_tryenter(lock, type, __FILE__, __LINE__) -#define rw_exit(lock) __rw_exit(lock, __FILE__, __LINE__) +#define mutex_enter(lock) __mutex_enter(lock, __FILE__, __LINE__, __func__) +#define mutex_exit(lock) __mutex_exit(lock, __FILE__, __LINE__, __func__) +#define mutex_spin_enter(lock) __mutex_spin_enter(lock, __FILE__, __LINE__, __func__) +#define mutex_spin_exit(lock) __mutex_spin_exit(lock, __FILE__, __LINE__, __func__) +#define mutex_tryenter(lock) __mutex_tryenter(lock, __FILE__, __LINE__, __func__) + +#define rw_tryupgrade(lock) __rw_tryupgrade(lock, __FILE__, __LINE__, __func__) +#define rw_downgrade(lock) __rw_downgrade(lock, __FILE__, __LINE__, __func__) +#define rw_enter(lock, type) __rw_enter(lock, type, __FILE__, __LINE__, __func__) +#define rw_tryenter(lock, type) __rw_tryenter(lock, type, __FILE__, __LINE__, __func__) +#define rw_exit(lock) __rw_exit(lock, __FILE__, __LINE__, __func__) /* Basic port I/O */ static inline void outb_(u_int8_t v, u_int16_t port) @@ -86,7 +85,16 @@ static inline void lockdoc_log_memory(int alloc, const char *datatype, const voi lockdoc_x86_restore_intr(flags); } -static inline void lockdoc_log_lock(int lock_op, const volatile void* ptr, const char *file, int line, int irq_sync) { +/* + * TODO: Check for different lock types. We can *not*: + * - Copy the FreeBSD approach with the embedded struct (since it just doesn't exist) + * - Copy the Linux approach with __same_type (doesn't exist either) + * + * Possible solutions: + * - Pass an enum that is statically set in the macro, different in each function (similar to Linux) + * + */ +static inline void lockdoc_log_lock(int lock_op, const volatile void* ptr, const char *file, int line, const char* func, int irq_sync) { u_long eflags; eflags = x86_read_psl(); lockdoc_x86_disable_intr(); @@ -102,12 +110,14 @@ static inline void lockdoc_log_lock(int lock_op, const volatile void* ptr, const // context la_buffer.ctx = lockdoc_get_ctx(); + // TODO Check for IRQ + // pointer - la_buffer.ptr = (unsigned long)ptr; + la_buffer.ptr = (uint32_t)ptr; // size only relevant for memory access - // TODO type + // TODO type (See fuction-level TODO) strncpy(la_buffer.type, "dummy", LOG_CHAR_BUFFER_LEN); la_buffer.type[LOG_CHAR_BUFFER_LEN - 1] = '\0'; @@ -116,14 +126,14 @@ static inline void lockdoc_log_lock(int lock_op, const volatile void* ptr, const la_buffer.lock_member[LOG_CHAR_BUFFER_LEN - 1] = '\0'; // file - strncpy(la_buffer.file,file,LOG_CHAR_BUFFER_LEN); + 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); + // function + strncpy(la_buffer.function, func, LOG_CHAR_BUFFER_LEN); la_buffer.function[LOG_CHAR_BUFFER_LEN - 1] = '\0'; // TODO preempt_count diff --git a/sys/sys/mutex.h b/sys/sys/mutex.h index eb202d79dde..8196f98e91f 100644 --- a/sys/sys/mutex.h +++ b/sys/sys/mutex.h @@ -185,7 +185,7 @@ void mutex_wakeup(kmutex_t *); /* * This import is needed so that the mutex_ are being defined - * without having to add the lockdoc.h import to every single+ + * without having to add the lockdoc.h import to every single * file where mutex_functions are being called. */ #ifdef LOCKDOC @@ -210,9 +210,18 @@ void mutex_exit(kmutex_t *); void mutex_spin_enter(kmutex_t *); void mutex_spin_exit(kmutex_t *); -#endif int mutex_tryenter(kmutex_t *); +#else +void _mutex_enter(kmutex_t *); +void _mutex_exit(kmutex_t *); + +void _mutex_spin_enter(kmutex_t *); +void _mutex_spin_exit(kmutex_t *); + +int _mutex_tryenter(kmutex_t *); +#endif + int mutex_owned(const kmutex_t *); int mutex_ownable(const kmutex_t *); diff --git a/sys/sys/rwlock.h b/sys/sys/rwlock.h index 2420d0afce6..afa80d36ebc 100644 --- a/sys/sys/rwlock.h +++ b/sys/sys/rwlock.h @@ -96,9 +96,9 @@ int rw_vector_tryenter(krwlock_t *, const krw_t); #include <machine/rwlock.h> /* - * This import is needed so that the mutex_ are being defined - * without having to add the lockdoc.h import to every single+ - * file where mutex_functions are being called. + * This import is needed so that the rw_ are being defined + * without having to add the lockdoc.h import to every single + * file where rw_functions are being called. */ #ifdef LOCKDOC #include <sys/lockdoc.h> @@ -111,9 +111,13 @@ void rw_destroy(krwlock_t *); #ifndef LOCKDOC int rw_tryenter(krwlock_t *, const krw_t); -#endif int rw_tryupgrade(krwlock_t *); void rw_downgrade(krwlock_t *); +#else +int _rw_tryenter(krwlock_t *, const krw_t); +int _rw_tryupgrade(krwlock_t *); +void _rw_downgrade(krwlock_t *); +#endif int rw_read_held(krwlock_t *); int rw_write_held(krwlock_t *); @@ -122,6 +126,9 @@ int rw_lock_held(krwlock_t *); #ifndef LOCKDOC void rw_enter(krwlock_t *, const krw_t); void rw_exit(krwlock_t *); +#else +void _rw_enter(krwlock_t *, const krw_t); +void _rw_exit(krwlock_t *); #endif void rw_obj_init(void); |
