-/* $OpenBSD: lock_machdep.c,v 1.12 2017/04/16 14:28:07 visa Exp $ */
+/* $OpenBSD: lock_machdep.c,v 1.13 2017/04/20 13:20:17 visa Exp $ */
/*
* Copyright (c) 2007 Artur Grabowski <art@openbsd.org>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/atomic.h>
+#include <sys/witness.h>
+#include <sys/_lock.h>
#include <machine/lock.h>
#include <machine/cpufunc.h>
#include <ddb/db_output.h>
void
-__mp_lock_init(struct __mp_lock *mpl)
+___mp_lock_init(struct __mp_lock *mpl)
{
memset(mpl->mpl_cpus, 0, sizeof(mpl->mpl_cpus));
mpl->mpl_users = 0;
}
void
-__mp_lock(struct __mp_lock *mpl)
+___mp_lock(struct __mp_lock *mpl LOCK_FL_VARS)
{
struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()];
long rf = read_rflags();
+#ifdef WITNESS
+ int lock_held;
+
+ lock_held = __mp_lock_held(mpl);
+ if (!lock_held)
+ WITNESS_CHECKORDER(&mpl->mpl_lock_obj,
+ LOP_EXCLUSIVE | LOP_NEWORDER, file, line, NULL);
+#endif
disable_intr();
if (cpu->mplc_depth++ == 0)
write_rflags(rf);
__mp_lock_spin(mpl, cpu->mplc_ticket);
+
+ WITNESS_LOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line);
}
void
-__mp_unlock(struct __mp_lock *mpl)
+___mp_unlock(struct __mp_lock *mpl LOCK_FL_VARS)
{
struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()];
long rf = read_rflags();
}
#endif
+ WITNESS_UNLOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line);
+
disable_intr();
if (--cpu->mplc_depth == 0)
mpl->mpl_ticket++;
}
int
-__mp_release_all(struct __mp_lock *mpl)
+___mp_release_all(struct __mp_lock *mpl LOCK_FL_VARS)
{
struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()];
long rf = read_rflags();
int rv;
+#ifdef WITNESS
+ int i;
+#endif
disable_intr();
rv = cpu->mplc_depth;
+#ifdef WITNESS
+ for (i = 0; i < rv; i++)
+ WITNESS_UNLOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line);
+#endif
cpu->mplc_depth = 0;
mpl->mpl_ticket++;
write_rflags(rf);
}
int
-__mp_release_all_but_one(struct __mp_lock *mpl)
+___mp_release_all_but_one(struct __mp_lock *mpl LOCK_FL_VARS)
{
struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()];
int rv = cpu->mplc_depth - 1;
+#ifdef WITNESS
+ int i;
+
+ for (i = 0; i < rv; i++)
+ WITNESS_UNLOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line);
+#endif
#ifdef MP_LOCKDEBUG
if (!__mp_lock_held(mpl)) {
}
void
-__mp_acquire_count(struct __mp_lock *mpl, int count)
+___mp_acquire_count(struct __mp_lock *mpl, int count LOCK_FL_VARS)
{
while (count--)
- __mp_lock(mpl);
+ ___mp_lock(mpl LOCK_FL_ARGS);
}
int
-/* $OpenBSD: mplock.h,v 1.3 2014/03/14 02:08:57 dlg Exp $ */
+/* $OpenBSD: mplock.h,v 1.4 2017/04/20 13:20:17 visa Exp $ */
/*
* Copyright (c) 2004 Niklas Hallqvist. All rights reserved.
#ifndef _MACHINE_MPLOCK_H_
#define _MACHINE_MPLOCK_H_
+#include <sys/_lock.h>
+
struct __mp_lock_cpu {
u_int mplc_ticket;
u_int mplc_depth;
struct __mp_lock_cpu mpl_cpus[MAXCPUS];
volatile u_int mpl_ticket;
u_int mpl_users;
+#ifdef WITNESS
+ struct lock_object mpl_lock_obj;
+#endif
};
#ifndef _LOCORE
-void __mp_lock_init(struct __mp_lock *);
-void __mp_lock(struct __mp_lock *);
-void __mp_unlock(struct __mp_lock *);
-int __mp_release_all(struct __mp_lock *);
-int __mp_release_all_but_one(struct __mp_lock *);
-void __mp_acquire_count(struct __mp_lock *, int);
+void ___mp_lock_init(struct __mp_lock *);
+void ___mp_lock(struct __mp_lock * LOCK_FL_VARS);
+void ___mp_unlock(struct __mp_lock * LOCK_FL_VARS);
+int ___mp_release_all(struct __mp_lock * LOCK_FL_VARS);
+int ___mp_release_all_but_one(struct __mp_lock * LOCK_FL_VARS);
+void ___mp_acquire_count(struct __mp_lock *, int LOCK_FL_VARS);
int __mp_lock_held(struct __mp_lock *);
+#ifdef WITNESS
+
+void _mp_lock_init(struct __mp_lock *, struct lock_type *);
+
+#define __mp_lock_init(mpl) do { \
+ static struct lock_type __lock_type = { .lt_name = #mpl }; \
+ _mp_lock_init((mpl), &__lock_type); \
+} while (0)
+
+#else /* WITNESS */
+
+#define __mp_lock_init ___mp_lock_init
+
+#endif /* WITNESS */
+
+#define __mp_lock(mpl) ___mp_lock((mpl) LOCK_FILE_LINE)
+#define __mp_unlock(mpl) ___mp_unlock((mpl) LOCK_FILE_LINE)
+
+#define __mp_release_all(mpl) \
+ ___mp_release_all((mpl) LOCK_FILE_LINE)
+#define __mp_release_all_but_one(mpl) \
+ ___mp_release_all_but_one((mpl) LOCK_FILE_LINE)
+#define __mp_acquire_count(mpl, count) \
+ ___mp_acquire_count((mpl), (count) LOCK_FILE_LINE)
+
#endif
#endif /* !_MACHINE_MPLOCK_H */
-/* $OpenBSD: lock_machdep.c,v 1.21 2017/04/16 14:28:07 visa Exp $ */
+/* $OpenBSD: lock_machdep.c,v 1.22 2017/04/20 13:20:17 visa Exp $ */
/* $NetBSD: lock_machdep.c,v 1.1.2.3 2000/05/03 14:40:30 sommerfeld Exp $ */
/*-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/atomic.h>
+#include <sys/witness.h>
+#include <sys/_lock.h>
#include <machine/lock.h>
#include <machine/cpufunc.h>
#ifdef MULTIPROCESSOR
void
-__mp_lock_init(struct __mp_lock *mpl)
+___mp_lock_init(struct __mp_lock *mpl)
{
memset(mpl->mpl_cpus, 0, sizeof(mpl->mpl_cpus));
mpl->mpl_users = 0;
}
void
-__mp_lock(struct __mp_lock *mpl)
+___mp_lock(struct __mp_lock *mpl LOCK_FL_VARS)
{
struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()];
long ef = read_eflags();
+#ifdef WITNESS
+ int lock_held;
+
+ lock_held = __mp_lock_held(mpl);
+ if (!lock_held)
+ WITNESS_CHECKORDER(&mpl->mpl_lock_obj,
+ LOP_EXCLUSIVE | LOP_NEWORDER, file, line, NULL);
+#endif
disable_intr();
if (cpu->mplc_depth++ == 0)
write_eflags(ef);
__mp_lock_spin(mpl, cpu->mplc_ticket);
+
+ WITNESS_LOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line);
}
void
-__mp_unlock(struct __mp_lock *mpl)
+___mp_unlock(struct __mp_lock *mpl LOCK_FL_VARS)
{
struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()];
int ef = read_eflags();
}
#endif
+ WITNESS_UNLOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line);
+
disable_intr();
if (--cpu->mplc_depth == 0)
mpl->mpl_ticket++;
}
int
-__mp_release_all(struct __mp_lock *mpl)
+___mp_release_all(struct __mp_lock *mpl LOCK_FL_VARS)
{
struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()];
int ef = read_eflags();
int rv;
+#ifdef WITNESS
+ int i;
+#endif
disable_intr();
rv = cpu->mplc_depth;
+#ifdef WITNESS
+ for (i = 0; i < rv; i++)
+ WITNESS_UNLOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line);
+#endif
cpu->mplc_depth = 0;
mpl->mpl_ticket++;
write_eflags(ef);
}
int
-__mp_release_all_but_one(struct __mp_lock *mpl)
+___mp_release_all_but_one(struct __mp_lock *mpl LOCK_FL_VARS)
{
struct __mp_lock_cpu *cpu = &mpl->mpl_cpus[cpu_number()];
int rv = cpu->mplc_depth - 1;
+#ifdef WITNESS
+ int i;
+
+ for (i = 0; i < rv; i++)
+ WITNESS_UNLOCK(&mpl->mpl_lock_obj, LOP_EXCLUSIVE, file, line);
+#endif
cpu->mplc_depth = 1;
}
void
-__mp_acquire_count(struct __mp_lock *mpl, int count)
+___mp_acquire_count(struct __mp_lock *mpl, int count LOCK_FL_VARS)
{
while (count--)
- __mp_lock(mpl);
+ ___mp_lock(mpl LOCK_FL_ARGS);
}
int
#ifndef _MACHINE_MPLOCK_H_
#define _MACHINE_MPLOCK_H_
+#include <sys/_lock.h>
+
struct __mp_lock_cpu {
u_int mplc_ticket;
u_int mplc_depth;
struct __mp_lock_cpu mpl_cpus[MAXCPUS];
volatile u_int mpl_ticket;
u_int mpl_users;
+#ifdef WITNESS
+ struct lock_object mpl_lock_obj;
+#endif
};
#ifndef _LOCORE
-void __mp_lock_init(struct __mp_lock *);
-void __mp_lock(struct __mp_lock *);
-void __mp_unlock(struct __mp_lock *);
-int __mp_release_all(struct __mp_lock *);
-int __mp_release_all_but_one(struct __mp_lock *);
-void __mp_acquire_count(struct __mp_lock *, int);
+void ___mp_lock_init(struct __mp_lock *);
+void ___mp_lock(struct __mp_lock * LOCK_FL_VARS);
+void ___mp_unlock(struct __mp_lock * LOCK_FL_VARS);
+int ___mp_release_all(struct __mp_lock * LOCK_FL_VARS);
+int ___mp_release_all_but_one(struct __mp_lock * LOCK_FL_VARS);
+void ___mp_acquire_count(struct __mp_lock *, int LOCK_FL_VARS);
int __mp_lock_held(struct __mp_lock *);
-#endif
+#ifdef WITNESS
+
+void _mp_lock_init(struct __mp_lock *, struct lock_type *);
+
+#define __mp_lock_init(mpl) do { \
+ static struct lock_type __lock_type = { .lt_name = #mpl }; \
+ _mp_lock_init((mpl), &__lock_type); \
+} while (0)
+
+#else /* WITNESS */
+
+#define __mp_lock_init ___mp_lock_init
+
+#endif /* WITNESS */
+
+#define __mp_lock(mpl) ___mp_lock((mpl) LOCK_FILE_LINE)
+#define __mp_unlock(mpl) ___mp_unlock((mpl) LOCK_FILE_LINE)
+
+#define __mp_release_all(mpl) \
+ ___mp_release_all((mpl) LOCK_FILE_LINE)
+#define __mp_release_all_but_one(mpl) \
+ ___mp_release_all_but_one((mpl) LOCK_FILE_LINE)
+#define __mp_acquire_count(mpl, count) \
+ ___mp_acquire_count((mpl), (count) LOCK_FILE_LINE)
#endif
+
+#endif /* !_MACHINE_MPLOCK_H */
-/* $OpenBSD: kern_lock.c,v 1.47 2016/06/19 11:54:33 natano Exp $ */
+/* $OpenBSD: kern_lock.c,v 1.48 2017/04/20 13:20:17 visa Exp $ */
/*
* Copyright (c) 1995
#include <sys/param.h>
#include <sys/lock.h>
+#include <sys/mplock.h>
#include <sys/systm.h>
#include <sys/sched.h>
+#include <sys/witness.h>
+#include <sys/_lock.h>
#ifdef MP_LOCKDEBUG
/* CPU-dependent timing, this needs to be settable from ddb. */
*/
void
-_kernel_lock(void)
+_kernel_lock(const char *file, int line)
{
SCHED_ASSERT_UNLOCKED();
+#ifdef WITNESS
+ ___mp_lock(&kernel_lock, file, line);
+#else
__mp_lock(&kernel_lock);
+#endif
}
void
{
return (__mp_lock_held(&kernel_lock));
}
+
+#ifdef WITNESS
+void
+_mp_lock_init(struct __mp_lock *mpl, struct lock_type *type)
+{
+ mpl->mpl_lock_obj.lo_name = type->lt_name;
+ mpl->mpl_lock_obj.lo_type = type;
+ if (mpl == &kernel_lock)
+ mpl->mpl_lock_obj.lo_flags = LO_WITNESS | LO_INITIALIZED |
+ LO_SLEEPABLE | (LO_CLASS_KERNEL_LOCK << LO_CLASSSHIFT);
+ else if (mpl == &sched_lock)
+ mpl->mpl_lock_obj.lo_flags = LO_WITNESS | LO_INITIALIZED |
+ LO_RECURSABLE | (LO_CLASS_SCHED_LOCK << LO_CLASSSHIFT);
+ WITNESS_INIT(&mpl->mpl_lock_obj, type);
+
+ ___mp_lock_init(mpl);
+}
+#endif /* WITNESS */
+
#endif /* MULTIPROCESSOR */
-/* $OpenBSD: systm.h,v 1.125 2017/03/17 17:19:16 mpi Exp $ */
+/* $OpenBSD: systm.h,v 1.126 2017/04/20 13:20:17 visa Exp $ */
/* $NetBSD: systm.h,v 1.50 1996/06/09 04:55:09 briggs Exp $ */
/*-
#if defined(MULTIPROCESSOR)
void _kernel_lock_init(void);
-void _kernel_lock(void);
+void _kernel_lock(const char *, int);
void _kernel_unlock(void);
int _kernel_lock_held(void);
#define KERNEL_LOCK_INIT() _kernel_lock_init()
-#define KERNEL_LOCK() _kernel_lock()
+#define KERNEL_LOCK() _kernel_lock(__FILE__, __LINE__)
#define KERNEL_UNLOCK() _kernel_unlock()
#define KERNEL_ASSERT_LOCKED() KASSERT(_kernel_lock_held())
#define KERNEL_ASSERT_UNLOCKED() KASSERT(!_kernel_lock_held())