kernel - Move mplock to machine-independent C
authorMatthew Dillon <dillon@apollo.backplane.com>
Sun, 20 Dec 2009 02:57:32 +0000 (18:57 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Sun, 20 Dec 2009 02:57:32 +0000 (18:57 -0800)
* Remove the per-platform mplock code and move it all into
  machine-independent code: sys/mplock2.h and kern/kern_mplock.c.

* Inline the critical path.

* When a conflict occurs kern_mplock.c will KTR log the file and line
  number of both the holder and conflicting acquirer.  Set
  debug.ktr.giant_enable=-1 to enable conflict logging.

144 files changed:
sys/bus/cam/cam_sim.c
sys/bus/cam/cam_xpt.c
sys/bus/cam/scsi/scsi_cd.c
sys/bus/cam/scsi/scsi_da.c
sys/conf/files
sys/dev/disk/ahci/ahci_dragonfly.h
sys/dev/disk/nata/ata-all.c
sys/dev/disk/nata/ata-chipset.c
sys/dev/disk/nata/atapi-cam.c
sys/dev/disk/sili/sili_dragonfly.h
sys/dev/raid/aac/aac.c
sys/dev/raid/aac/aac_cam.c
sys/emulation/43bsd/43bsd_file.c
sys/emulation/43bsd/43bsd_hostinfo.c
sys/emulation/43bsd/43bsd_signal.c
sys/emulation/43bsd/43bsd_socket.c
sys/emulation/43bsd/43bsd_stats.c
sys/emulation/43bsd/43bsd_vm.c
sys/emulation/dragonfly12/dfbsd12_getdirentries.c
sys/emulation/dragonfly12/dfbsd12_stat.c
sys/emulation/linux/i386/linux_machdep.c
sys/emulation/linux/i386/linux_ptrace.c
sys/emulation/linux/linux_file.c
sys/emulation/linux/linux_getcwd.c
sys/emulation/linux/linux_ioctl.c
sys/emulation/linux/linux_misc.c
sys/emulation/linux/linux_signal.c
sys/emulation/linux/linux_socket.c
sys/emulation/linux/linux_stats.c
sys/emulation/linux/linux_sysctl.c
sys/emulation/linux/linux_uid16.c
sys/kern/imgact_resident.c
sys/kern/init_main.c
sys/kern/kern_acct.c
sys/kern/kern_acl.c
sys/kern/kern_checkpoint.c
sys/kern/kern_clock.c
sys/kern/kern_descrip.c
sys/kern/kern_event.c
sys/kern/kern_exec.c
sys/kern/kern_exit.c
sys/kern/kern_fork.c
sys/kern/kern_intr.c
sys/kern/kern_jail.c
sys/kern/kern_ktrace.c
sys/kern/kern_linker.c
sys/kern/kern_module.c
sys/kern/kern_mplock.c [new file with mode: 0644]
sys/kern/kern_ntptime.c
sys/kern/kern_p1003_1b.c
sys/kern/kern_proc.c
sys/kern/kern_prot.c
sys/kern/kern_resource.c
sys/kern/kern_shutdown.c
sys/kern/kern_sig.c
sys/kern/kern_slaballoc.c
sys/kern/kern_synch.c
sys/kern/kern_sysctl.c
sys/kern/kern_syslink.c
sys/kern/kern_time.c
sys/kern/kern_timeout.c
sys/kern/kern_umtx.c
sys/kern/kern_upcall.c
sys/kern/kern_usched.c
sys/kern/kern_uuid.c
sys/kern/kern_varsym.c
sys/kern/kern_xxx.c
sys/kern/lwkt_caps.c
sys/kern/lwkt_thread.c
sys/kern/subr_bus.c
sys/kern/subr_prof.c
sys/kern/sys_generic.c
sys/kern/sys_pipe.c
sys/kern/sys_process.c
sys/kern/sys_socket.c
sys/kern/sysv_msg.c
sys/kern/sysv_sem.c
sys/kern/sysv_shm.c
sys/kern/uipc_syscalls.c
sys/kern/usched_bsd4.c
sys/kern/usched_dummy.c
sys/kern/vfs_aio.c
sys/kern/vfs_bio.c
sys/kern/vfs_cache.c
sys/kern/vfs_syscalls.c
sys/kern/vfs_vnops.c
sys/net/bpf.c
sys/net/if_ethersubr.c
sys/net/if_loop.c
sys/net/ipfw/ip_fw2.c
sys/net/netisr.c
sys/net/pfil.c
sys/net/tap/if_tap.c
sys/net/tun/if_tun.c
sys/netinet/if_ether.c
sys/netinet/ip_divert.c
sys/netinet/ip_input.c
sys/netinet/ip_output.c
sys/netinet/tcp_subr.c
sys/netproto/ncp/ncp_mod.c
sys/opencrypto/cryptodev.c
sys/platform/pc32/conf/files
sys/platform/pc32/i386/busdma_machdep.c
sys/platform/pc32/i386/genassym.c
sys/platform/pc32/i386/machdep.c
sys/platform/pc32/i386/mp_machdep.c
sys/platform/pc32/i386/mplock.s [deleted file]
sys/platform/pc32/i386/sys_machdep.c
sys/platform/pc32/i386/trap.c
sys/platform/pc32/i386/vm86.c
sys/platform/pc32/i386/vm_machdep.c
sys/platform/pc32/include/lock.h
sys/platform/pc32/isa/npx.c
sys/platform/pc64/conf/files
sys/platform/pc64/include/lock.h
sys/platform/pc64/isa/npx.c
sys/platform/pc64/x86_64/busdma_machdep.c
sys/platform/pc64/x86_64/machdep.c
sys/platform/pc64/x86_64/mp_machdep.c
sys/platform/pc64/x86_64/mplock.s [deleted file]
sys/platform/pc64/x86_64/npx.c
sys/platform/pc64/x86_64/trap.c
sys/platform/pc64/x86_64/vm_machdep.c
sys/platform/vkernel/conf/files
sys/platform/vkernel/i386/cpu_regs.c
sys/platform/vkernel/i386/genassym.c
sys/platform/vkernel/i386/mp.c
sys/platform/vkernel/i386/mplock.s [deleted file]
sys/platform/vkernel/i386/npx.c
sys/platform/vkernel/i386/trap.c
sys/platform/vkernel/i386/vm_machdep.c
sys/platform/vkernel/include/lock.h
sys/platform/vkernel/platform/busdma_machdep.c
sys/platform/vkernel/platform/copyio.c
sys/sys/mplock2.h [new file with mode: 0644]
sys/sys/systm.h
sys/sys/thread.h
sys/vfs/devfs/devfs_vnops.c
sys/vfs/hammer/hammer_vnops.c
sys/vfs/nfs/nfs_syscalls.c
sys/vm/vm_mmap.c
sys/vm/vm_swap.c
sys/vm/vm_unix.c
sys/vm/vm_vmspace.c

index be18d29..05754c6 100644 (file)
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/spinlock.h>
+
 #include <sys/thread2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 #include "cam.h"
 #include "cam_ccb.h"
index c63b608..7e0ab1c 100644 (file)
 #include <sys/thread.h>
 #include <sys/lock.h>
 #include <sys/spinlock.h>
+
 #include <sys/thread2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 #include <machine/clock.h>
 #include <machine/stdarg.h>
index bf68bb0..81b541a 100644 (file)
 #include <sys/sysctl.h>
 #include <sys/taskqueue.h>
 #include <sys/proc.h>
-#include <sys/buf2.h>
 #include <sys/camlib.h>
+
+#include <sys/buf2.h>
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include "../cam.h"
 #include "../cam_ccb.h"
index 2f92554..b0154b4 100644 (file)
@@ -33,6 +33,7 @@
 #include <sys/bootmaj.h>
 
 #ifdef _KERNEL
+
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/buf.h>
 #include <sys/malloc.h>
 #include <sys/cons.h>
 #include <sys/proc.h>
+
 #include <sys/buf2.h>
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
+
 #endif /* _KERNEL */
 
 #ifdef _KERNEL
index 8283663..caae1ec 100644 (file)
@@ -680,6 +680,7 @@ kern/kern_sig.c             standard
 kern/kern_memio.c      standard
 kern/kern_upcall.c     standard
 kern/kern_sfbuf.c      standard
+kern/kern_mplock.c     standard
 kern/kern_msfbuf.c     standard
 kern/kern_subr.c       standard
 kern/kern_iosched.c    standard
index ec2be67..8545d56 100644 (file)
@@ -68,6 +68,7 @@
 #include <bus/pci/pcidevs.h>
 
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #define AHCI_CDEV_MAJOR                188
 
index 8c7d3fb..ce3dacf 100644 (file)
 #include <sys/nata.h>
 #include <sys/objcache.h>
 #include <sys/queue.h>
-#include <sys/spinlock2.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
 
+#include <sys/spinlock2.h>
+#include <sys/mplock2.h>
+
 #include "ata-all.h"
 #include "ata_if.h"
 
index be764ea..e775db6 100644 (file)
 #include <sys/queue.h>
 #include <sys/rman.h>
 #include <sys/spinlock.h>
-#include <sys/spinlock2.h>
 #include <sys/systm.h>
 #include <sys/taskqueue.h>
 
+#include <sys/spinlock2.h>
+#include <sys/mplock2.h>
+
 #include <machine/bus_dma.h>
 
 #include <bus/pci/pcireg.h>
index afd40bc..54a0fc4 100644 (file)
 #include <sys/module.h>
 #include <sys/nata.h>
 #include <sys/spinlock.h>
-#include <sys/spinlock2.h>
 #include <sys/queue.h>
 #include <sys/systm.h>
+
 #include <sys/thread2.h>
+#include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 #include <bus/cam/cam.h>
 #include <bus/cam/cam_ccb.h>
index d29eb4c..30a6880 100644 (file)
@@ -68,6 +68,7 @@
 #include <bus/pci/pcidevs.h>
 
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #define SILI_CDEV_MAJOR                188
 
index f2c0505..4e4e259 100644 (file)
@@ -56,6 +56,8 @@
 #include <sys/eventhandler.h>
 #include <sys/rman.h>
 
+#include <sys/mplock2.h>
+
 #include <bus/pci/pcireg.h>
 #include <bus/pci/pcivar.h>
 
index 7051d04..3f8b355 100644 (file)
@@ -56,6 +56,8 @@
 
 #include <machine/md_var.h>
 
+#include <sys/mplock2.h>
+
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
index d39b3ff..eb2fdf8 100644 (file)
@@ -63,6 +63,8 @@
 #include <sys/nlookup.h>
 #include <sys/vnode.h>
 
+#include <sys/mplock2.h>
+
 #include <vfs/union/union.h>
 
 /*
index 68985c3..8e7d17f 100644 (file)
 #include <sys/priv.h>
 #include <sys/socket.h>
 #include <sys/sysctl.h>
+
 #include <vm/vm_param.h>
 
+#include <sys/mplock2.h>
+
 /*
  * MPALMOSTSAFE
  */
index 1b41509..8645a0a 100644 (file)
@@ -55,7 +55,9 @@
 #include <sys/proc.h>
 #include <sys/signal.h>
 #include <sys/signalvar.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #define        ONSIG   32              /* NSIG for osig* syscalls.  XXX. */
 
index f33ba3b..2554761 100644 (file)
@@ -54,6 +54,8 @@
 #include <sys/socketvar.h>
 #include <sys/uio.h>
 
+#include <sys/mplock2.h>
+
 #include "43bsd_socket.h"
 
 /*
index 65bcfa2..10b7a05 100644 (file)
@@ -57,6 +57,8 @@
 #include <sys/namei.h>
 #include <sys/nlookup.h>
 
+#include <sys/mplock2.h>
+
 #include <emulation/43bsd/stat.h>
 
 static int
index e940914..026365b 100644 (file)
@@ -49,7 +49,9 @@
 #include <sys/kern_syscall.h>
 #include <sys/mman.h>
 #include <sys/proc.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 /*
  * MPSAFE
index 4b9704e..e811339 100644 (file)
@@ -44,6 +44,8 @@
 #include <sys/sysproto.h>
 #include <sys/uio.h>
 
+#include <sys/mplock2.h>
+
 #define        PADDED_SIZE(x)  \
        ((sizeof(struct dfbsd12_dirent) + (x) + 1 + 3) & ~3)
 #define        MAX_NAMELEN     255
index 404b316..16ae75c 100644 (file)
@@ -49,6 +49,8 @@
 #include <sys/vnode.h>
 #include <emulation/dragonfly12/stat.h>
 
+#include <sys/mplock2.h>
+
 static void
 cvtstat(struct dfbsd12_stat *oldstat, struct stat *newstat)
 {
index db95b3a..e2edbaf 100644 (file)
@@ -53,6 +53,8 @@
 #include <vm/pmap.h>
 #include <vm/vm_map.h>
 
+#include <sys/mplock2.h>
+
 #include "linux.h"
 #include "linux_proto.h"
 #include "../linux_ipc.h"
@@ -419,7 +421,7 @@ int
 sys_linux_clone(struct linux_clone_args *args)
 {
        int error, ff = RFPROC;
-       struct proc *p2;
+       struct proc *p2 = NULL;
        int exit_signal;
        vm_offset_t start;
        struct rfork_args rf_args;
index 36de908..319d29b 100644 (file)
@@ -43,6 +43,8 @@
 #include <sys/user.h>
 #include <sys/reg.h>
 
+#include <sys/mplock2.h>
+
 #include <machine/md_var.h>
 #include <machine/pcb.h>
 
index c966d2f..16c3ede 100644 (file)
@@ -53,6 +53,7 @@
 #include <vfs/ufs/ufsmount.h>
 
 #include <sys/file2.h>
+#include <sys/mplock2.h>
 
 #include <arch_linux/linux.h>
 #include <arch_linux/linux_proto.h>
index 276a45d..e8ad1b8 100644 (file)
@@ -57,6 +57,8 @@
 #include <sys/kern_syscall.h>
 #include <vfs/ufs/dir.h>       /* XXX only for DIRBLKSIZ */
 
+#include <sys/mplock2.h>
+
 #include <arch_linux/linux.h>
 #include <arch_linux/linux_proto.h>
 #include "linux_util.h"
index 2fdca89..39f058c 100644 (file)
@@ -55,7 +55,9 @@
 #include <net/if.h>
 #include <net/if_dl.h>
 #include <net/if_types.h>
+
 #include <sys/file2.h>
+#include <sys/mplock2.h>
 
 #include <arch_linux/linux.h>
 #include <arch_linux/linux_proto.h>
index cf62405..dd09b7b 100644 (file)
@@ -48,7 +48,6 @@
 #include <sys/reboot.h>
 #include <sys/resourcevar.h>
 #include <sys/signalvar.h>
-#include <sys/signal2.h>
 #include <sys/stat.h>
 #include <sys/sysctl.h>
 #include <sys/sysproto.h>
 #include <sys/vmmeter.h>
 #include <sys/vnode.h>
 #include <sys/wait.h>
+
+#include <sys/signal2.h>
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
index 56e656b..043ff5f 100644 (file)
 #include <sys/sysproto.h>
 #include <sys/kern_syscall.h>
 #include <sys/thread.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
+
 #include <arch_linux/linux.h>
 #include <arch_linux/linux_proto.h>
 #include "linux_signal.h"
index a40609b..0273316 100644 (file)
@@ -42,6 +42,8 @@
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 
+#include <sys/mplock2.h>
+
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
index 440e38d..0d6cf9e 100644 (file)
 #include <sys/unistd.h>
 #include <sys/vnode.h>
 #include <sys/device.h>
-#include <sys/file2.h>
 #include <sys/kern_syscall.h>
 
+#include <sys/file2.h>
+#include <sys/mplock2.h>
+
 #include <arch_linux/linux.h>
 #include <arch_linux/linux_proto.h>
 #include "linux_util.h"
index fc3cae4..66e3c4b 100644 (file)
@@ -36,6 +36,8 @@
 #include <sys/proc.h>
 #include <sys/sysproto.h>
 
+#include <sys/mplock2.h>
+
 #include <arch_linux/linux.h>
 #include <arch_linux/linux_proto.h>
 #include "linux_util.h"
index 215ff84..77664d0 100644 (file)
@@ -38,6 +38,8 @@
 #include <sys/sysproto.h>
 #include <sys/thread.h>
 
+#include <sys/mplock2.h>
+
 #include <arch_linux/linux.h>
 #include <arch_linux/linux_proto.h>
 #include "linux_util.h"
index fecaa18..a1c27d1 100644 (file)
@@ -62,6 +62,7 @@
 #include <vm/vm_extern.h>
 
 #include <sys/sysref2.h>
+#include <sys/mplock2.h>
 
 static int exec_res_id = 0;
 
index 3e9db56..a39c37c 100644 (file)
 #include <sys/unistd.h>
 #include <sys/malloc.h>
 #include <sys/machintr.h>
+
 #include <sys/file2.h>
 #include <sys/thread2.h>
 #include <sys/sysref2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 #include <machine/cpu.h>
 
index 8c124ec..73df0a1 100644 (file)
@@ -60,6 +60,8 @@
 
 #include <vm/vm_zone.h>
 
+#include <sys/mplock2.h>
+
 /*
  * The routines implemented in this file are described in:
  *      Leffler, et al.: The Design and Implementation of the 4.3BSD
index 37fa027..57fab88 100644 (file)
@@ -47,6 +47,8 @@
 #include <sys/stat.h>
 #include <sys/acl.h>
 
+#include <sys/mplock2.h>
+
 static int vacl_set_acl(struct vnode *vp, acl_type_t type, struct acl *aclp);
 static int vacl_get_acl(struct vnode *vp, acl_type_t type, struct acl *aclp);
 static int vacl_aclcheck(struct vnode *vp, acl_type_t type, struct acl *aclp);
index 7738d04..76e51f3 100644 (file)
@@ -36,8 +36,6 @@
 #include <sys/nlookup.h>
 
 #include <sys/file.h>
-/* only on dragonfly */
-#include <sys/file2.h>
 #include <sys/fcntl.h>
 #include <sys/signal.h>
 #include <vm/vm_param.h>
@@ -73,6 +71,9 @@
 #include <sys/mount.h>
 #include <sys/ckpt.h>
 
+#include <sys/mplock2.h>
+#include <sys/file2.h>
+
 static int elf_loadphdrs(struct file *fp,  Elf_Phdr *phdr, int numsegs);
 static int elf_getnotes(struct lwp *lp, struct file *fp, size_t notesz);
 static int elf_demarshalnotes(void *src, prpsinfo_t *psinfo,
index 8c05ebd..65c737b 100644 (file)
@@ -95,7 +95,9 @@
 #include <vm/vm_map.h>
 #include <vm/vm_extern.h>
 #include <sys/sysctl.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <machine/cpu.h>
 #include <machine/limits.h>
index 2502135..19f1916 100644 (file)
 #include <sys/thread2.h>
 #include <sys/file2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 static void fsetfd_locked(struct filedesc *fdp, struct file *fp, int fd);
 static void fdreserve_locked (struct filedesc *fdp, int fd0, int incr);
index 766f8fe..4b2f5c1 100644 (file)
 #include <sys/sysctl.h>
 #include <sys/sysproto.h>
 #include <sys/uio.h>
-#include <sys/thread2.h>
 #include <sys/signalvar.h>
 #include <sys/filio.h>
+
+#include <sys/thread2.h>
 #include <sys/file2.h>
+#include <sys/mplock2.h>
 
 #include <vm/vm_zone.h>
 
index 571adf8..cfc92e3 100644 (file)
@@ -72,6 +72,7 @@
 #include <sys/reg.h>
 
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments");
 MALLOC_DEFINE(M_EXECARGS, "exec-args", "Exec arguments");
index 07930a7..ffcc1c2 100644 (file)
@@ -79,6 +79,7 @@
 
 #include <sys/thread2.h>
 #include <sys/sysref2.h>
+#include <sys/mplock2.h>
 
 static void reaplwps(void *context, int dummy);
 static void reaplwp(struct lwp *lp);
index b24aa22..a804e8b 100644 (file)
@@ -68,6 +68,7 @@
 #include <sys/thread2.h>
 #include <sys/signal2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 static MALLOC_DEFINE(M_ATFORK, "atfork", "atfork callback");
 
index acadbe1..c615fad 100644 (file)
@@ -35,7 +35,6 @@
 #include <sys/sysctl.h>
 #include <sys/thread.h>
 #include <sys/proc.h>
-#include <sys/thread2.h>
 #include <sys/random.h>
 #include <sys/serialize.h>
 #include <sys/interrupt.h>
@@ -46,6 +45,9 @@
 
 #include <sys/interrupt.h>
 
+#include <sys/thread2.h>
+#include <sys/mplock2.h>
+
 struct info_info;
 
 typedef struct intrec {
index 6b0da59..2d4bd34 100644 (file)
@@ -60,6 +60,8 @@
 #include <netinet/in.h>
 #include <netinet6/in6_var.h>
 
+#include <sys/mplock2.h>
+
 static struct prison   *prison_find(int);
 static void            prison_ipcache_init(struct prison *);
 
index f21cdf4..4fc5e51 100644 (file)
@@ -52,6 +52,9 @@
 #include <sys/sysent.h>
 
 #include <vm/vm_zone.h>
+
+#include <sys/mplock2.h>
+
 static MALLOC_DEFINE(M_KTRACE, "KTRACE", "KTRACE");
 
 #ifdef KTRACE
index 4225e03..02464c3 100644 (file)
@@ -49,6 +49,8 @@
 
 #include <vm/vm_zone.h>
 
+#include <sys/mplock2.h>
+
 #ifdef _KERNEL_VIRTUAL
 #include <dlfcn.h>
 #endif
index de2c770..7af9655 100644 (file)
@@ -38,6 +38,8 @@
 #include <sys/linker.h>
 #include <sys/proc.h>
 
+#include <sys/mplock2.h>
+
 MALLOC_DEFINE(M_MODULE, "module", "module data structures");
 
 typedef TAILQ_HEAD(, module) modulelist_t;
diff --git a/sys/kern/kern_mplock.c b/sys/kern/kern_mplock.c
new file mode 100644 (file)
index 0000000..14e2a5a
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 2009 The DragonFly Project.  All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Matthew Dillon <dillon@backplane.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Helper functions for MP lock acquisition and release.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/rtprio.h>
+#include <sys/queue.h>
+#include <sys/sysctl.h>
+#include <sys/kthread.h>
+#include <machine/cpu.h>
+#include <sys/lock.h>
+#include <sys/caps.h>
+#include <sys/spinlock.h>
+#include <sys/ktr.h>
+
+#include <sys/thread2.h>
+#include <sys/mplock2.h>
+#include <sys/spinlock2.h>
+
+#ifdef SMP
+static int chain_mplock = 0;
+static int bgl_yield = 10;
+static __int64_t mplock_contention_count = 0;
+
+SYSCTL_INT(_lwkt, OID_AUTO, chain_mplock, CTLFLAG_RW, &chain_mplock, 0, "");
+SYSCTL_INT(_lwkt, OID_AUTO, bgl_yield_delay, CTLFLAG_RW, &bgl_yield, 0, "");
+SYSCTL_QUAD(_lwkt, OID_AUTO, mplock_contention_count, CTLFLAG_RW,
+       &mplock_contention_count, 0, "spinning due to MPLOCK contention");
+
+/*
+ * Kernel Trace
+ */
+#if !defined(KTR_GIANT_CONTENTION)
+#define KTR_GIANT_CONTENTION    KTR_ALL
+#endif
+
+KTR_INFO_MASTER(giant);
+KTR_INFO(KTR_GIANT_CONTENTION, giant, beg, 0,
+       "thread=%p held %s:%-5d  want %s:%-5d",
+        sizeof(void *) * 3 + sizeof(int) * 2);
+KTR_INFO(KTR_GIANT_CONTENTION, giant, end, 1,
+       "thread=%p held %s:%-5d  want %s:%-5d",
+        sizeof(void *) * 3 + sizeof(int) * 2);
+
+#define loggiant(name)                                         \
+       KTR_LOG(giant_ ## name, curthread,                      \
+               mp_lock_holder_file, mp_lock_holder_line,       \
+               file, line)
+
+int    mp_lock;
+int    mp_lock_contention_mask;
+const char *mp_lock_holder_file;       /* debugging */
+int    mp_lock_holder_line;            /* debugging */
+
+/*
+ * Sets up the initial MP lock state near the start of the kernel boot
+ */
+void
+cpu_get_initial_mplock(void)
+{
+       mp_lock = 0;    /* cpu 0 */
+       curthread->td_mpcount = 1;
+}
+
+/*
+ * Called when the MP lock could not be trvially acquired.  The caller
+ * has already bumped td_mpcount.
+ */
+void
+_get_mplock_contested(const char *file, int line)
+{
+       globaldata_t gd = mycpu;
+       int ov;
+       int nv;
+
+       ++mplock_contention_count;
+       for (;;) {
+               ov = mp_lock;
+               nv = gd->gd_cpuid;
+               if (ov == gd->gd_cpuid)
+                       break;
+               if (ov == -1) {
+                       if (atomic_cmpset_int(&mp_lock, ov, gd->gd_cpuid))
+                               break;
+               } else {
+                       loggiant(beg);
+                       lwkt_switch();
+                       loggiant(end);
+                       KKASSERT(gd->gd_cpuid == mp_lock);
+                       break;
+               }
+       }
+}
+
+/*
+ * Called if td_mpcount went negative or if td_mpcount is 0 and we were
+ * unable to release the MP lock.  Handles sanity checks and conflicts.
+ *
+ * It is possible for the inline release to have raced an interrupt which
+ * get/rel'd the MP lock, causing the inline's cmpset to fail.  If this
+ * case occurs mp_lock will either already be in a released state or it
+ * will have already been acquired by another cpu.
+ */
+void
+_rel_mplock_contested(void)
+{
+       globaldata_t gd = mycpu;
+       int ov;
+
+       KKASSERT(gd->gd_curthread->td_mpcount >= 0);
+       for (;;) {
+               ov = mp_lock;
+               if (ov != gd->gd_cpuid)
+                       break;
+               if (atomic_cmpset_int(&mp_lock, ov, -1))
+                       break;
+       }
+}
+
+/*
+ * Called when try_mplock() fails.
+ *
+ * The inline bumped td_mpcount so we have to undo it.
+ *
+ * It is possible to race an interrupt which acquired and released the
+ * MP lock.  When combined with the td_mpcount decrement we do the MP lock
+ * can wind up in any state and possibly not even owned by us.
+ *
+ * It is also possible for this function to be called even if td_mpcount > 1
+ * if someone bumped it and raced an interrupt which then called try_mpock().
+ */
+void
+_try_mplock_contested(const char *file, int line)
+{
+       globaldata_t gd = mycpu;
+       thread_t td = gd->gd_curthread;
+       int ov;
+
+       --td->td_mpcount;
+       KKASSERT(td->td_mpcount >= 0);
+       ++mplock_contention_count;
+
+       for (;;) {
+               ov = mp_lock;
+               if (ov != gd->gd_cpuid)
+                       break;
+               if (atomic_cmpset_int(&mp_lock, ov, -1))
+                       break;
+       }
+}
+
+/*
+ * Called when cpu_try_mplock() fails.
+ *
+ * The inline did not touch td_mpcount so we do not either.
+ */
+void
+_cpu_try_mplock_contested(const char *file, int line)
+{
+       ++mplock_contention_count;
+}
+
+/*
+ * Temporarily yield the MP lock.  This is part of lwkt_user_yield()
+ * which is kinda hackish.
+ */
+void
+yield_mplock(thread_t td)
+{
+       int savecnt;
+
+       savecnt = td->td_mpcount;
+       td->td_mpcount = 1;
+       rel_mplock();
+       DELAY(bgl_yield);
+       get_mplock();
+       td->td_mpcount = savecnt;
+}
+
+#if 0
+
+/*
+ * The rel_mplock() code will call this function after releasing the
+ * last reference on the MP lock if mp_lock_contention_mask is non-zero.
+ *
+ * We then chain an IPI to a single other cpu potentially needing the
+ * lock.  This is a bit heuristical and we can wind up with IPIs flying
+ * all over the place.
+ */
+static void lwkt_mp_lock_uncontested_remote(void *arg __unused);
+
+void
+lwkt_mp_lock_uncontested(void)
+{
+    globaldata_t gd;
+    globaldata_t dgd;
+    cpumask_t mask;
+    cpumask_t tmpmask;
+    int cpuid;
+
+    if (chain_mplock) {
+       gd = mycpu;
+       clr_mplock_contention_mask(gd);
+       mask = mp_lock_contention_mask;
+       tmpmask = ~((1 << gd->gd_cpuid) - 1);
+
+       if (mask) {
+           if (mask & tmpmask)
+                   cpuid = bsfl(mask & tmpmask);
+           else
+                   cpuid = bsfl(mask);
+           atomic_clear_int(&mp_lock_contention_mask, 1 << cpuid);
+           dgd = globaldata_find(cpuid);
+           lwkt_send_ipiq(dgd, lwkt_mp_lock_uncontested_remote, NULL);
+       }
+    }
+}
+
+/*
+ * The idea is for this IPI to interrupt a potentially lower priority
+ * thread, such as a user thread, to allow the scheduler to reschedule
+ * a higher priority kernel thread that needs the MP lock.
+ *
+ * For now we set the LWKT reschedule flag which generates an AST in
+ * doreti, though theoretically it is also possible to possibly preempt
+ * here if the underlying thread was operating in user mode.  Nah.
+ */
+static void
+lwkt_mp_lock_uncontested_remote(void *arg __unused)
+{
+       need_lwkt_resched();
+}
+
+#endif
+
+#endif /* SMP */
index 9a8ad11..e0685f6 100644 (file)
@@ -44,7 +44,9 @@
 #include <sys/timex.h>
 #include <sys/timepps.h>
 #include <sys/sysctl.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 /*
  * Single-precision macros for 64-bit machines
index bd9f191..503b656 100644 (file)
@@ -48,6 +48,8 @@
 #include <sys/sysctl.h>
 #include <sys/unistd.h>
 
+#include <sys/mplock2.h>
+
 MALLOC_DEFINE(M_P31B, "p1003.1b", "Posix 1003.1B");
 
 /* p31b_proc: Return a proc struct corresponding to a pid to operate on.
index 797d51a..46997aa 100644 (file)
@@ -54,6 +54,7 @@
 #include <machine/smp.h>
 
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 static MALLOC_DEFINE(M_PGRP, "pgrp", "process group header");
 MALLOC_DEFINE(M_SESSION, "session", "session header");
index 55a54ff..a3d2bd2 100644 (file)
@@ -63,6 +63,7 @@
 
 #include <sys/thread2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 static MALLOC_DEFINE(M_CRED, "cred", "credentials");
 
index e6c8ce6..325c3d0 100644 (file)
@@ -63,6 +63,7 @@
 
 #include <sys/thread2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 static int donice (struct proc *chgp, int n);
 
index 74a48c3..5054440 100644 (file)
@@ -78,6 +78,7 @@
 
 #include <sys/thread2.h>
 #include <sys/buf2.h>
+#include <sys/mplock2.h>
 
 #include <machine/clock.h>
 #include <machine/md_var.h>
index 60abb3f..be4cfcb 100644 (file)
@@ -47,7 +47,6 @@
 #include <sys/kernel.h>
 #include <sys/sysproto.h>
 #include <sys/signalvar.h>
-#include <sys/signal2.h>
 #include <sys/resourcevar.h>
 #include <sys/vnode.h>
 #include <sys/event.h>
 #include <sys/unistd.h>
 #include <sys/kern_syscall.h>
 #include <sys/vkernel.h>
+
+#include <sys/signal2.h>
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <machine/cpu.h>
 #include <machine/smp.h>
index c621b95..93cacbf 100644 (file)
 #include <machine/cpu.h>
 
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #define arysize(ary)   (sizeof(ary)/sizeof((ary)[0]))
 
index a6e813f..04114e7 100644 (file)
@@ -47,7 +47,6 @@
 #include <sys/proc.h>
 #include <sys/kernel.h>
 #include <sys/signalvar.h>
-#include <sys/signal2.h>
 #include <sys/resourcevar.h>
 #include <sys/vmmeter.h>
 #include <sys/sysctl.h>
 #endif
 #include <sys/xwait.h>
 #include <sys/ktr.h>
+#include <sys/serialize.h>
 
+#include <sys/signal2.h>
 #include <sys/thread2.h>
 #include <sys/spinlock2.h>
 #include <sys/mutex2.h>
-#include <sys/serialize.h>
+#include <sys/mplock2.h>
 
 #include <machine/cpu.h>
 #include <machine/smp.h>
index 5b5f452..cd118d6 100644 (file)
@@ -51,6 +51,9 @@
 #include <sys/priv.h>
 #include <sys/sysproto.h>
 #include <sys/lock.h>
+
+#include <sys/mplock2.h>
+
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
 
index 869f8e0..5fb159c 100644 (file)
@@ -68,6 +68,7 @@
 #include <sys/thread2.h>
 #include <sys/spinlock2.h>
 #include <sys/buf2.h>
+#include <sys/mplock2.h>
 
 #include "opt_syslink.h"
 
index 386dbf1..2f3ec84 100644 (file)
 #include <sys/kern_syscall.h>
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
+
 #include <sys/msgport2.h>
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 struct timezone tz;
 
index 6351326..189ffb0 100644 (file)
 #include <sys/kernel.h>
 #include <sys/interrupt.h>
 #include <sys/thread.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #ifndef MAX_SOFTCLOCK_STEPS
 #define MAX_SOFTCLOCK_STEPS 100 /* Maximum allowed value of steps. */
index 82b66a9..132c3e3 100644 (file)
@@ -64,6 +64,7 @@
 #include <vm/vm_kern.h>
 
 #include <vm/vm_page2.h>
+#include <sys/mplock2.h>
 
 static void umtx_sleep_page_action_cow(vm_page_t m, vm_page_action_t action);
 
index d471478..736c6d6 100644 (file)
@@ -50,6 +50,8 @@
 #include <sys/lock.h>
 #include <sys/signalvar.h>
 
+#include <sys/mplock2.h>
+
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <vm/vm_kern.h>
index f76ff2b..9ef93fe 100644 (file)
@@ -41,6 +41,9 @@
 #include <sys/sysproto.h>              /* struct usched_set_args */
 #include <sys/systm.h>                 /* strcmp() */
 #include <sys/usched.h>        
+
+#include <sys/mplock2.h>
+
 #include <machine/smp.h>
 
 static TAILQ_HEAD(, usched) usched_list = TAILQ_HEAD_INITIALIZER(usched_list);
index 61b9d9a..a4fa8e8 100644 (file)
@@ -41,6 +41,8 @@
 #include <sys/gpt.h>
 #include <net/if_var.h>
 
+#include <sys/mplock2.h>
+
 /*
  * See also:
  *     http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt
index e90a533..6e0d85c 100644 (file)
@@ -53,6 +53,8 @@
 #include <sys/varsym.h>
 #include <sys/sysproto.h>
 
+#include <sys/mplock2.h>
+
 MALLOC_DEFINE(M_VARSYM, "varsym", "variable sets for variant symlinks");
 
 struct varsymset       varsymset_sys;
index 2b28aa4..90f595b 100644 (file)
@@ -44,6 +44,8 @@
 #include <sys/sysctl.h>
 #include <sys/utsname.h>
 
+#include <sys/mplock2.h>
+
 /*
  * MPALMOSTSAFE
  */
index 78f2c79..d713224 100644 (file)
@@ -62,6 +62,9 @@
 #include <sys/ucred.h>
 #include <sys/caps.h>
 #include <sys/sysctl.h>
+
+#include <sys/mplock2.h>
+
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
 
index 5111082..b21100e 100644 (file)
@@ -55,6 +55,7 @@
 
 #include <sys/thread2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 #include <vm/vm.h>
 #include <vm/vm_param.h>
@@ -77,9 +78,6 @@ KTR_INFO(KTR_CTXSW, ctxsw, pre, 1, "pre %p > %p", 2 * sizeof(struct thread *));
 
 static MALLOC_DEFINE(M_THREAD, "thread", "lwkt threads");
 
-#ifdef SMP
-static int mplock_countx = 0;
-#endif
 #ifdef INVARIANTS
 static int panic_on_cscount = 0;
 #endif
@@ -88,16 +86,9 @@ static __int64_t preempt_hit = 0;
 static __int64_t preempt_miss = 0;
 static __int64_t preempt_weird = 0;
 static __int64_t token_contention_count __debugvar = 0;
-static __int64_t mplock_contention_count __debugvar = 0;
 static int lwkt_use_spin_port;
-#ifdef SMP
-static int chain_mplock = 0;
-static int bgl_yield = 10;
-#endif
 static struct objcache *thread_cache;
 
-volatile cpumask_t mp_lock_contention_mask;
-
 #ifdef SMP
 static void lwkt_schedule_remote(void *arg, int arg2, struct intrframe *frame);
 #endif
@@ -139,10 +130,6 @@ TUNABLE_INT("lwkt.use_spin_port", &lwkt_use_spin_port);
 #ifdef INVARIANTS
 SYSCTL_INT(_lwkt, OID_AUTO, panic_on_cscount, CTLFLAG_RW, &panic_on_cscount, 0, "");
 #endif
-#ifdef SMP
-SYSCTL_INT(_lwkt, OID_AUTO, chain_mplock, CTLFLAG_RW, &chain_mplock, 0, "");
-SYSCTL_INT(_lwkt, OID_AUTO, bgl_yield_delay, CTLFLAG_RW, &bgl_yield, 0, "");
-#endif
 SYSCTL_QUAD(_lwkt, OID_AUTO, switch_count, CTLFLAG_RW, &switch_count, 0, "");
 SYSCTL_QUAD(_lwkt, OID_AUTO, preempt_hit, CTLFLAG_RW, &preempt_hit, 0, "");
 SYSCTL_QUAD(_lwkt, OID_AUTO, preempt_miss, CTLFLAG_RW, &preempt_miss, 0, "");
@@ -150,24 +137,9 @@ SYSCTL_QUAD(_lwkt, OID_AUTO, preempt_weird, CTLFLAG_RW, &preempt_weird, 0, "");
 #ifdef INVARIANTS
 SYSCTL_QUAD(_lwkt, OID_AUTO, token_contention_count, CTLFLAG_RW,
        &token_contention_count, 0, "spinning due to token contention");
-SYSCTL_QUAD(_lwkt, OID_AUTO, mplock_contention_count, CTLFLAG_RW,
-       &mplock_contention_count, 0, "spinning due to MPLOCK contention");
 #endif
 
 /*
- * Kernel Trace
- */
-#if !defined(KTR_GIANT_CONTENTION)
-#define KTR_GIANT_CONTENTION   KTR_ALL
-#endif
-
-KTR_INFO_MASTER(giant);
-KTR_INFO(KTR_GIANT_CONTENTION, giant, beg, 0, "thread=%p", sizeof(void *));
-KTR_INFO(KTR_GIANT_CONTENTION, giant, end, 1, "thread=%p", sizeof(void *));
-
-#define loggiant(name) KTR_LOG(giant_ ## name, curthread)
-
-/*
  * These helper procedures handle the runq, they can only be called from
  * within a critical section.
  *
@@ -662,10 +634,6 @@ again:
                    TAILQ_FOREACH(ntd, &gd->gd_tdrunq[nq], td_threadq) {
                        if (ntd->td_mpcount && !mpheld && !cpu_try_mplock()) {
                            /* spinning due to MP lock being held */
-#ifdef INVARIANTS
-                           ++mplock_contention_count;
-#endif
-                           /* mplock still not held, 'mpheld' still valid */
                            continue;
                        }
 
@@ -697,26 +665,35 @@ again:
                     * reschedule when the MP lock might become available.
                     */
                    if (nq < TDPRI_KERN_LPSCHED) {
+                       break;  /* for now refuse to run */
+#if 0
                        if (chain_mplock == 0)
                                break;
-                       atomic_set_int(&mp_lock_contention_mask,
-                                      gd->gd_cpumask);
                        /* continue loop, allow user threads to be scheduled */
+#endif
                    }
                }
+
+               /*
+                * Case where a (kernel) thread needed the MP lock and could
+                * not get one, and we may or may not have found another
+                * thread which does not need the MP lock to run while
+                * we wait (ntd).
+                */
                if (ntd == NULL) {
-                   cpu_mplock_contested();
                    ntd = &gd->gd_idlethread;
                    ntd->td_flags |= TDF_IDLE_NOHLT;
+                   set_mplock_contention_mask(gd);
+                   cpu_mplock_contested();
                    goto using_idle_thread;
                } else {
+                   clr_mplock_contention_mask(gd);
                    ++gd->gd_cnt.v_swtch;
                    TAILQ_REMOVE(&gd->gd_tdrunq[nq], ntd, td_threadq);
                    TAILQ_INSERT_TAIL(&gd->gd_tdrunq[nq], ntd, td_threadq);
                }
            } else {
-               if (ntd->td_mpcount)
-                       ++mplock_countx;
+               clr_mplock_contention_mask(gd);
                ++gd->gd_cnt.v_swtch;
                TAILQ_REMOVE(&gd->gd_tdrunq[nq], ntd, td_threadq);
                TAILQ_INSERT_TAIL(&gd->gd_tdrunq[nq], ntd, td_threadq);
@@ -752,12 +729,10 @@ using_idle_thread:
             */
            if (ntd->td_mpcount) {
                mpheld = MP_LOCK_HELD();
-               if (gd->gd_trap_nesting_level == 0 && panicstr == NULL) {
+               if (gd->gd_trap_nesting_level == 0 && panicstr == NULL)
                    panic("Idle thread %p was holding the BGL!", ntd);
-               } else if (mpheld == 0) {
-                   cpu_mplock_contested();
+               if (mpheld == 0)
                    goto again;
-               }
            }
 #endif
        }
