summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMerlin Scholz <merlin@scholz.ruhr>2023-03-16 23:26:30 +0100
committerMerlin Scholz <merlin@scholz.ruhr>2023-03-16 23:26:30 +0100
commit776ee58682b55a490930b73105b3596dde1f16fa (patch)
treeb41d6963b6f2d4f07bdcf5d478bcbc652c28cda0
parentbf1ce4ce265b9f38a71f0bca82d8f0e8c055233a (diff)
Implement logging for rwlock_enter() and rwlock_exit(), move from do-while macros to dedicated functions to allow for return values.
-rw-r--r--sys/arch/i386/i386/lock_stubs.S31
-rw-r--r--sys/dev/apm/apm.c13
-rw-r--r--sys/kern/kern_rwlock.c6
-rw-r--r--sys/lockdoc/log.c45
-rw-r--r--sys/sys/lockdoc.h42
-rw-r--r--sys/sys/rwlock.h13
6 files changed, 113 insertions, 37 deletions
diff --git a/sys/arch/i386/i386/lock_stubs.S b/sys/arch/i386/i386/lock_stubs.S
index 554a675e96e..36da6c5aa4d 100644
--- a/sys/arch/i386/i386/lock_stubs.S
+++ b/sys/arch/i386/i386/lock_stubs.S
@@ -118,7 +118,11 @@ END(mutex_exit)
*
* Acquire one hold on a RW lock.
*/
+#ifdef LOCKDOC
+ENTRY(_rw_enter)
+#else
ENTRY(rw_enter)
+#endif
movl 4(%esp), %edx
cmpl $RW_READER, 8(%esp)
jne 2f
@@ -150,14 +154,21 @@ ENTRY(rw_enter)
RET(3)
3:
jmp _C_LABEL(rw_vector_enter)
+#ifdef LOCKDOC
+END(_rw_enter)
+#else
END(rw_enter)
-
+#endif
/*
* void rw_exit(krwlock_t *rwl);
*
* Release one hold on a RW lock.
*/
+#ifdef LOCKDOC
+ENTRY(_rw_exit)
+#else
ENTRY(rw_exit)
+#endif
movl 4(%esp), %edx
movl (%edx), %eax
testb $RW_WRITE_LOCKED, %al
@@ -193,14 +204,21 @@ ENTRY(rw_exit)
* Slow path.
*/
3: jmp _C_LABEL(rw_vector_exit)
+#ifdef LOCKDOC
+END(_rw_exit)
+#else
END(rw_exit)
-
+#endif
/*
* int rw_tryenter(krwlock_t *rwl, krw_t op);
*
* Try to acquire one hold on a RW lock.
*/
+#ifdef LOCKDOC
+ENTRY(_rw_tryenter)
+#else
ENTRY(rw_tryenter)
+#endif
movl 4(%esp), %edx
cmpl $RW_READER, 8(%esp)
jne 2f
@@ -237,8 +255,11 @@ ENTRY(rw_tryenter)
4:
xorl %eax, %eax
jmp 3b
+#ifdef LOCKDOC
+END(_rw_tryenter)
+#else
END(rw_tryenter)
-
+#endif
#ifndef XENPV
/*
@@ -341,7 +362,9 @@ END(i686_mutex_spin_exit)
#else /* !XENPV */
-/* For now; strong alias not working for some reason. */
+/* For now; strong alias not working for some reason.
+ * Not relevant for LOCKDOC as it's only used in Xen
+ */
ENTRY(mutex_spin_enter)
jmp _C_LABEL(mutex_vector_enter)
diff --git a/sys/dev/apm/apm.c b/sys/dev/apm/apm.c
index 9819afff6be..130a01208a9 100644
--- a/sys/dev/apm/apm.c
+++ b/sys/dev/apm/apm.c
@@ -87,22 +87,11 @@ int apmdebug = 0;
* assert an exclusive lock any time thread context enters the
* APM module. This is both the APM thread itself, as well as
* user context.
- *
- * LOCKDOC Update: I don't know why this is implemented as a
- * macro with (void) cast here, but it breaks when LOCKDOC replaces
- * mutex_enter with a macro. So we circumvent that.
*/
-#ifdef LOCKDOC
-#define APM_LOCK(apmsc) \
- mutex_enter(&(apmsc)->sc_lock)
-#define APM_UNLOCK(apmsc) \
- mutex_exit(&(apmsc)->sc_lock)
-#else
#define APM_LOCK(apmsc) \
(void) mutex_enter(&(apmsc)->sc_lock)
#define APM_UNLOCK(apmsc) \
(void) mutex_exit(&(apmsc)->sc_lock)
-#endif
static void apm_event_handle(struct apm_softc *, u_int, u_int);
static void apm_periodic_check(struct apm_softc *);
@@ -924,4 +913,4 @@ apmkqfilter(dev_t dev, struct knote *kn)
APM_UNLOCK(sc);
return (0);
-}
+} \ No newline at end of file
diff --git a/sys/kern/kern_rwlock.c b/sys/kern/kern_rwlock.c
index fbdbcdad870..90f2543c138 100644
--- a/sys/kern/kern_rwlock.c
+++ b/sys/kern/kern_rwlock.c
@@ -143,10 +143,16 @@ rw_swap(krwlock_t *rw, uintptr_t o, uintptr_t n)
#endif
#ifndef __HAVE_RW_STUBS
+#ifdef LOCKDOC
+__strong_alias(_rw_enter,rw_vector_enter);
+__strong_alias(_rw_exit,rw_vector_exit);
+__strong_alias(_rw_tryenter,rw_vector_tryenter);
+#else
__strong_alias(rw_enter,rw_vector_enter);
__strong_alias(rw_exit,rw_vector_exit);
__strong_alias(rw_tryenter,rw_vector_tryenter);
#endif
+#endif
lockops_t rwlock_lockops = {
.lo_name = "Reader / writer lock",
diff --git a/sys/lockdoc/log.c b/sys/lockdoc/log.c
index 56815b93d75..9269baf2e65 100644
--- a/sys/lockdoc/log.c
+++ b/sys/lockdoc/log.c
@@ -7,6 +7,51 @@
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);
+ _mutex_enter(lock);
+}
+
+inline void __mutex_exit(kmutex_t * lock, const char* file, int line) {
+ lockdoc_log_lock(V_WRITE, lock, file, line, LOCK_NONE);
+ _mutex_exit(lock);
+}
+
+inline void __mutex_spin_enter(kmutex_t * lock, const char* file, int line) {
+ lockdoc_log_lock(P_WRITE, lock, file, line, LOCK_NONE);
+ _mutex_spin_enter(lock);
+}
+
+inline void __mutex_spin_exit(kmutex_t * lock, const char* file, int line) {
+ lockdoc_log_lock(V_WRITE, lock, file, line, LOCK_NONE);
+ _mutex_spin_exit(lock);
+}
+
+inline void __rw_enter(krwlock_t * lock, const krw_t type, const char* file, int line) {
+ if(type == RW_READER)
+ lockdoc_log_lock(P_READ, lock, file, line, LOCK_NONE);
+ else
+ lockdoc_log_lock(P_WRITE, lock, file, line, LOCK_NONE);
+ _rw_enter(lock, type);
+}
+
+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 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);
+ _rw_exit(lock);
+}
+
+/*
+ * Yet to be implemented: Check https://man.netbsd.org/locking.9
+ */
+
int32_t lockdoc_get_ctx(void) {
if (curlwp == NULL) {
return 0;
diff --git a/sys/sys/lockdoc.h b/sys/sys/lockdoc.h
index 84fc5895680..81c987c2ce5 100644
--- a/sys/sys/lockdoc.h
+++ b/sys/sys/lockdoc.h
@@ -6,8 +6,9 @@
#include <sys/types.h>
#include <sys/systm.h>
-#include <sys/lockdebug.h>
#include <sys/lockdoc_event.h>
+#include <sys/mutex.h>
+#include <sys/rwlock.h>
#define DELIMITER "#"
#define DELIMITER_CHAR '#'
@@ -24,6 +25,17 @@ 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 trace_irqs_on(struct trapframe *frame);
void trace_irqs_off(struct trapframe *frame);
@@ -33,25 +45,13 @@ 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) do { \
- lockdoc_log_lock(P_WRITE, lock, __FILE__, __LINE__, LOCK_NONE); \
- _mutex_enter((lock)); \
-} while(/* CONSTCOND */ 0)
-
-#define mutex_exit(lock) do { \
- lockdoc_log_lock(V_WRITE, lock, __FILE__, __LINE__, LOCK_NONE); \
- _mutex_exit((lock)); \
-} while(/* CONSTCOND */ 0)
-
-#define mutex_spin_enter(lock) do { \
- lockdoc_log_lock(P_WRITE, lock, __FILE__, __LINE__, LOCK_NONE); \
- _mutex_spin_enter((lock)); \
-} while(/* CONSTCOND */ 0)
-
-#define mutex_spin_exit(lock) do { \
- lockdoc_log_lock(V_WRITE, lock, __FILE__, __LINE__, LOCK_NONE); \
- _mutex_spin_exit((lock)); \
-} while(/* CONSTCOND */ 0)
+#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__)
/* Basic port I/O */
static inline void outb_(u_int8_t v, u_int16_t port)
@@ -61,7 +61,7 @@ static inline void outb_(u_int8_t v, u_int16_t port)
static inline void lockdoc_log_memory(int alloc, const char *datatype, const void *ptr, size_t size) {
u_long flags;
-
+
flags = lockdoc_x86_disable_intr();
memset(&la_buffer,0,sizeof(la_buffer));
diff --git a/sys/sys/rwlock.h b/sys/sys/rwlock.h
index e64a1dca26a..2420d0afce6 100644
--- a/sys/sys/rwlock.h
+++ b/sys/sys/rwlock.h
@@ -95,12 +95,23 @@ 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.
+ */
+#ifdef LOCKDOC
+#include <sys/lockdoc.h>
+#endif
+
#ifdef _KERNEL
void rw_init(krwlock_t *);
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 *);
@@ -108,8 +119,10 @@ int rw_read_held(krwlock_t *);
int rw_write_held(krwlock_t *);
int rw_lock_held(krwlock_t *);
+#ifndef LOCKDOC
void rw_enter(krwlock_t *, const krw_t);
void rw_exit(krwlock_t *);
+#endif
void rw_obj_init(void);
krwlock_t *rw_obj_alloc(void);