freebsd_network: Mutex handling cleanup.

* Add support for mtx_assert.
 * Move MTX_SPIN handling to dedicated functions like FreeBSD does.

Tested with ipro1000 and realtekwifi.
This commit is contained in:
Augustin Cavalier 2022-02-24 21:07:50 -05:00
parent ba641651b4
commit d6e2a3156a
2 changed files with 77 additions and 20 deletions

View File

@ -7,14 +7,8 @@
#define _FBSD_COMPAT_SYS_MUTEX_H_
#include <sys/haiku-module.h>
#include <kernel/int.h>
#include <sys/queue.h>
#include <sys/_mutex.h>
#include <sys/pcpu.h>
#include <machine/atomic.h>
#include <machine/cpufunc.h>
#include <sys/systm.h>
#define MA_OWNED 0x1
@ -22,8 +16,6 @@
#define MA_RECURSED 0x4
#define MA_NOTRECURSED 0x8
#define mtx_assert(mtx, what)
#define MTX_DEF 0x00000000
#define MTX_SPIN 0x00000001
#define MTX_RECURSE 0x00000004
@ -34,17 +26,23 @@
#define MTX_NETWORK_LOCK "network driver"
/* on FreeBSD these are different functions */
#define mtx_lock_spin(x) mtx_lock(x)
#define mtx_unlock_spin(x) mtx_unlock(x)
extern struct mtx Giant;
void mtx_init(struct mtx*, const char*, const char*, int);
void mtx_sysinit(void *arg);
void mtx_destroy(struct mtx*);
void mtx_lock_spin(struct mtx* mutex);
void mtx_unlock_spin(struct mtx* mutex);
void _mtx_assert(struct mtx *m, int what, const char *file, int line);
#ifdef INVARIANTS
# define mtx_assert(m, what) \
_mtx_assert((m), (what), __FILE__, __LINE__)
#else
# define mtx_assert(m, what)
#endif
static inline void
@ -56,9 +54,7 @@ mtx_lock(struct mtx* mutex)
} else if (mutex->type == MTX_RECURSE) {
recursive_lock_lock(&mutex->u.recursive);
} else if (mutex->type == MTX_SPIN) {
cpu_status status = disable_interrupts();
acquire_spinlock(&mutex->u.spinlock.lock);
mutex->u.spinlock.state = status;
mtx_lock_spin(mutex);
}
}
@ -91,9 +87,7 @@ mtx_unlock(struct mtx* mutex)
} else if (mutex->type == MTX_RECURSE) {
recursive_lock_unlock(&mutex->u.recursive);
} else if (mutex->type == MTX_SPIN) {
cpu_status status = mutex->u.spinlock.state;
release_spinlock(&mutex->u.spinlock.lock);
restore_interrupts(status);
mtx_unlock_spin(mutex);
}
}
@ -118,11 +112,22 @@ mtx_owned(struct mtx* mutex)
return mutex->u.recursive.holder == find_thread(NULL);
#endif
}
if (mutex->type == MTX_SPIN)
return mutex->u.spinlock.lock.lock != 0;
return 0;
}
static inline int
mtx_recursed(struct mtx* mutex)
{
if (mutex->type == MTX_RECURSE)
return mutex->u.recursive.recursion != 0;
return 0;
}
struct mtx_args {
void *ma_mtx;
const char *ma_desc;

View File

@ -57,6 +57,58 @@ mtx_destroy(struct mtx *mutex)
}
void
mtx_lock_spin(struct mtx* mutex)
{
KASSERT(mutex->type == MTX_SPIN, ("not a spin mutex"));
cpu_status status = disable_interrupts();
acquire_spinlock(&mutex->u.spinlock.lock);
mutex->u.spinlock.state = status;
}
void
mtx_unlock_spin(struct mtx* mutex)
{
KASSERT(mutex->type == MTX_SPIN, ("not a spin mutex"));
cpu_status status = mutex->u.spinlock.state;
release_spinlock(&mutex->u.spinlock.lock);
restore_interrupts(status);
}
void
_mtx_assert(struct mtx *m, int what, const char *file, int line)
{
switch (what) {
case MA_OWNED:
case MA_OWNED | MA_RECURSED:
case MA_OWNED | MA_NOTRECURSED:
if (!mtx_owned(m))
panic("mutex %p not owned at %s:%d",
m, file, line);
if (mtx_recursed(m)) {
if ((what & MA_NOTRECURSED) != 0)
panic("mutex %p recursed at %s:%d",
m, file, line);
} else if ((what & MA_RECURSED) != 0) {
panic("mutex %p unrecursed at %s:%d",
m, file, line);
}
break;
case MA_NOTOWNED:
if (mtx_owned(m))
panic("mutex %p owned at %s:%d",
m, file, line);
break;
default:
panic("unknown mtx_assert at %s:%d", file, line);
}
}
status_t
init_mutexes()
{