@@ -1016,15 +991,8 @@ lwkt_user_yield(void)
      * has a chaining effect since if the interrupt is blocked, so is
      * the event, so normal scheduling will not pick up on the problem.
      */
-    if (mplock_countx && td->td_mpcount) {
-       int savecnt = td->td_mpcount;
-
-       td->td_mpcount = 1;
-       mplock_countx = 0;
-       rel_mplock();
-       DELAY(bgl_yield);
-       get_mplock();
-       td->td_mpcount = savecnt;
+    if (mp_lock_contention_mask && td->td_mpcount) {
+       yield_mplock(td);
     }
 #endif
 
@@ -1549,73 +1517,4 @@ lwkt_smp_stopped(void)
     crit_exit_gd(gd);
 }
 
-/*
- * get_mplock() calls this routine if it is unable to obtain the MP lock.
- * get_mplock() has already incremented td_mpcount.  We must block and
- * not return until giant is held.
- *
- * All we have to do is lwkt_switch() away.  The LWKT scheduler will not
- * reschedule the thread until it can obtain the giant lock for it.
- */
-void
-lwkt_mp_lock_contested(void)
-{
-    ++mplock_countx;
-    loggiant(beg);
-    lwkt_switch();
-    loggiant(end);
-}
-
-/*
- * The rel_mplock() code will call this function after releasing the
- * last reference on the MP lock if mp_lock_contention_mask is non-zero.
- *
- * We then chain an IPI to a single other cpu potentially needing the
- * lock.  This is a bit heuristical and we can wind up with IPIs flying
- * all over the place.
- */
-static void lwkt_mp_lock_uncontested_remote(void *arg __unused);
-
-void
-lwkt_mp_lock_uncontested(void)
-{
-    globaldata_t gd;
-    globaldata_t dgd;
-    cpumask_t mask;
-    cpumask_t tmpmask;
-    int cpuid;
-
-    if (chain_mplock) {
-       gd = mycpu;
-       atomic_clear_int(&mp_lock_contention_mask, gd->gd_cpumask);
-       mask = mp_lock_contention_mask;
-       tmpmask = ~((1 << gd->gd_cpuid) - 1);
-
-       if (mask) {
-           if (mask & tmpmask)
-                   cpuid = bsfl(mask & tmpmask);
-           else
-                   cpuid = bsfl(mask);
-           atomic_clear_int(&mp_lock_contention_mask, 1 << cpuid);
-           dgd = globaldata_find(cpuid);
-           lwkt_send_ipiq(dgd, lwkt_mp_lock_uncontested_remote, NULL);
-       }
-    }
-}
-
-/*
- * The idea is for this IPI to interrupt a potentially lower priority
- * thread, such as a user thread, to allow the scheduler to reschedule
- * a higher priority kernel thread that needs the MP lock.
- *
- * For now we set the LWKT reschedule flag which generates an AST in
- * doreti, though theoretically it is also possible to possibly preempt
- * here if the underlying thread was operating in user mode.  Nah.
- */
-static void
-lwkt_mp_lock_uncontested_remote(void *arg __unused)
-{
-       need_lwkt_resched();
-}
-
 #endif
index 0059dcd..2592977 100644 (file)
@@ -52,6 +52,7 @@
 #include <machine/stdarg.h>    /* for device_printf() */
 
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL);
 
index 25becac..8f46cf6 100644 (file)
@@ -42,7 +42,9 @@
 #include <sys/proc.h>
 #include <sys/resourcevar.h>
 #include <sys/sysctl.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <machine/cpu.h>
 
index 2463f5f..8078bc6 100644 (file)
@@ -68,7 +68,9 @@
 #endif
 #include <vm/vm.h>
 #include <vm/vm_page.h>
+
 #include <sys/file2.h>
+#include <sys/mplock2.h>
 
 #include <machine/limits.h>
 
index 88619c9..9203d13 100644 (file)
@@ -63,6 +63,7 @@
 
 #include <sys/file2.h>
 #include <sys/signal2.h>
+#include <sys/mplock2.h>
 
 #include <machine/cpufunc.h>
 
index 8267ead..84cd8a3 100644 (file)
@@ -49,7 +49,9 @@
 
 #include <sys/user.h>
 #include <vfs/procfs/procfs.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 /* use the equivalent procfs code */
 #if 0
index 835f007..6ce1948 100644 (file)
@@ -51,6 +51,8 @@
 #include <sys/filedesc.h>
 #include <sys/ucred.h>
 
+#include <sys/mplock2.h>
+
 #include <net/if.h>
 #include <net/route.h>
 
index 0aff652..a53974b 100644 (file)
@@ -34,6 +34,8 @@
 #include <sys/malloc.h>
 #include <sys/jail.h>
 
+#include <sys/mplock2.h>
+
 static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues");
 
 static void msginit (void *);
index fd800ee..ee0ae08 100644 (file)
@@ -22,6 +22,8 @@
 #include <sys/malloc.h>
 #include <sys/jail.h>
 
+#include <sys/mplock2.h>
+
 static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores");
 
 static void seminit (void *);
index 4a6eb45..b29ae5d 100644 (file)
@@ -48,6 +48,8 @@
 #include <sys/sysent.h>
 #include <sys/jail.h>
 
+#include <sys/mplock2.h>
+
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <sys/lock.h>
index 0c4b5ab..5aaa424 100644 (file)
@@ -79,6 +79,7 @@
 #include <sys/thread2.h>
 #include <sys/msgport2.h>
 #include <sys/socketvar2.h>
+#include <sys/mplock2.h>
 #include <net/netmsg2.h>
 
 #ifdef SCTP
index f021acf..8737423 100644 (file)
@@ -42,6 +42,7 @@
 
 #include <sys/thread2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 /*
  * Priorities.  Note that with 32 run queues per scheduler each queue
index bd2d205..aff357e 100644 (file)
@@ -50,6 +50,7 @@
 
 #include <sys/thread2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 #define MAXPRI                 128
 #define PRIBASE_REALTIME       0
index ecb3e0e..2e9dcc2 100644 (file)
 #include <vm/vm_map.h>
 #include <vm/vm_zone.h>
 #include <sys/aio.h>
+
 #include <sys/file2.h>
 #include <sys/buf2.h>
 #include <sys/sysref2.h>
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <machine/limits.h>
 #include "opt_vfs_aio.h"
index cdf7d68..5b6a55d 100644 (file)
@@ -57,6 +57,7 @@
 #include <sys/buf2.h>
 #include <sys/thread2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 #include <vm/vm_page2.h>
 
 #include "opt_ddb.h"
index 55984d6..8367997 100644 (file)
@@ -89,6 +89,7 @@
 #include <ddb/ddb.h>
 
 #include <sys/sysref2.h>
+#include <sys/mplock2.h>
 
 #define MAX_RECURSION_DEPTH    64
 
index 6f4616c..0a51718 100644 (file)
@@ -72,6 +72,7 @@
 #include <sys/buf2.h>
 #include <sys/file2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 #include <vm/vm.h>
 #include <vm/vm_object.h>
index ee44f49..2e17d00 100644 (file)
@@ -58,6 +58,7 @@
 #include <sys/syslog.h>
 
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 static int vn_closefile (struct file *fp);
 static int vn_ioctl (struct file *fp, u_long com, caddr_t data,
index 2924a28..cb795b7 100644 (file)
@@ -63,6 +63,7 @@
 #include <sys/vnode.h>
 
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <net/if.h>
 #include <net/bpf.h>
index c26e452..2b736bc 100644 (file)
@@ -57,7 +57,9 @@
 #include <sys/sockio.h>
 #include <sys/sysctl.h>
 #include <sys/thread.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <net/if.h>
 #include <net/netisr.h>
index ddba6ef..ede54c8 100644 (file)
@@ -53,6 +53,8 @@
 #include <sys/socket.h>
 #include <sys/sockio.h>
 
+#include <sys/mplock2.h>
+
 #include <net/if.h>
 #include <net/if_types.h>
 #include <net/ifq_var.h>
index 6210748..20bf240 100644 (file)
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
 #include <sys/syslog.h>
-#include <sys/thread2.h>
 #include <sys/ucred.h>
 #include <sys/in_cksum.h>
 #include <sys/lock.h>
 
 #include <net/if.h>
 #include <net/route.h>
-#include <net/netmsg2.h>
 #include <net/pfil.h>
 #include <net/dummynet/ip_dummynet.h>
 
+#include <sys/thread2.h>
+#include <sys/mplock2.h>
+#include <net/netmsg2.h>
+
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/in_var.h>
index 2a3d620..209aede 100644 (file)
@@ -56,6 +56,7 @@
 #include <sys/thread2.h>
 #include <sys/msgport2.h>
 #include <net/netmsg2.h>
+#include <sys/mplock2.h>
 
 #define NETISR_GET_MPLOCK(ni) \
 do { \
index 6278664..4dbc9c0 100644 (file)
@@ -41,6 +41,7 @@
 #include <net/if.h>
 #include <net/pfil.h>
 #include <net/netmsg2.h>
+#include <sys/mplock2.h>
 
 #define PFIL_CFGPORT   cpu_portfn(0)
 
index 7d2e160..2010b01 100644 (file)
 #include <sys/sockio.h>
 #include <sys/sysctl.h>
 #include <sys/systm.h>
-#include <sys/thread2.h>
 #include <sys/ttycom.h>
 #include <sys/uio.h>
 #include <sys/vnode.h>
 #include <sys/serialize.h>
 
+#include <sys/thread2.h>
+#include <sys/mplock2.h>
+
 #include <net/bpf.h>
 #include <net/ethernet.h>
 #include <net/if.h>
index 91d55c0..7a06e71 100644 (file)
@@ -44,6 +44,8 @@
 #include <sys/vnode.h>
 #include <sys/malloc.h>
 
+#include <sys/mplock2.h>
+
 #include <net/if.h>
 #include <net/if_types.h>
 #include <net/ifq_var.h>
index 5667b9b..11b86f6 100644 (file)
 #include <sys/thread2.h>
 #include <sys/msgport2.h>
 #include <net/netmsg2.h>
+#include <sys/mplock2.h>
 
 #ifdef CARP
 #include <netinet/ip_carp.h>
index 5de7634..02d1bfd 100644 (file)
@@ -56,7 +56,6 @@
 #include <sys/systm.h>
 #include <sys/proc.h>
 #include <sys/priv.h>
-#include <sys/thread2.h>
 #include <sys/in_cksum.h>
 #include <sys/lock.h>
 #ifdef SMP
 
 #include <net/if.h>
 #include <net/route.h>
+
 #ifdef SMP
 #include <net/netmsg2.h>
 #endif
+#include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
index fe74292..2263614 100644 (file)
@@ -95,6 +95,8 @@
 #include <sys/in_cksum.h>
 #include <sys/lock.h>
 
+#include <sys/mplock2.h>
+
 #include <machine/stdarg.h>
 
 #include <net/if.h>
index ab53a0f..c6d7995 100644 (file)
 #include <sys/proc.h>
 #include <sys/priv.h>
 #include <sys/sysctl.h>
-#include <sys/thread2.h>
 #include <sys/in_cksum.h>
 #include <sys/lock.h>
 
+#include <sys/thread2.h>
+#include <sys/mplock2.h>
+
 #include <net/if.h>
 #include <net/netisr.h>
 #include <net/pfil.h>
index 942b0ee..99f96c0 100644 (file)
 #endif
 
 #include <sys/md5.h>
-#include <sys/msgport2.h>
 #include <machine/smp.h>
 
+#include <sys/msgport2.h>
+#include <sys/mplock2.h>
 #include <net/netmsg2.h>
 
 #if !defined(KTR_TCP)
index f36a45b..f702ed6 100644 (file)
@@ -43,6 +43,8 @@
 #include <sys/uio.h>
 #include <sys/msgport.h>
 
+#include <sys/mplock2.h>
+
 #include "ncp.h"
 #include "ncp_conn.h"
 #include "ncp_subr.h"
index 401c910..8ce8655 100644 (file)
 #include <sys/kernel.h>
 #include <sys/fcntl.h>
 #include <sys/proc.h>
+
 #include <sys/file2.h>
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <opencrypto/cryptodev.h>
 #include <opencrypto/xform.h>
index 1d5a9d8..f775a91 100644 (file)
@@ -175,7 +175,6 @@ platform/pc32/i386/est.c            optional        cpu_enable_est
 #arch/i386/i386/io_apic.c              optional        smp
 #arch/i386/i386/local_apic.c           optional        smp
 platform/pc32/i386/mpboot.s            optional        smp
-platform/pc32/i386/mplock.s            optional        smp
 platform/pc32/i386/mp_clock.c          optional        smp
 platform/pc32/i386/mp_machdep.c                optional        smp
 platform/pc32/i386/mp_madt.c           optional        smp
index 0ee2246..b880bf7 100644 (file)
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/uio.h>
-#include <sys/thread2.h>
 #include <sys/bus_dma.h>
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
 #include <sys/lock.h>
+
+#include <sys/thread2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 #include <vm/vm.h>
 #include <vm/vm_page.h>
index aa826df..0980eae 100644 (file)
@@ -95,9 +95,6 @@ ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
 ASSYM(TDF_RUNNING, TDF_RUNNING);
 ASSYM(TDF_USINGFP, TDF_USINGFP);
 ASSYM(TDF_KERNELFP, TDF_KERNELFP);
-#ifdef SMP
-ASSYM(MP_FREE_LOCK, MP_FREE_LOCK);
-#endif
 ASSYM(MACHINTR_INTREN, offsetof(struct machintr_abi, intren));
 
 ASSYM(TD_SAVEFPU, offsetof(struct thread, td_mach) + offsetof(struct md_thread, mtd_savefpu));
index 95815a3..0903ec8 100644 (file)
@@ -88,6 +88,7 @@
 #include <vm/vm_extern.h>
 
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <sys/user.h>
 #include <sys/exec.h>
index dc3dfca..b853258 100644 (file)
@@ -49,6 +49,8 @@
 #include <sys/gmon.h>
 #endif
 
+#include <sys/mplock2.h>
+
 #include <machine/smp.h>
 #include <machine_base/apic/apicreg.h>
 #include <machine/atomic.h>
diff --git a/sys/platform/pc32/i386/mplock.s b/sys/platform/pc32/i386/mplock.s
deleted file mode 100644 (file)
index 45f1dc1..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * $FreeBSD: src/sys/i386/i386/mplock.s,v 1.29.2.2 2000/05/16 06:58:06 dillon Exp $
- * $DragonFly: src/sys/platform/pc32/i386/mplock.s,v 1.21 2006/11/07 06:43:24 dillon Exp $
- *
- * Copyright (c) 2003,2004 The DragonFly Project.  All rights reserved.
- * 
- * This code is derived from software contributed to The DragonFly Project
- * by Matthew Dillon <dillon@backplane.com>
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name of The DragonFly Project nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific, prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- *                             DragonFly MPLOCK operation
- *
- * Each thread has an MP lock count, td_mpcount, and there is a shared
- * global called mp_lock.  mp_lock is the physical MP lock and contains either
- * -1 or the cpuid of the cpu owning the lock.  The count is *NOT* integrated
- * into mp_lock but instead resides in each thread td_mpcount.
- *
- * When obtaining or releasing the MP lock the td_mpcount is PREDISPOSED
- * to the desired count *PRIOR* to operating on the mp_lock itself.  MP
- * lock operations can occur outside a critical section with interrupts
- * enabled with the provisio (which the routines below handle) that an
- * interrupt may come along and preempt us, racing our cmpxchgl instruction
- * to perform the operation we have requested by pre-disposing td_mpcount.
- *
- * Additionally, the LWKT threading system manages the MP lock and
- * lwkt_switch(), in particular, may be called after pre-disposing td_mpcount
- * to handle 'blocking' on the MP lock.
- *
- *
- * Recoded from the FreeBSD original:
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- */
-
-#include <machine/asmacros.h>
-#include <machine_base/apic/apicreg.h>
-
-#include "assym.s"
-
-/*
- * YYY Debugging only.  Define this to be paranoid about invalidating the
- * TLB when we get giant.
- */
-#undef PARANOID_INVLTLB
-
-       .data
-       ALIGN_DATA
-#ifdef SMP
-       .globl  mp_lock
-mp_lock:
-       .long   -1                      /* initialized to not held */
-#endif
-
-       .text
-       SUPERALIGN_TEXT
-
-       /*
-        * Note on cmpxchgl... exchanges ecx with mem if mem matches eax.
-        * Z=1 (jz) on success.   A lock prefix is required for MP.
-        */
-NON_GPROF_ENTRY(cpu_get_initial_mplock)
-       movl    PCPU(curthread),%ecx
-       movl    $1,TD_MPCOUNT(%ecx)     /* curthread has mpcount of 1 */
-       movl    $0,mp_lock              /* owned by cpu 0 */
-       NON_GPROF_RET
-
-       /*
-        * cpu_try_mplock() returns non-zero on success, 0 on failure.  It
-        * only adjusts mp_lock, it does not touch td_mpcount.  Callers
-        * should always increment td_mpcount *before* trying to acquire
-        * the actual lock, predisposing td_mpcount to the desired state of
-        * the lock.
-        *
-        * NOTE! Only call cpu_try_mplock() inside a critical section.  If
-        * you don't an interrupt can come along and get and release
-        * the lock before our cmpxchgl instruction, causing us to fail 
-        * but resulting in the lock being held by our cpu.
-        */
-NON_GPROF_ENTRY(cpu_try_mplock)
-       movl    PCPU(cpuid),%ecx
-       movl    $-1,%eax
-       lock cmpxchgl %ecx,mp_lock      /* ecx<->mem if eax matches */
-       jnz     1f
-#ifdef PARANOID_INVLTLB
-       movl    %cr3,%eax; movl %eax,%cr3       /* YYY check and remove */
-#endif
-       movl    $1,%eax
-       NON_GPROF_RET
-1:
-       subl    %eax,%eax
-       NON_GPROF_RET
-
-       /*
-        * get_mplock() Obtains the MP lock and may switch away if it cannot
-        * get it.  This routine may be called WITHOUT a critical section
-        * and with cpu interrupts enabled.
-        *
-        * To handle races in a sane fashion we predispose TD_MPCOUNT,
-        * which prevents us from losing the lock in a race if we already
-        * have it or happen to get it.  It also means that we might get
-        * the lock in an interrupt race before we have a chance to execute
-        * our cmpxchgl instruction, so we have to handle that case.
-        * Fortunately simply calling lwkt_switch() handles the situation
-        * for us and also 'blocks' us until the MP lock can be obtained.
-        */
-NON_GPROF_ENTRY(get_mplock)
-       movl    PCPU(cpuid),%ecx
-       movl    PCPU(curthread),%edx
-       incl    TD_MPCOUNT(%edx)        /* predispose */
-       cmpl    %ecx,mp_lock
-       jne     1f
-       NON_GPROF_RET                   /* success! */
-
-       /*
-        * We don't already own the mp_lock, use cmpxchgl to try to get
-        * it.
-        */
-1:
-       movl    $-1,%eax
-       lock cmpxchgl %ecx,mp_lock
-       jnz     2f
-#ifdef PARANOID_INVLTLB
-       movl    %cr3,%eax; movl %eax,%cr3 /* YYY check and remove */
-#endif
-       NON_GPROF_RET                   /* success */
-
-       /*
-        * Failure, but we could end up owning mp_lock anyway due to
-        * an interrupt race.  lwkt_switch() will clean up the mess
-        * and 'block' until the mp_lock is obtained.
-        *
-        * Create a stack frame for the call so KTR logs the stack
-        * backtrace properly.
-        */
-2:
-       pushl   %ebp
-       movl    %esp,%ebp
-       call    lwkt_mp_lock_contested
-       popl    %ebp
-#ifdef INVARIANTS
-       movl    PCPU(cpuid),%eax        /* failure */
-       cmpl    %eax,mp_lock
-       jne     4f
-#endif
-       NON_GPROF_RET
-#ifdef INVARIANTS
-4:
-       cmpl    $0,panicstr             /* don't double panic */
-       je      badmp_get2
-       NON_GPROF_RET
-#endif
-
-       /*
-        * try_mplock() attempts to obtain the MP lock.  1 is returned on
-        * success, 0 on failure.  We do not have to be in a critical section
-        * and interrupts are almost certainly enabled.
-        *
-        * We must pre-dispose TD_MPCOUNT in order to deal with races in
-        * a reasonable way.
-        *
-        */
-NON_GPROF_ENTRY(try_mplock)
-       movl    PCPU(cpuid),%ecx
-       movl    PCPU(curthread),%edx
-       incl    TD_MPCOUNT(%edx)                /* pre-dispose for race */
-       cmpl    %ecx,mp_lock
-       je      1f                              /* trivial success */
-       movl    $-1,%eax
-       lock cmpxchgl %ecx,mp_lock
-       jnz     2f
-       /*
-        * Success
-        */
-#ifdef PARANOID_INVLTLB
-       movl    %cr3,%eax; movl %eax,%cr3       /* YYY check and remove */
-#endif
-1:
-       movl    $1,%eax                         /* success (cmpxchgl good!) */
-       NON_GPROF_RET
-
-       /*
-        * The cmpxchgl failed but we might have raced.  Undo the mess by
-        * predispoing TD_MPCOUNT and then checking.  If TD_MPCOUNT is
-        * still non-zero we don't care what state the lock is in (since
-        * we obviously didn't own it above), just return failure even if
-        * we won the lock in an interrupt race.  If TD_MPCOUNT is zero
-        * make sure we don't own the lock in case we did win it in a race.
-        */
-2:
-       decl    TD_MPCOUNT(%edx)
-       cmpl    $0,TD_MPCOUNT(%edx)
-       jne     3f
-       movl    PCPU(cpuid),%eax
-       movl    $-1,%ecx
-       lock cmpxchgl %ecx,mp_lock
-3:
-       subl    %eax,%eax
-       NON_GPROF_RET
-       
-       /*
-        * rel_mplock() releases a previously obtained MP lock.
-        *
-        * In order to release the MP lock we pre-dispose TD_MPCOUNT for
-        * the release and basically repeat the release portion of try_mplock
-        * above.
-        */
-NON_GPROF_ENTRY(rel_mplock)
-       movl    PCPU(curthread),%edx
-       movl    TD_MPCOUNT(%edx),%eax
-#ifdef INVARIANTS
-       cmpl    $0,%eax
-       je      badmp_rel
-#endif
-       subl    $1,%eax
-       movl    %eax,TD_MPCOUNT(%edx)
-       cmpl    $0,%eax
-       jne     3f
-       movl    PCPU(cpuid),%eax
-       movl    $-1,%ecx
-       lock cmpxchgl %ecx,mp_lock
-       movl    mp_lock_contention_mask,%eax
-       cmpl    $0,%eax
-       je      3f
-       call    lwkt_mp_lock_uncontested
-3:
-       NON_GPROF_RET
-
-#ifdef INVARIANTS
-
-badmp_get:
-       pushl   $bmpsw1
-       call    panic
-badmp_get2:
-       pushl   $bmpsw1a
-       call    panic
-badmp_rel:
-       pushl   $bmpsw2
-       call    panic
-
-       .data
-
-bmpsw1:
-       .asciz  "try/get_mplock(): already have lock! %d %p"
-
-bmpsw1a:
-       .asciz  "try/get_mplock(): failed on count or switch %d %p"
-
-bmpsw2:
-       .asciz  "rel_mplock(): mpcount already 0 @ %p %p %p %p %p %p %p %p!"
-
-#endif
-
index 9c7459f..c9d4988 100644 (file)
@@ -61,7 +61,9 @@
 #include <machine/globaldata.h>        /* mdcpu */
 
 #include <vm/vm_kern.h>                /* for kernel_map */
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #define MAX_LD 8192
 #define LD_PER_PAGE 512
index 9eec21f..e7f8758 100644 (file)
 #include <machine/vm86.h>
 
 #include <ddb/ddb.h>
+
 #include <sys/msgport2.h>
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #ifdef SMP
 
index 1d88690..b393fa3 100644 (file)
@@ -43,7 +43,9 @@
 #include <vm/vm_page.h>
 
 #include <sys/user.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <machine/md_var.h>
 #include <machine/pcb_ext.h>   /* pcb.h included via sys/user.h */
index 1489003..a59a2a0 100644 (file)
@@ -77,7 +77,9 @@
 #include <vm/vm_extern.h>
 
 #include <sys/user.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <bus/isa/isa.h>
 
index 8d2bab3..48346e2 100644 (file)
 #include <machine/psl.h>
 #endif
 
-/*
- * MP_FREE_LOCK is used by both assembly and C under SMP.
- */
-#ifdef SMP
-#define MP_FREE_LOCK           0xffffffff      /* value of lock when free */
-#endif
-
 #ifdef LOCORE
 
 /*
@@ -172,47 +165,5 @@ spin_lock_init(spinlock_t lock)
 
 #endif  /* _KERNEL */
 
-#if defined(_KERNEL) || defined(_UTHREAD)
-
-/*
- * MP LOCK functions for SMP and UP.  Under UP the MP lock does not exist
- * but we leave a few functions intact as macros for convenience.
- */
-#ifdef SMP
-
-void   get_mplock(void);
-int    try_mplock(void);
-void   rel_mplock(void);
-int    cpu_try_mplock(void);
-void   cpu_get_initial_mplock(void);
-
-extern u_int   mp_lock;
-
-#define MP_LOCK_HELD()   (mp_lock == mycpu->gd_cpuid)
-#define ASSERT_MP_LOCK_HELD(td)   KASSERT(MP_LOCK_HELD(), ("MP_LOCK_HELD(): not held thread %p", td))
-
-static __inline void
-cpu_rel_mplock(void)
-{
-       mp_lock = MP_FREE_LOCK;
-}
-
-static __inline int
-owner_mplock(void)
-{
-       return (mp_lock);
-}
-
-#else
-
-#define get_mplock()
-#define try_mplock()   1
-#define rel_mplock()
-#define owner_mplock() 0       /* always cpu 0 */
-#define MP_LOCK_HELD() (!0)
-#define ASSERT_MP_LOCK_HELD(td)
-
-#endif /* SMP */
-#endif  /* _KERNEL || _UTHREAD */
 #endif /* LOCORE */
 #endif /* !_MACHINE_LOCK_H_ */
index 5509800..1516315 100644 (file)
@@ -53,7 +53,9 @@
 #include <sys/syslog.h>
 #endif
 #include <sys/signalvar.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #ifndef SMP
 #include <machine/asmacros.h>
index b92879c..4c39be3 100644 (file)
@@ -92,7 +92,6 @@ platform/pc64/x86_64/atomic.c                 standard                        \
         compile-with    "${CC} -c ${CFLAGS} ${WERROR} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}"
 platform/pc64/x86_64/autoconf.c        standard
 platform/pc64/x86_64/mpboot.S          optional        smp
-platform/pc64/x86_64/mplock.s          optional        smp
 
 # DDB XXX
 cpu/x86_64/misc/x86_64-gdbstub.c               optional        ddb
index ce80365..a6ccdfd 100644 (file)
 #include <machine/psl.h>
 #endif
 
-/*
- * MP_FREE_LOCK is used by both assembly and C under SMP.
- */
-#ifdef SMP
-#define MP_FREE_LOCK           0xffffffff      /* value of lock when free */
-#endif
-
 #ifdef LOCORE
 
 /*
@@ -172,47 +165,5 @@ spin_lock_init(spinlock_t lock)
 
 #endif  /* _KERNEL */
 
-#if defined(_KERNEL) || defined(_UTHREAD)
-
-/*
- * MP LOCK functions for SMP and UP.  Under UP the MP lock does not exist
- * but we leave a few functions intact as macros for convenience.
- */
-#ifdef SMP
-
-void   get_mplock(void);
-int    try_mplock(void);
-void   rel_mplock(void);
-int    cpu_try_mplock(void);
-void   cpu_get_initial_mplock(void);
-
-extern u_int   mp_lock;
-
-#define MP_LOCK_HELD()   (mp_lock == mycpu->gd_cpuid)
-#define ASSERT_MP_LOCK_HELD(td)   KASSERT(MP_LOCK_HELD(), ("MP_LOCK_HELD(): not held thread %p", td))
-
-static __inline void
-cpu_rel_mplock(void)
-{
-       mp_lock = MP_FREE_LOCK;
-}
-
-static __inline int
-owner_mplock(void)
-{
-       return (mp_lock);
-}
-
-#else /* !SMP */
-
-#define get_mplock()
-#define try_mplock()   1
-#define rel_mplock()
-#define owner_mplock() 0       /* always cpu 0 */
-#define MP_LOCK_HELD() (!0)
-#define ASSERT_MP_LOCK_HELD(td)
-
-#endif /* SMP */
-#endif  /* _KERNEL || _UTHREAD */
 #endif /* LOCORE */
 #endif /* !_MACHINE_LOCK_H_ */
index df35c5c..58a085b 100644 (file)
@@ -54,7 +54,9 @@
 #include <sys/syslog.h>
 #endif
 #include <sys/signalvar.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #ifndef SMP
 #include <machine/asmacros.h>
index 0ee2246..b880bf7 100644 (file)
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/uio.h>
-#include <sys/thread2.h>
 #include <sys/bus_dma.h>
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
 #include <sys/lock.h>
+
+#include <sys/thread2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 #include <vm/vm.h>
 #include <vm/vm_page.h>
index fbad5da..0c72a7a 100644 (file)
@@ -85,6 +85,7 @@
 #include <vm/vm_extern.h>
 
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <sys/user.h>
 #include <sys/exec.h>
index 4ba86bc..560c600 100644 (file)
@@ -37,6 +37,8 @@
 #include <sys/cons.h>  /* cngetc() */
 #include <sys/machintr.h>
 
+#include <sys/mplock2.h>
+
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <vm/pmap.h>
diff --git a/sys/platform/pc64/x86_64/mplock.s b/sys/platform/pc64/x86_64/mplock.s
deleted file mode 100644 (file)
index b0fc0a8..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * $FreeBSD: src/sys/i386/i386/mplock.s,v 1.29.2.2 2000/05/16 06:58:06 dillon Exp $
- * $DragonFly: src/sys/platform/pc32/i386/mplock.s,v 1.21 2006/11/07 06:43:24 dillon Exp $
- *
- * Copyright (c) 2003,2004 The DragonFly Project.  All rights reserved.
- * 
- * This code is derived from software contributed to The DragonFly Project
- * by Matthew Dillon <dillon@backplane.com>
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name of The DragonFly Project nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific, prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- *                             DragonFly MPLOCK operation
- *
- * Each thread has an MP lock count, td_mpcount, and there is a shared
- * global called mp_lock.  mp_lock is the physical MP lock and contains either
- * -1 or the cpuid of the cpu owning the lock.  The count is *NOT* integrated
- * into mp_lock but instead resides in each thread td_mpcount.
- *
- * When obtaining or releasing the MP lock the td_mpcount is PREDISPOSED
- * to the desired count *PRIOR* to operating on the mp_lock itself.  MP
- * lock operations can occur outside a critical section with interrupts
- * enabled with the provisio (which the routines below handle) that an
- * interrupt may come along and preempt us, racing our cmpxchgl instruction
- * to perform the operation we have requested by pre-disposing td_mpcount.
- *
- * Additionally, the LWKT threading system manages the MP lock and
- * lwkt_switch(), in particular, may be called after pre-disposing td_mpcount
- * to handle 'blocking' on the MP lock.
- *
- *
- * Recoded from the FreeBSD original:
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- */
-
-#include <machine/asmacros.h>
-#include <machine_base/apic/apicreg.h>
-
-#include "assym.s"
-
-/*
- * YYY Debugging only.  Define this to be paranoid about invalidating the
- * TLB when we get giant.
- */
-#undef PARANOID_INVLTLB
-
-       .data
-       ALIGN_DATA
-#ifdef SMP
-       .globl  mp_lock
-mp_lock:
-       .long   -1                      /* initialized to not held */
-#endif
-
-       .text
-       SUPERALIGN_TEXT
-
-       /*
-        * Note on cmpxchgl... exchanges ecx with mem if mem matches eax.
-        * Z=1 (jz) on success.   A lock prefix is required for MP.
-        */
-NON_GPROF_ENTRY(cpu_get_initial_mplock)
-       movq    PCPU(curthread),%rcx
-       movl    $1,TD_MPCOUNT(%rcx)     /* curthread has mpcount of 1 */
-       movl    $0,mp_lock              /* owned by cpu 0 */
-       NON_GPROF_RET
-
-       /*
-        * cpu_try_mplock() returns non-zero on success, 0 on failure.  It
-        * only adjusts mp_lock, it does not touch td_mpcount.  Callers
-        * should always increment td_mpcount *before* trying to acquire
-        * the actual lock, predisposing td_mpcount to the desired state of
-        * the lock.
-        *
-        * NOTE! Only call cpu_try_mplock() inside a critical section.  If
-        * you don't an interrupt can come along and get and release
-        * the lock before our cmpxchgl instruction, causing us to fail 
-        * but resulting in the lock being held by our cpu.
-        */
-NON_GPROF_ENTRY(cpu_try_mplock)
-       movl    PCPU(cpuid),%ecx
-       movl    $-1,%eax
-       lock cmpxchgl %ecx,mp_lock      /* ecx<->mem if eax matches */
-       jnz     1f
-#ifdef PARANOID_INVLTLB
-       movq    %cr3,%rax; movq %rax,%cr3       /* YYY check and remove */
-#endif
-       movl    $1,%eax
-       NON_GPROF_RET
-1:
-       subl    %eax,%eax
-       NON_GPROF_RET
-
-       /*
-        * get_mplock() Obtains the MP lock and may switch away if it cannot
-        * get it.  This routine may be called WITHOUT a critical section
-        * and with cpu interrupts enabled.
-        *
-        * To handle races in a sane fashion we predispose TD_MPCOUNT,
-        * which prevents us from losing the lock in a race if we already
-        * have it or happen to get it.  It also means that we might get
-        * the lock in an interrupt race before we have a chance to execute
-        * our cmpxchgl instruction, so we have to handle that case.
-        * Fortunately simply calling lwkt_switch() handles the situation
-        * for us and also 'blocks' us until the MP lock can be obtained.
-        */
-NON_GPROF_ENTRY(get_mplock)
-       movl    PCPU(cpuid),%ecx
-       movq    PCPU(curthread),%rdx
-       incl    TD_MPCOUNT(%rdx)        /* predispose */
-       cmpl    %ecx,mp_lock
-       jne     1f
-       NON_GPROF_RET                   /* success! */
-
-       /*
-        * We don't already own the mp_lock, use cmpxchgl to try to get
-        * it.
-        */
-1:
-       movl    $-1,%eax
-       lock cmpxchgl %ecx,mp_lock
-       jnz     2f
-#ifdef PARANOID_INVLTLB
-       movq    %cr3,%rax; movq %rax,%cr3 /* YYY check and remove */
-#endif
-       NON_GPROF_RET                   /* success */
-
-       /*
-        * Failure, but we could end up owning mp_lock anyway due to
-        * an interrupt race.  lwkt_switch() will clean up the mess
-        * and 'block' until the mp_lock is obtained.
-        *
-        * Create a stack frame for the call so KTR logs the stack
-        * backtrace properly.
-        */
-2:
-       pushq   %rbp
-       movq    %rsp,%rbp
-       call    lwkt_mp_lock_contested
-       popq    %rbp
-#ifdef INVARIANTS
-       movl    PCPU(cpuid),%eax        /* failure */
-       cmpl    %eax,mp_lock
-       jne     4f
-#endif
-       NON_GPROF_RET
-#ifdef INVARIANTS
-4:
-       cmpl    $0,panicstr             /* don't double panic */
-       je      badmp_get2
-       NON_GPROF_RET
-#endif
-
-       /*
-        * try_mplock() attempts to obtain the MP lock.  1 is returned on
-        * success, 0 on failure.  We do not have to be in a critical section
-        * and interrupts are almost certainly enabled.
-        *
-        * We must pre-dispose TD_MPCOUNT in order to deal with races in
-        * a reasonable way.
-        *
-        */
-NON_GPROF_ENTRY(try_mplock)
-       movl    PCPU(cpuid),%ecx
-       movq    PCPU(curthread),%rdx
-       incl    TD_MPCOUNT(%rdx)                /* pre-dispose for race */
-       cmpl    %ecx,mp_lock
-       je      1f                              /* trivial success */
-       movl    $-1,%eax
-       lock cmpxchgl %ecx,mp_lock
-       jnz     2f
-       /*
-        * Success
-        */
-#ifdef PARANOID_INVLTLB
-       movq    %cr3,%rax; movq %rax,%cr3       /* YYY check and remove */
-#endif
-1:
-       movl    $1,%eax                         /* success (cmpxchgl good!) */
-       NON_GPROF_RET
-
-       /*
-        * The cmpxchgl failed but we might have raced.  Undo the mess by
-        * predispoing TD_MPCOUNT and then checking.  If TD_MPCOUNT is
-        * still non-zero we don't care what state the lock is in (since
-        * we obviously didn't own it above), just return failure even if
-        * we won the lock in an interrupt race.  If TD_MPCOUNT is zero
-        * make sure we don't own the lock in case we did win it in a race.
-        */
-2:
-       decl    TD_MPCOUNT(%rdx)
-       cmpl    $0,TD_MPCOUNT(%rdx)
-       jne     3f
-       movl    PCPU(cpuid),%eax
-       movl    $-1,%ecx
-       lock cmpxchgl %ecx,mp_lock
-3:
-       subl    %eax,%eax
-       NON_GPROF_RET
-       
-       /*
-        * rel_mplock() releases a previously obtained MP lock.
-        *
-        * In order to release the MP lock we pre-dispose TD_MPCOUNT for
-        * the release and basically repeat the release portion of try_mplock
-        * above.
-        */
-NON_GPROF_ENTRY(rel_mplock)
-       movq    PCPU(curthread),%rdx
-       movl    TD_MPCOUNT(%rdx),%eax
-#ifdef INVARIANTS
-       cmpl    $0,%eax
-       je      badmp_rel
-#endif
-       subl    $1,%eax
-       movl    %eax,TD_MPCOUNT(%rdx)
-       cmpl    $0,%eax
-       jne     3f
-       movl    PCPU(cpuid),%eax
-       movl    $-1,%ecx
-       lock cmpxchgl %ecx,mp_lock
-       movl    mp_lock_contention_mask,%eax
-       cmpl    $0,%eax
-       je      3f
-       call    lwkt_mp_lock_uncontested
-3:
-       NON_GPROF_RET
-
-#ifdef INVARIANTS
-
-badmp_get:
-       movq    $bmpsw1,%rdi
-       movl    $0,%eax
-       call    panic
-badmp_get2:
-       movq    $bmpsw1a,%rdi
-       movl    $0,%eax
-       call    panic
-badmp_rel:
-       movq    $bmpsw2,%rdi
-       movl    $0,%eax
-       call    panic
-
-       .data
-
-bmpsw1:
-       .asciz  "try/get_mplock(): already have lock! %d %p"
-
-bmpsw1a:
-       .asciz  "try/get_mplock(): failed on count or switch %d %p"
-
-bmpsw2:
-       .asciz  "rel_mplock(): mpcount already 0 @ %p %p %p %p %p %p %p %p!"
-
-#endif
-
index a5d422d..2770065 100644 (file)
@@ -51,7 +51,9 @@
 #include <sys/syslog.h>
 #endif
 #include <sys/signalvar.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #ifndef SMP
 #include <machine/asmacros.h>
index d4da1de..1ad9f1d 100644 (file)
@@ -81,7 +81,9 @@
 #include <machine_base/isa/intr_machdep.h>
 
 #include <ddb/ddb.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #ifdef SMP
 
index 8165d8d..278d06d 100644 (file)
@@ -72,6 +72,7 @@
 #include <vm/vm_extern.h>
 
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <bus/isa/isa.h>
 
index ccc0d21..b639ce6 100644 (file)
@@ -35,7 +35,6 @@ cpu/i386/misc/atomic.c                standard                                \
 platform/vkernel/i386/autoconf.c       standard
 platform/vkernel/i386/mp.c             optional        smp             \
        compile-with    "${CC} -c -pthread ${CFLAGS} ${WERROR} -I/usr/include ${.IMPSRC}"
-platform/vkernel/i386/mplock.s         optional        smp
 #
 # DDB XXX
 cpu/i386/misc/elf_machdep.c            standard
index 88cd367..591632b 100644 (file)
@@ -83,6 +83,7 @@
 #include <vm/vm_extern.h>
 
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <sys/user.h>
 #include <sys/exec.h>
index 8c4bdd9..743c5d5 100644 (file)
@@ -90,9 +90,6 @@ ASSYM(TD_MPCOUNT, offsetof(struct thread, td_mpcount));
 #endif
 ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
 ASSYM(TDF_RUNNING, TDF_RUNNING);
-#ifdef SMP
-ASSYM(MP_FREE_LOCK, MP_FREE_LOCK);
-#endif
 
 ASSYM(TD_SAVEFPU, offsetof(struct thread, td_mach) + offsetof(struct md_thread, mtd_savefpu));
 
index 900d442..c8fed9e 100644 (file)
@@ -46,6 +46,8 @@
 #include <vm/vm_object.h>
 #include <vm/vm_page.h>
 
+#include <sys/mplock2.h>
+
 #include <machine/cpu.h>
 #include <machine/cpufunc.h>
 #include <machine/globaldata.h>
diff --git a/sys/platform/vkernel/i386/mplock.s b/sys/platform/vkernel/i386/mplock.s
deleted file mode 100644 (file)
index 822a761..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * $FreeBSD: src/sys/i386/i386/mplock.s,v 1.29.2.2 2000/05/16 06:58:06 dillon Exp $
- * $DragonFly: src/sys/platform/vkernel/i386/mplock.s,v 1.2 2007/07/01 02:51:43 dillon Exp $
- *
- * Copyright (c) 2003,2004 The DragonFly Project.  All rights reserved.
- * 
- * This code is derived from software contributed to The DragonFly Project
- * by Matthew Dillon <dillon@backplane.com>
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- * 3. Neither the name of The DragonFly Project nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific, prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- *                             DragonFly MPLOCK operation
- *
- * Each thread has an MP lock count, td_mpcount, and there is a shared
- * global called mp_lock.  mp_lock is the physical MP lock and contains either
- * -1 or the cpuid of the cpu owning the lock.  The count is *NOT* integrated
- * into mp_lock but instead resides in each thread td_mpcount.
- *
- * When obtaining or releasing the MP lock the td_mpcount is PREDISPOSED
- * to the desired count *PRIOR* to operating on the mp_lock itself.  MP
- * lock operations can occur outside a critical section with interrupts
- * enabled with the provisio (which the routines below handle) that an
- * interrupt may come along and preempt us, racing our cmpxchgl instruction
- * to perform the operation we have requested by pre-disposing td_mpcount.
- *
- * Additionally, the LWKT threading system manages the MP lock and
- * lwkt_switch(), in particular, may be called after pre-disposing td_mpcount
- * to handle 'blocking' on the MP lock.
- *
- *
- * Recoded from the FreeBSD original:
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@FreeBSD.org> wrote this file.  As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- */
-
-#include <machine/asmacros.h>
-#if 0
-#include <machine_base/apic/apicreg.h>
-#endif
-
-#include "assym.s"
-
-/*
- * YYY Debugging only.  Define this to be paranoid about invalidating the
- * TLB when we get giant.
- */
-#undef PARANOID_INVLTLB
-
-       .data
-       ALIGN_DATA
-#ifdef SMP
-       .globl  mp_lock
-mp_lock:
-       .long   -1                      /* initialized to not held */
-#endif
-
-       .text
-       SUPERALIGN_TEXT
-
-       /*
-        * Note on cmpxchgl... exchanges ecx with mem if mem matches eax.
-        * Z=1 (jz) on success.   A lock prefix is required for MP.
-        */
-NON_GPROF_ENTRY(cpu_get_initial_mplock)
-       movl    PCPU(curthread),%ecx
-       movl    $1,TD_MPCOUNT(%ecx)     /* curthread has mpcount of 1 */
-       movl    $0,mp_lock              /* owned by cpu 0 */
-       NON_GPROF_RET
-
-       /*
-        * cpu_try_mplock() returns non-zero on success, 0 on failure.  It
-        * only adjusts mp_lock, it does not touch td_mpcount.  Callers
-        * should always increment td_mpcount *before* trying to acquire
-        * the actual lock, predisposing td_mpcount to the desired state of
-        * the lock.
-        *
-        * NOTE! Only call cpu_try_mplock() inside a critical section.  If
-        * you don't an interrupt can come along and get and release
-        * the lock before our cmpxchgl instruction, causing us to fail 
-        * but resulting in the lock being held by our cpu.
-        */
-NON_GPROF_ENTRY(cpu_try_mplock)
-       movl    PCPU(cpuid),%ecx
-       movl    $-1,%eax
-       lock cmpxchgl %ecx,mp_lock      /* ecx<->mem if eax matches */
-       jnz     1f
-#ifdef PARANOID_INVLTLB
-       movl    %cr3,%eax; movl %eax,%cr3       /* YYY check and remove */
-#endif
-       movl    $1,%eax
-       NON_GPROF_RET
-1:
-       subl    %eax,%eax
-       NON_GPROF_RET
-
-       /*
-        * get_mplock() Obtains the MP lock and may switch away if it cannot
-        * get it.  This routine may be called WITHOUT a critical section
-        * and with cpu interrupts enabled.
-        *
-        * To handle races in a sane fashion we predispose TD_MPCOUNT,
-        * which prevents us from losing the lock in a race if we already
-        * have it or happen to get it.  It also means that we might get
-        * the lock in an interrupt race before we have a chance to execute
-        * our cmpxchgl instruction, so we have to handle that case.
-        * Fortunately simply calling lwkt_switch() handles the situation
-        * for us and also 'blocks' us until the MP lock can be obtained.
-        */
-NON_GPROF_ENTRY(get_mplock)
-       movl    PCPU(cpuid),%ecx
-       movl    PCPU(curthread),%edx
-       incl    TD_MPCOUNT(%edx)        /* predispose */
-       cmpl    %ecx,mp_lock
-       jne     1f
-       NON_GPROF_RET                   /* success! */
-
-       /*
-        * We don't already own the mp_lock, use cmpxchgl to try to get
-        * it.
-        */
-1:
-       movl    $-1,%eax
-       lock cmpxchgl %ecx,mp_lock
-       jnz     2f
-       NON_GPROF_RET                   /* success */
-
-       /*
-        * Failure, but we could end up owning mp_lock anyway due to
-        * an interrupt race.  lwkt_switch() will clean up the mess
-        * and 'block' until the mp_lock is obtained.
-        *
-        * Create a stack frame for the call so KTR logs the stack
-        * backtrace properly.
-        */
-2:
-       pushl   %ebp
-       movl    %esp,%ebp
-       call    lwkt_mp_lock_contested
-       popl    %ebp
-#ifdef INVARIANTS
-       movl    PCPU(cpuid),%eax        /* failure */
-       cmpl    %eax,mp_lock
-       jne     4f
-#endif
-       NON_GPROF_RET
-#ifdef INVARIANTS
-4:
-       cmpl    $0,panicstr             /* don't double panic */
-       je      badmp_get2
-       NON_GPROF_RET
-#endif
-
-       /*
-        * try_mplock() attempts to obtain the MP lock.  1 is returned on
-        * success, 0 on failure.  We do not have to be in a critical section
-        * and interrupts are almost certainly enabled.
-        *
-        * We must pre-dispose TD_MPCOUNT in order to deal with races in
-        * a reasonable way.
-        *
-        */
-NON_GPROF_ENTRY(try_mplock)
-       movl    PCPU(cpuid),%ecx
-       movl    PCPU(curthread),%edx
-       incl    TD_MPCOUNT(%edx)                /* pre-dispose for race */
-       cmpl    %ecx,mp_lock
-       je      1f                              /* trivial success */
-       movl    $-1,%eax
-       lock cmpxchgl %ecx,mp_lock
-       jnz     2f
-       /*
-        * Success
-        */
-#ifdef PARANOID_INVLTLB
-       movl    %cr3,%eax; movl %eax,%cr3       /* YYY check and remove */
-#endif
-1:
-       movl    $1,%eax                         /* success (cmpxchgl good!) */
-       NON_GPROF_RET
-
-       /*
-        * The cmpxchgl failed but we might have raced.  Undo the mess by
-        * predispoing TD_MPCOUNT and then checking.  If TD_MPCOUNT is
-        * still non-zero we don't care what state the lock is in (since
-        * we obviously didn't own it above), just return failure even if
-        * we won the lock in an interrupt race.  If TD_MPCOUNT is zero
-        * make sure we don't own the lock in case we did win it in a race.
-        */
-2:
-       decl    TD_MPCOUNT(%edx)
-       cmpl    $0,TD_MPCOUNT(%edx)
-       jne     3f
-       movl    PCPU(cpuid),%eax
-       movl    $-1,%ecx
-       lock cmpxchgl %ecx,mp_lock
-3:
-       subl    %eax,%eax
-       NON_GPROF_RET
-       
-       /*
-        * rel_mplock() releases a previously obtained MP lock.
-        *
-        * In order to release the MP lock we pre-dispose TD_MPCOUNT for
-        * the release and basically repeat the release portion of try_mplock
-        * above.
-        */
-NON_GPROF_ENTRY(rel_mplock)
-       movl    PCPU(curthread),%edx
-       movl    TD_MPCOUNT(%edx),%eax
-#ifdef INVARIANTS
-       cmpl    $0,%eax
-       je      badmp_rel
-#endif
-       subl    $1,%eax
-       movl    %eax,TD_MPCOUNT(%edx)
-       cmpl    $0,%eax
-       jne     3f
-       movl    PCPU(cpuid),%eax
-       movl    $-1,%ecx
-       lock cmpxchgl %ecx,mp_lock
-       movl    mp_lock_contention_mask,%eax
-       cmpl    $0,%eax
-       je      3f
-       call    lwkt_mp_lock_uncontested
-3:
-       NON_GPROF_RET
-
-#ifdef INVARIANTS
-
-badmp_get:
-       pushl   $bmpsw1
-       call    panic
-badmp_get2:
-       pushl   $bmpsw1a
-       call    panic
-badmp_rel:
-       pushl   $bmpsw2
-       call    panic
-
-       .data
-
-bmpsw1:
-       .asciz  "try/get_mplock(): already have lock! %d %p"
-
-bmpsw1a:
-       .asciz  "try/get_mplock(): failed on count or switch %d %p"
-
-bmpsw2:
-       .asciz  "rel_mplock(): mpcount already 0 @ %p %p %p %p %p %p %p %p!"
-
-#endif
-
index b20276f..2f14267 100644 (file)
@@ -54,7 +54,9 @@
 #include <sys/syslog.h>
 #endif
 #include <sys/signalvar.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #ifndef SMP
 #include <machine/asmacros.h>
index 9333e6a..664adc3 100644 (file)
 #include <machine/vm86.h>
 
 #include <ddb/ddb.h>
+
 #include <sys/msgport2.h>
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #ifdef SMP
 
index ecf9b5b..266c765 100644 (file)
@@ -76,7 +76,9 @@
 #include <vm/vm_extern.h>
 
 #include <sys/user.h>
+
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 #include <bus/isa/isa.h>
 
index ad420a6..20131d7 100644 (file)
 #include <machine/psl.h>
 #endif
 
-/*
- * MP_FREE_LOCK is used by both assembly and C under SMP.
- */
-#ifdef SMP
-#define MP_FREE_LOCK           0xffffffff      /* value of lock when free */
-#endif
-
 #ifndef LOCORE
 
-#if defined(_KERNEL) || defined(_UTHREAD)
-
-/*
- * MP LOCK functions for SMP and UP.  Under UP the MP lock does not exist
- * but we leave a few functions intact as macros for convenience.
- */
-#ifdef SMP
-
-void   get_mplock(void);
-int    try_mplock(void);
-void   rel_mplock(void);
-int    cpu_try_mplock(void);
-void   cpu_get_initial_mplock(void);
-
-extern u_int   mp_lock;
-
-#define MP_LOCK_HELD()   (mp_lock == mycpu->gd_cpuid)
-#define ASSERT_MP_LOCK_HELD(td)   KASSERT(MP_LOCK_HELD(), ("MP_LOCK_HELD(): not held thread %p", td))
-
-static __inline void
-cpu_rel_mplock(void)
-{
-       mp_lock = MP_FREE_LOCK;
-}
-
-static __inline int
-owner_mplock(void)
-{
-       return (mp_lock);
-}
-
-#else
-
-#define get_mplock()
-#define try_mplock()   1
-#define rel_mplock()
-#define owner_mplock() 0       /* always cpu 0 */
-#define MP_LOCK_HELD() (!0)
-#define ASSERT_MP_LOCK_HELD(td)
-
-#endif /* SMP */
-#endif  /* _KERNEL || _UTHREAD */
 #endif /* LOCORE */
 #endif /* !_MACHINE_LOCK_H_ */
index 92f6797..2523dd1 100644 (file)
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/uio.h>
-#include <sys/thread2.h>
 #include <sys/bus_dma.h>
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
 #include <sys/lock.h>
+
+#include <sys/thread2.h>
 #include <sys/spinlock2.h>
+#include <sys/mplock2.h>
 
 #include <vm/vm.h>
 #include <vm/vm_page.h>
index 904e240..9231995 100644 (file)
@@ -44,6 +44,8 @@
 #include <sys/stat.h>
 #include <sys/mman.h>
 
+#include <sys/mplock2.h>
+
 /*
  * A bcopy that works dring low level boot, before FP is working
  */
diff --git a/sys/sys/mplock2.h b/sys/sys/mplock2.h
new file mode 100644 (file)
index 0000000..1ea688a
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * SYS/MPLOCK2.H
+ *
+ * Implement the MP lock.  Note that debug operations
+ */
+#ifndef _SYS_MPLOCK2_H_
+#define _SYS_MPLOCK2_H_
+
+#ifndef _MACHINE_ATOMIC_H_
+#include <machine/atomic.h>
+#endif
+#ifndef _SYS_THREAD_H_
+#include <sys/thread.h>
+#endif
+#ifndef _SYS_GLOBALDATA_H_
+#include <sys/globaldata.h>
+#endif
+
+#ifdef SMP
+
+#define get_mplock()           get_mplock_debug(__FILE__, __LINE__)
+#define try_mplock()           try_mplock_debug(__FILE__, __LINE__)
+#define cpu_try_mplock()       cpu_try_mplock_debug(__FILE__, __LINE__)
+
+void _get_mplock_contested(const char *file, int line);
+void _try_mplock_contested(const char *file, int line);
+void _cpu_try_mplock_contested(const char *file, int line);
+void _rel_mplock_contested(void);
+void cpu_get_initial_mplock(void);
+void cpu_mplock_contested(void);
+void yield_mplock(struct thread *td);
+
+extern int mp_lock;
+extern int mp_lock_contention_mask;
+extern const char *mp_lock_holder_file;
+extern int mp_lock_holder_line;
+
+/*
+ * Acquire the MP lock, block until we get it.
+ *
+ * In order to acquire the MP lock we must first pre-dispose td_mpcount
+ * for the acquisition and then get the actual lock.
+ *
+ * The contested function is called only if we do not have or are unable
+ * to acquire the actual lock.  It will not return until the lock has
+ * been acquired.
+ */
+static __inline
+void
+get_mplock_debug(const char *file, int line)
+{
+       globaldata_t gd = mycpu;
+       thread_t td = gd->gd_curthread;
+
+       ++td->td_mpcount;
+       if (mp_lock != gd->gd_cpuid) {
+               if (atomic_cmpset_int(&mp_lock, -1, gd->gd_cpuid) == 0)
+                       _get_mplock_contested(file, line);
+#ifdef INVARIANTS
+               mp_lock_holder_file = file;
+               mp_lock_holder_line = line;
+#endif
+       }
+}
+
+/*
+ * Release the MP lock
+ *
+ * In order to release the MP lock we must first pre-dispose td_mpcount
+ * for the release and then, if it is 0, release the actual lock.
+ *
+ * The contested function is called only if we are unable to release the
+ * Actual lock.  This can occur if we raced an interrupt after decrementing
+ * td_mpcount to 0 and the interrupt acquired and released the lock.
+ *
+ * The function also catches the td_mpcount underflow case because the
+ * lock will be in a released state and thus fail the subsequent release.
+ */
+static __inline
+void
+rel_mplock(void)
+{
+       globaldata_t gd = mycpu;
+       thread_t td = gd->gd_curthread;
+       int n;
+
+       n = --td->td_mpcount;
+       if (n <= 0 && atomic_cmpset_int(&mp_lock, gd->gd_cpuid, -1) == 0)
+               _rel_mplock_contested();
+}
+
+/*
+ * Attempt to acquire the MP lock, returning 0 on failure and 1 on success.
+ *
+ * The contested function is called on failure and typically serves simply
+ * to log the attempt (if debugging enabled).
+ */
+static __inline
+int
+try_mplock_debug(const char *file, int line)
+{
+       globaldata_t gd = mycpu;
+       thread_t td = gd->gd_curthread;
+
+       ++td->td_mpcount;
+       if (mp_lock != gd->gd_cpuid &&
+           atomic_cmpset_int(&mp_lock, -1, gd->gd_cpuid) == 0) {
+               _try_mplock_contested(file, line);
+               return(0);
+       }
+#ifdef INVARIANTS
+       mp_lock_holder_file = file;
+       mp_lock_holder_line = line;
+#endif
+       return(1);
+}
+
+/*
+ * Low level acquisition of the MP lock ignoring curthred->td_mpcount
+ *
+ * This version of try_mplock() is used when the caller has already
+ * predisposed td->td_mpcount.
+ *
+ * Returns non-zero on success, 0 on failure.
+ *
+ * WARNING: Must be called from within a critical section if td_mpcount is
+ *         zero, otherwise an itnerrupt race can cause the lock to be lost.
+ */
+static __inline
+int
+cpu_try_mplock_debug(const char *file, int line)
+{
+       globaldata_t gd = mycpu;
+
+       if (mp_lock != gd->gd_cpuid &&
+           atomic_cmpset_int(&mp_lock, -1, gd->gd_cpuid) == 0) {
+               _cpu_try_mplock_contested(file, line);
+               return(0);
+       }
+#ifdef INVARIANTS
+       mp_lock_holder_file = file;
+       mp_lock_holder_line = line;
+#endif
+       return(1);
+}
+
+/*
+ * A cpu wanted the MP lock but could not get it.  This function is also
+ * called directly from the LWKT scheduler.
+ *
+ * Reentrant, may be called even if the cpu is already contending the MP
+ * lock.
+ */
+static __inline
+void
+set_mplock_contention_mask(globaldata_t gd)
+{
+       atomic_set_int(&mp_lock_contention_mask, gd->gd_cpumask);
+}
+
+/*
+ * A cpu is no longer contending for the MP lock after previously contending
+ * for it.
+ *
+ * Reentrant, may be called even if the cpu was not previously contending
+ * the MP lock.
+ */
+static __inline
+void
+clr_mplock_contention_mask(globaldata_t gd)
+{
+       atomic_clear_int(&mp_lock_contention_mask, gd->gd_cpumask);
+}
+
+static __inline
+int
+owner_mplock(void)
+{
+       return (mp_lock);
+}
+
+/*
+ * Low level release of the MP lock ignoring curthread->td_mpcount
+ *
+ * WARNING: Caller must be in a critical section, otherwise the
+ *         mp_lock can be lost from an interrupt race and we would
+ *         end up clearing someone else's lock.
+ */
+static __inline void
+cpu_rel_mplock(void)
+{
+       mp_lock = -1;
+}
+
+#define MP_LOCK_HELD()         \
+       (mp_lock == mycpu->gd_cpuid)
+#define ASSERT_MP_LOCK_HELD(td)        \
+       KASSERT(MP_LOCK_HELD(), ("MP_LOCK_HELD: Not held thread %p", td))
+
+#else
+
+/*
+ * UNI-PROCESSOR BUILD - Degenerate case macros
+ */
+#define        get_mplock()
+#define        rel_mplock()
+#define try_mplock()           1
+#define owner_mplock()         0
+#define MP_LOCK_HELD()         (!0)
+#define ASSERT_MP_LOCK_HELD(td)
+
+#endif
+
+#endif
index 46028d7..4b04fc4 100644 (file)
@@ -154,7 +154,6 @@ void        *phashinit (int count, struct malloc_type *type, u_long *nentries);
 
 int    cpu_sanitize_frame (struct trapframe *);
 int    cpu_sanitize_tls (struct savetls *);
-void   cpu_mplock_contested(void);
 void   cpu_spinlock_contested(void);
 void   cpu_halt (void);
 void   cpu_reset (void);
index 4aacce7..946cca7 100644 (file)
@@ -432,8 +432,6 @@ extern int  lwkt_create (void (*func)(void *), void *, struct thread **,
                         struct thread *, int, int, const char *, ...);
 extern void lwkt_exit (void) __dead2;
 extern void lwkt_remove_tdallq (struct thread *);
-extern void lwkt_mp_lock_contested(void);
-extern void lwkt_mp_lock_uncontested(void);
 
 #endif
 
index 43c83c0..e7ddd0c 100644 (file)
 #include <sys/pioctl.h>
 
 #include <machine/limits.h>
-#include <vm/vm_page2.h>
+
 #include <sys/buf2.h>
 #include <sys/sysref2.h>
+#include <sys/mplock2.h>
+#include <vm/vm_page2.h>
 
 MALLOC_DECLARE(M_DEVFS);
 #define DEVFS_BADOP    (void *)devfs_badop
index 31f0228..eedb090 100644 (file)
@@ -47,6 +47,9 @@
 #include <sys/file.h>
 #include <vm/vm_extern.h>
 #include <vfs/fifofs/fifo.h>
+
+#include <sys/mplock2.h>
+
 #include "hammer.h"
 
 /*
index 2058282..99d279d 100644 (file)
@@ -62,6 +62,7 @@
 #include <vm/vm_zone.h>
 
 #include <sys/mutex2.h>
+#include <sys/mplock2.h>
 
 #include <netinet/in.h>
 #include <netinet/tcp.h>
index d266f27..af9d97f 100644 (file)
@@ -80,6 +80,7 @@
 
 #include <sys/file2.h>
 #include <sys/thread2.h>
+#include <sys/mplock2.h>
 
 static int max_proc_mmap;
 SYSCTL_INT(_vm, OID_AUTO, max_proc_mmap, CTLFLAG_RW, &max_proc_mmap, 0, "");
index 765457f..8e73309 100644 (file)
 #include <sys/lock.h>
 #include <sys/conf.h>
 #include <sys/stat.h>
-#include <sys/thread2.h>
+
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
 #include <vm/swap_pager.h>
 #include <vm/vm_zone.h>
 
+#include <sys/thread2.h>
+#include <sys/mplock2.h>
+
 /*
  * Indirect driver for multi-controller paging.
  */
index a5658f6..b9745a1 100644 (file)
@@ -56,6 +56,8 @@
 #include <vm/pmap.h>
 #include <vm/vm_map.h>
 
+#include <sys/mplock2.h>
+
 /*
  * obreak_args(char *nsize)
  *
index 6d97b0e..49c90d9 100644 (file)
@@ -53,6 +53,7 @@
 
 #include <sys/spinlock2.h>
 #include <sys/sysref2.h>
+#include <sys/mplock2.h>
 
 static struct vmspace_entry *vkernel_find_vmspace(struct vkernel_proc *vkp,
                                                  void *id);