From 684a93c4b15cf9f678dcf209702dadcd4f670406 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sat, 19 Dec 2009 18:57:32 -0800 Subject: [PATCH] kernel - Move mplock to machine-independent C * 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. --- sys/bus/cam/cam_sim.c | 2 + sys/bus/cam/cam_xpt.c | 2 + sys/bus/cam/scsi/scsi_cd.c | 4 +- sys/bus/cam/scsi/scsi_da.c | 4 + sys/conf/files | 1 + sys/dev/disk/ahci/ahci_dragonfly.h | 1 + sys/dev/disk/nata/ata-all.c | 4 +- sys/dev/disk/nata/ata-chipset.c | 4 +- sys/dev/disk/nata/atapi-cam.c | 4 +- sys/dev/disk/sili/sili_dragonfly.h | 1 + sys/dev/raid/aac/aac.c | 2 + sys/dev/raid/aac/aac_cam.c | 2 + sys/emulation/43bsd/43bsd_file.c | 2 + sys/emulation/43bsd/43bsd_hostinfo.c | 3 + sys/emulation/43bsd/43bsd_signal.c | 2 + sys/emulation/43bsd/43bsd_socket.c | 2 + sys/emulation/43bsd/43bsd_stats.c | 2 + sys/emulation/43bsd/43bsd_vm.c | 2 + .../dragonfly12/dfbsd12_getdirentries.c | 2 + sys/emulation/dragonfly12/dfbsd12_stat.c | 2 + sys/emulation/linux/i386/linux_machdep.c | 4 +- sys/emulation/linux/i386/linux_ptrace.c | 2 + sys/emulation/linux/linux_file.c | 1 + sys/emulation/linux/linux_getcwd.c | 2 + sys/emulation/linux/linux_ioctl.c | 2 + sys/emulation/linux/linux_misc.c | 4 +- sys/emulation/linux/linux_signal.c | 3 + sys/emulation/linux/linux_socket.c | 2 + sys/emulation/linux/linux_stats.c | 4 +- sys/emulation/linux/linux_sysctl.c | 2 + sys/emulation/linux/linux_uid16.c | 2 + sys/kern/imgact_resident.c | 1 + sys/kern/init_main.c | 2 + sys/kern/kern_acct.c | 2 + sys/kern/kern_acl.c | 2 + sys/kern/kern_checkpoint.c | 5 +- sys/kern/kern_clock.c | 2 + sys/kern/kern_descrip.c | 1 + sys/kern/kern_event.c | 4 +- sys/kern/kern_exec.c | 1 + sys/kern/kern_exit.c | 1 + sys/kern/kern_fork.c | 1 + sys/kern/kern_intr.c | 4 +- sys/kern/kern_jail.c | 2 + sys/kern/kern_ktrace.c | 3 + sys/kern/kern_linker.c | 2 + sys/kern/kern_module.c | 2 + sys/kern/kern_mplock.c | 273 +++++++++++++++++ sys/kern/kern_ntptime.c | 2 + sys/kern/kern_p1003_1b.c | 2 + sys/kern/kern_proc.c | 1 + sys/kern/kern_prot.c | 1 + sys/kern/kern_resource.c | 1 + sys/kern/kern_shutdown.c | 1 + sys/kern/kern_sig.c | 4 +- sys/kern/kern_slaballoc.c | 1 + sys/kern/kern_synch.c | 5 +- sys/kern/kern_sysctl.c | 3 + sys/kern/kern_syslink.c | 1 + sys/kern/kern_time.c | 2 + sys/kern/kern_timeout.c | 2 + sys/kern/kern_umtx.c | 1 + sys/kern/kern_upcall.c | 2 + sys/kern/kern_usched.c | 3 + sys/kern/kern_uuid.c | 2 + sys/kern/kern_varsym.c | 2 + sys/kern/kern_xxx.c | 2 + sys/kern/lwkt_caps.c | 3 + sys/kern/lwkt_thread.c | 139 ++------- sys/kern/subr_bus.c | 1 + sys/kern/subr_prof.c | 2 + sys/kern/sys_generic.c | 2 + sys/kern/sys_pipe.c | 1 + sys/kern/sys_process.c | 2 + sys/kern/sys_socket.c | 2 + sys/kern/sysv_msg.c | 2 + sys/kern/sysv_sem.c | 2 + sys/kern/sysv_shm.c | 2 + sys/kern/uipc_syscalls.c | 1 + sys/kern/usched_bsd4.c | 1 + sys/kern/usched_dummy.c | 1 + sys/kern/vfs_aio.c | 2 + sys/kern/vfs_bio.c | 1 + sys/kern/vfs_cache.c | 1 + sys/kern/vfs_syscalls.c | 1 + sys/kern/vfs_vnops.c | 1 + sys/net/bpf.c | 1 + sys/net/if_ethersubr.c | 2 + sys/net/if_loop.c | 2 + sys/net/ipfw/ip_fw2.c | 6 +- sys/net/netisr.c | 1 + sys/net/pfil.c | 1 + sys/net/tap/if_tap.c | 4 +- sys/net/tun/if_tun.c | 2 + sys/netinet/if_ether.c | 1 + sys/netinet/ip_divert.c | 4 +- sys/netinet/ip_input.c | 2 + sys/netinet/ip_output.c | 4 +- sys/netinet/tcp_subr.c | 3 +- sys/netproto/ncp/ncp_mod.c | 2 + sys/opencrypto/cryptodev.c | 2 + sys/platform/pc32/conf/files | 1 - sys/platform/pc32/i386/busdma_machdep.c | 4 +- sys/platform/pc32/i386/genassym.c | 3 - sys/platform/pc32/i386/machdep.c | 1 + sys/platform/pc32/i386/mp_machdep.c | 2 + sys/platform/pc32/i386/mplock.s | 282 ----------------- sys/platform/pc32/i386/sys_machdep.c | 2 + sys/platform/pc32/i386/trap.c | 2 + sys/platform/pc32/i386/vm86.c | 2 + sys/platform/pc32/i386/vm_machdep.c | 2 + sys/platform/pc32/include/lock.h | 49 --- sys/platform/pc32/isa/npx.c | 2 + sys/platform/pc64/conf/files | 1 - sys/platform/pc64/include/lock.h | 49 --- sys/platform/pc64/isa/npx.c | 2 + sys/platform/pc64/x86_64/busdma_machdep.c | 4 +- sys/platform/pc64/x86_64/machdep.c | 1 + sys/platform/pc64/x86_64/mp_machdep.c | 2 + sys/platform/pc64/x86_64/mplock.s | 285 ------------------ sys/platform/pc64/x86_64/npx.c | 2 + sys/platform/pc64/x86_64/trap.c | 2 + sys/platform/pc64/x86_64/vm_machdep.c | 1 + sys/platform/vkernel/conf/files | 1 - sys/platform/vkernel/i386/cpu_regs.c | 1 + sys/platform/vkernel/i386/genassym.c | 3 - sys/platform/vkernel/i386/mp.c | 2 + sys/platform/vkernel/i386/mplock.s | 281 ----------------- sys/platform/vkernel/i386/npx.c | 2 + sys/platform/vkernel/i386/trap.c | 2 + sys/platform/vkernel/i386/vm_machdep.c | 2 + sys/platform/vkernel/include/lock.h | 49 --- .../vkernel/platform/busdma_machdep.c | 4 +- sys/platform/vkernel/platform/copyio.c | 2 + sys/sys/mplock2.h | 214 +++++++++++++ sys/sys/systm.h | 1 - sys/sys/thread.h | 2 - sys/vfs/devfs/devfs_vnops.c | 4 +- sys/vfs/hammer/hammer_vnops.c | 3 + sys/vfs/nfs/nfs_syscalls.c | 1 + sys/vm/vm_mmap.c | 1 + sys/vm/vm_swap.c | 5 +- sys/vm/vm_unix.c | 2 + sys/vm/vm_vmspace.c | 1 + 144 files changed, 758 insertions(+), 1152 deletions(-) create mode 100644 sys/kern/kern_mplock.c delete mode 100644 sys/platform/pc32/i386/mplock.s delete mode 100644 sys/platform/pc64/x86_64/mplock.s delete mode 100644 sys/platform/vkernel/i386/mplock.s create mode 100644 sys/sys/mplock2.h diff --git a/sys/bus/cam/cam_sim.c b/sys/bus/cam/cam_sim.c index be18d29182..05754c60a4 100644 --- a/sys/bus/cam/cam_sim.c +++ b/sys/bus/cam/cam_sim.c @@ -35,8 +35,10 @@ #include #include #include + #include #include +#include #include "cam.h" #include "cam_ccb.h" diff --git a/sys/bus/cam/cam_xpt.c b/sys/bus/cam/cam_xpt.c index c63b60891b..7e0ab1c182 100644 --- a/sys/bus/cam/cam_xpt.c +++ b/sys/bus/cam/cam_xpt.c @@ -47,8 +47,10 @@ #include #include #include + #include #include +#include #include #include diff --git a/sys/bus/cam/scsi/scsi_cd.c b/sys/bus/cam/scsi/scsi_cd.c index bf68bb037f..81b541a86a 100644 --- a/sys/bus/cam/scsi/scsi_cd.c +++ b/sys/bus/cam/scsi/scsi_cd.c @@ -65,9 +65,11 @@ #include #include #include -#include #include + +#include #include +#include #include "../cam.h" #include "../cam_ccb.h" diff --git a/sys/bus/cam/scsi/scsi_da.c b/sys/bus/cam/scsi/scsi_da.c index 2f92554bb3..b0154b46e6 100644 --- a/sys/bus/cam/scsi/scsi_da.c +++ b/sys/bus/cam/scsi/scsi_da.c @@ -33,6 +33,7 @@ #include #ifdef _KERNEL + #include #include #include @@ -47,8 +48,11 @@ #include #include #include + #include #include +#include + #endif /* _KERNEL */ #ifdef _KERNEL diff --git a/sys/conf/files b/sys/conf/files index 8283663887..caae1ec9d0 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -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 diff --git a/sys/dev/disk/ahci/ahci_dragonfly.h b/sys/dev/disk/ahci/ahci_dragonfly.h index ec2be679d1..8545d56edd 100644 --- a/sys/dev/disk/ahci/ahci_dragonfly.h +++ b/sys/dev/disk/ahci/ahci_dragonfly.h @@ -68,6 +68,7 @@ #include #include +#include #define AHCI_CDEV_MAJOR 188 diff --git a/sys/dev/disk/nata/ata-all.c b/sys/dev/disk/nata/ata-all.c index 8c7d3fb713..ce3dacfa89 100644 --- a/sys/dev/disk/nata/ata-all.c +++ b/sys/dev/disk/nata/ata-all.c @@ -44,10 +44,12 @@ #include #include #include -#include #include #include +#include +#include + #include "ata-all.h" #include "ata_if.h" diff --git a/sys/dev/disk/nata/ata-chipset.c b/sys/dev/disk/nata/ata-chipset.c index be764eaed4..e775db6e21 100644 --- a/sys/dev/disk/nata/ata-chipset.c +++ b/sys/dev/disk/nata/ata-chipset.c @@ -42,10 +42,12 @@ #include #include #include -#include #include #include +#include +#include + #include #include diff --git a/sys/dev/disk/nata/atapi-cam.c b/sys/dev/disk/nata/atapi-cam.c index afd40bc04c..54a0fc450c 100644 --- a/sys/dev/disk/nata/atapi-cam.c +++ b/sys/dev/disk/nata/atapi-cam.c @@ -40,10 +40,12 @@ #include #include #include -#include #include #include + #include +#include +#include #include #include diff --git a/sys/dev/disk/sili/sili_dragonfly.h b/sys/dev/disk/sili/sili_dragonfly.h index d29eb4cf82..30a68800a3 100644 --- a/sys/dev/disk/sili/sili_dragonfly.h +++ b/sys/dev/disk/sili/sili_dragonfly.h @@ -68,6 +68,7 @@ #include #include +#include #define SILI_CDEV_MAJOR 188 diff --git a/sys/dev/raid/aac/aac.c b/sys/dev/raid/aac/aac.c index f2c05053f0..4e4e259184 100644 --- a/sys/dev/raid/aac/aac.c +++ b/sys/dev/raid/aac/aac.c @@ -56,6 +56,8 @@ #include #include +#include + #include #include diff --git a/sys/dev/raid/aac/aac_cam.c b/sys/dev/raid/aac/aac_cam.c index 7051d04f6f..3f8b355496 100644 --- a/sys/dev/raid/aac/aac_cam.c +++ b/sys/dev/raid/aac/aac_cam.c @@ -56,6 +56,8 @@ #include +#include + #include #include diff --git a/sys/emulation/43bsd/43bsd_file.c b/sys/emulation/43bsd/43bsd_file.c index d39b3ffa9b..eb2fdf826a 100644 --- a/sys/emulation/43bsd/43bsd_file.c +++ b/sys/emulation/43bsd/43bsd_file.c @@ -63,6 +63,8 @@ #include #include +#include + #include /* diff --git a/sys/emulation/43bsd/43bsd_hostinfo.c b/sys/emulation/43bsd/43bsd_hostinfo.c index 68985c3321..8e7d17ff58 100644 --- a/sys/emulation/43bsd/43bsd_hostinfo.c +++ b/sys/emulation/43bsd/43bsd_hostinfo.c @@ -49,8 +49,11 @@ #include #include #include + #include +#include + /* * MPALMOSTSAFE */ diff --git a/sys/emulation/43bsd/43bsd_signal.c b/sys/emulation/43bsd/43bsd_signal.c index 1b41509c25..8645a0a89b 100644 --- a/sys/emulation/43bsd/43bsd_signal.c +++ b/sys/emulation/43bsd/43bsd_signal.c @@ -55,7 +55,9 @@ #include #include #include + #include +#include #define ONSIG 32 /* NSIG for osig* syscalls. XXX. */ diff --git a/sys/emulation/43bsd/43bsd_socket.c b/sys/emulation/43bsd/43bsd_socket.c index f33ba3bcc6..2554761cbb 100644 --- a/sys/emulation/43bsd/43bsd_socket.c +++ b/sys/emulation/43bsd/43bsd_socket.c @@ -54,6 +54,8 @@ #include #include +#include + #include "43bsd_socket.h" /* diff --git a/sys/emulation/43bsd/43bsd_stats.c b/sys/emulation/43bsd/43bsd_stats.c index 65bcfa2513..10b7a05689 100644 --- a/sys/emulation/43bsd/43bsd_stats.c +++ b/sys/emulation/43bsd/43bsd_stats.c @@ -57,6 +57,8 @@ #include #include +#include + #include static int diff --git a/sys/emulation/43bsd/43bsd_vm.c b/sys/emulation/43bsd/43bsd_vm.c index e9409143c8..026365b817 100644 --- a/sys/emulation/43bsd/43bsd_vm.c +++ b/sys/emulation/43bsd/43bsd_vm.c @@ -49,7 +49,9 @@ #include #include #include + #include +#include /* * MPSAFE diff --git a/sys/emulation/dragonfly12/dfbsd12_getdirentries.c b/sys/emulation/dragonfly12/dfbsd12_getdirentries.c index 4b9704eb03..e811339528 100644 --- a/sys/emulation/dragonfly12/dfbsd12_getdirentries.c +++ b/sys/emulation/dragonfly12/dfbsd12_getdirentries.c @@ -44,6 +44,8 @@ #include #include +#include + #define PADDED_SIZE(x) \ ((sizeof(struct dfbsd12_dirent) + (x) + 1 + 3) & ~3) #define MAX_NAMELEN 255 diff --git a/sys/emulation/dragonfly12/dfbsd12_stat.c b/sys/emulation/dragonfly12/dfbsd12_stat.c index 404b316e41..16ae75c730 100644 --- a/sys/emulation/dragonfly12/dfbsd12_stat.c +++ b/sys/emulation/dragonfly12/dfbsd12_stat.c @@ -49,6 +49,8 @@ #include #include +#include + static void cvtstat(struct dfbsd12_stat *oldstat, struct stat *newstat) { diff --git a/sys/emulation/linux/i386/linux_machdep.c b/sys/emulation/linux/i386/linux_machdep.c index db95b3aee0..e2edbafe0c 100644 --- a/sys/emulation/linux/i386/linux_machdep.c +++ b/sys/emulation/linux/i386/linux_machdep.c @@ -53,6 +53,8 @@ #include #include +#include + #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; diff --git a/sys/emulation/linux/i386/linux_ptrace.c b/sys/emulation/linux/i386/linux_ptrace.c index 36de90846f..319d29b56d 100644 --- a/sys/emulation/linux/i386/linux_ptrace.c +++ b/sys/emulation/linux/i386/linux_ptrace.c @@ -43,6 +43,8 @@ #include #include +#include + #include #include diff --git a/sys/emulation/linux/linux_file.c b/sys/emulation/linux/linux_file.c index c966d2fd0f..16c3edea3b 100644 --- a/sys/emulation/linux/linux_file.c +++ b/sys/emulation/linux/linux_file.c @@ -53,6 +53,7 @@ #include #include +#include #include #include diff --git a/sys/emulation/linux/linux_getcwd.c b/sys/emulation/linux/linux_getcwd.c index 276a45debb..e8ad1b8513 100644 --- a/sys/emulation/linux/linux_getcwd.c +++ b/sys/emulation/linux/linux_getcwd.c @@ -57,6 +57,8 @@ #include #include /* XXX only for DIRBLKSIZ */ +#include + #include #include #include "linux_util.h" diff --git a/sys/emulation/linux/linux_ioctl.c b/sys/emulation/linux/linux_ioctl.c index 2fdca89967..39f058c563 100644 --- a/sys/emulation/linux/linux_ioctl.c +++ b/sys/emulation/linux/linux_ioctl.c @@ -55,7 +55,9 @@ #include #include #include + #include +#include #include #include diff --git a/sys/emulation/linux/linux_misc.c b/sys/emulation/linux/linux_misc.c index cf62405ec4..dd09b7b051 100644 --- a/sys/emulation/linux/linux_misc.c +++ b/sys/emulation/linux/linux_misc.c @@ -48,7 +48,6 @@ #include #include #include -#include #include #include #include @@ -57,7 +56,10 @@ #include #include #include + +#include #include +#include #include #include diff --git a/sys/emulation/linux/linux_signal.c b/sys/emulation/linux/linux_signal.c index 56e656b1be..043ff5fc0f 100644 --- a/sys/emulation/linux/linux_signal.c +++ b/sys/emulation/linux/linux_signal.c @@ -37,7 +37,10 @@ #include #include #include + #include +#include + #include #include #include "linux_signal.h" diff --git a/sys/emulation/linux/linux_socket.c b/sys/emulation/linux/linux_socket.c index a40609b219..02733167d7 100644 --- a/sys/emulation/linux/linux_socket.c +++ b/sys/emulation/linux/linux_socket.c @@ -42,6 +42,8 @@ #include #include +#include + #include #include #include diff --git a/sys/emulation/linux/linux_stats.c b/sys/emulation/linux/linux_stats.c index 440e38d37f..0d6cf9efa4 100644 --- a/sys/emulation/linux/linux_stats.c +++ b/sys/emulation/linux/linux_stats.c @@ -44,9 +44,11 @@ #include #include #include -#include #include +#include +#include + #include #include #include "linux_util.h" diff --git a/sys/emulation/linux/linux_sysctl.c b/sys/emulation/linux/linux_sysctl.c index fc3cae44ef..66e3c4ba19 100644 --- a/sys/emulation/linux/linux_sysctl.c +++ b/sys/emulation/linux/linux_sysctl.c @@ -36,6 +36,8 @@ #include #include +#include + #include #include #include "linux_util.h" diff --git a/sys/emulation/linux/linux_uid16.c b/sys/emulation/linux/linux_uid16.c index 215ff84ed9..77664d0b26 100644 --- a/sys/emulation/linux/linux_uid16.c +++ b/sys/emulation/linux/linux_uid16.c @@ -38,6 +38,8 @@ #include #include +#include + #include #include #include "linux_util.h" diff --git a/sys/kern/imgact_resident.c b/sys/kern/imgact_resident.c index fecaa18bdf..a1c27d106e 100644 --- a/sys/kern/imgact_resident.c +++ b/sys/kern/imgact_resident.c @@ -62,6 +62,7 @@ #include #include +#include static int exec_res_id = 0; diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 3e9db5649a..a39c37caef 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -63,10 +63,12 @@ #include #include #include + #include #include #include #include +#include #include diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c index 8c124ecb14..73df0a1067 100644 --- a/sys/kern/kern_acct.c +++ b/sys/kern/kern_acct.c @@ -60,6 +60,8 @@ #include +#include + /* * The routines implemented in this file are described in: * Leffler, et al.: The Design and Implementation of the 4.3BSD diff --git a/sys/kern/kern_acl.c b/sys/kern/kern_acl.c index 37fa0274ca..57fab880ab 100644 --- a/sys/kern/kern_acl.c +++ b/sys/kern/kern_acl.c @@ -47,6 +47,8 @@ #include #include +#include + 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); diff --git a/sys/kern/kern_checkpoint.c b/sys/kern/kern_checkpoint.c index 7738d04fbc..76e51f3c8f 100644 --- a/sys/kern/kern_checkpoint.c +++ b/sys/kern/kern_checkpoint.c @@ -36,8 +36,6 @@ #include #include -/* only on dragonfly */ -#include #include #include #include @@ -73,6 +71,9 @@ #include #include +#include +#include + 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, diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 8c05ebdd85..65c737b212 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -95,7 +95,9 @@ #include #include #include + #include +#include #include #include diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 2502135c6a..19f1916ff8 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -105,6 +105,7 @@ #include #include #include +#include static void fsetfd_locked(struct filedesc *fdp, struct file *fp, int fd); static void fdreserve_locked (struct filedesc *fdp, int fd0, int incr); diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 766f8fee33..4b2f5c1543 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -48,10 +48,12 @@ #include #include #include -#include #include #include + +#include #include +#include #include diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 571adf82bd..cfc92e31f3 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -72,6 +72,7 @@ #include #include +#include MALLOC_DEFINE(M_PARGS, "proc-args", "Process arguments"); MALLOC_DEFINE(M_EXECARGS, "exec-args", "Exec arguments"); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 07930a79a3..ffcc1c22c3 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -79,6 +79,7 @@ #include #include +#include static void reaplwps(void *context, int dummy); static void reaplwp(struct lwp *lp); diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index b24aa22101..a804e8bac3 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -68,6 +68,7 @@ #include #include #include +#include static MALLOC_DEFINE(M_ATFORK, "atfork", "atfork callback"); diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index acadbe18b5..c615fade23 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -46,6 +45,9 @@ #include +#include +#include + struct info_info; typedef struct intrec { diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 6b0da590bf..2d4bd3495e 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -60,6 +60,8 @@ #include #include +#include + static struct prison *prison_find(int); static void prison_ipcache_init(struct prison *); diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index f21cdf42f8..4fc5e5119f 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -52,6 +52,9 @@ #include #include + +#include + static MALLOC_DEFINE(M_KTRACE, "KTRACE", "KTRACE"); #ifdef KTRACE diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 4225e033e7..02464c3c2c 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -49,6 +49,8 @@ #include +#include + #ifdef _KERNEL_VIRTUAL #include #endif diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c index de2c770208..7af9655bc7 100644 --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -38,6 +38,8 @@ #include #include +#include + 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 index 0000000000..14e2a5a4b4 --- /dev/null +++ b/sys/kern/kern_mplock.c @@ -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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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 */ diff --git a/sys/kern/kern_ntptime.c b/sys/kern/kern_ntptime.c index 9a8ad11084..e0685f6255 100644 --- a/sys/kern/kern_ntptime.c +++ b/sys/kern/kern_ntptime.c @@ -44,7 +44,9 @@ #include #include #include + #include +#include /* * Single-precision macros for 64-bit machines diff --git a/sys/kern/kern_p1003_1b.c b/sys/kern/kern_p1003_1b.c index bd9f191829..503b6562b9 100644 --- a/sys/kern/kern_p1003_1b.c +++ b/sys/kern/kern_p1003_1b.c @@ -48,6 +48,8 @@ #include #include +#include + MALLOC_DEFINE(M_P31B, "p1003.1b", "Posix 1003.1B"); /* p31b_proc: Return a proc struct corresponding to a pid to operate on. diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 797d51a4c5..46997aa322 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -54,6 +54,7 @@ #include #include +#include static MALLOC_DEFINE(M_PGRP, "pgrp", "process group header"); MALLOC_DEFINE(M_SESSION, "session", "session header"); diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 55a54ff2cb..a3d2bd2298 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -63,6 +63,7 @@ #include #include +#include static MALLOC_DEFINE(M_CRED, "cred", "credentials"); diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c index e6c8ce6de0..325c3d0d65 100644 --- a/sys/kern/kern_resource.c +++ b/sys/kern/kern_resource.c @@ -63,6 +63,7 @@ #include #include +#include static int donice (struct proc *chgp, int n); diff --git a/sys/kern/kern_shutdown.c b/sys/kern/kern_shutdown.c index 74a48c39b1..5054440077 100644 --- a/sys/kern/kern_shutdown.c +++ b/sys/kern/kern_shutdown.c @@ -78,6 +78,7 @@ #include #include +#include #include #include diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 60abb3fbf5..be4cfcb2fc 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include @@ -69,7 +68,10 @@ #include #include #include + +#include #include +#include #include #include diff --git a/sys/kern/kern_slaballoc.c b/sys/kern/kern_slaballoc.c index c621b95173..93cacbf5cc 100644 --- a/sys/kern/kern_slaballoc.c +++ b/sys/kern/kern_slaballoc.c @@ -116,6 +116,7 @@ #include #include +#include #define arysize(ary) (sizeof(ary)/sizeof((ary)[0])) diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index a6e813fbfb..04114e70d4 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include @@ -58,11 +57,13 @@ #endif #include #include +#include +#include #include #include #include -#include +#include #include #include diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 5b5f4524e4..cd118d6ca0 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -51,6 +51,9 @@ #include #include #include + +#include + #include #include diff --git a/sys/kern/kern_syslink.c b/sys/kern/kern_syslink.c index 869f8e0894..5fb159c2bb 100644 --- a/sys/kern/kern_syslink.c +++ b/sys/kern/kern_syslink.c @@ -68,6 +68,7 @@ #include #include #include +#include #include "opt_syslink.h" diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 386dbf1da7..2f3ec8488f 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -53,8 +53,10 @@ #include #include #include + #include #include +#include struct timezone tz; diff --git a/sys/kern/kern_timeout.c b/sys/kern/kern_timeout.c index 6351326efc..189ffb09d0 100644 --- a/sys/kern/kern_timeout.c +++ b/sys/kern/kern_timeout.c @@ -105,7 +105,9 @@ #include #include #include + #include +#include #ifndef MAX_SOFTCLOCK_STEPS #define MAX_SOFTCLOCK_STEPS 100 /* Maximum allowed value of steps. */ diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index 82b66a9d1b..132c3e353c 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -64,6 +64,7 @@ #include #include +#include static void umtx_sleep_page_action_cow(vm_page_t m, vm_page_action_t action); diff --git a/sys/kern/kern_upcall.c b/sys/kern/kern_upcall.c index d4714789f1..736c6d6ebd 100644 --- a/sys/kern/kern_upcall.c +++ b/sys/kern/kern_upcall.c @@ -50,6 +50,8 @@ #include #include +#include + #include #include #include diff --git a/sys/kern/kern_usched.c b/sys/kern/kern_usched.c index f76ff2b3f2..9ef93fefa4 100644 --- a/sys/kern/kern_usched.c +++ b/sys/kern/kern_usched.c @@ -41,6 +41,9 @@ #include /* struct usched_set_args */ #include /* strcmp() */ #include + +#include + #include static TAILQ_HEAD(, usched) usched_list = TAILQ_HEAD_INITIALIZER(usched_list); diff --git a/sys/kern/kern_uuid.c b/sys/kern/kern_uuid.c index 61b9d9adc2..a4fa8e88f7 100644 --- a/sys/kern/kern_uuid.c +++ b/sys/kern/kern_uuid.c @@ -41,6 +41,8 @@ #include #include +#include + /* * See also: * http://www.opengroup.org/dce/info/draft-leach-uuids-guids-01.txt diff --git a/sys/kern/kern_varsym.c b/sys/kern/kern_varsym.c index e90a533a22..6e0d85c2b6 100644 --- a/sys/kern/kern_varsym.c +++ b/sys/kern/kern_varsym.c @@ -53,6 +53,8 @@ #include #include +#include + MALLOC_DEFINE(M_VARSYM, "varsym", "variable sets for variant symlinks"); struct varsymset varsymset_sys; diff --git a/sys/kern/kern_xxx.c b/sys/kern/kern_xxx.c index 2b28aa421f..90f595b64f 100644 --- a/sys/kern/kern_xxx.c +++ b/sys/kern/kern_xxx.c @@ -44,6 +44,8 @@ #include #include +#include + /* * MPALMOSTSAFE */ diff --git a/sys/kern/lwkt_caps.c b/sys/kern/lwkt_caps.c index 78f2c7962f..d713224377 100644 --- a/sys/kern/lwkt_caps.c +++ b/sys/kern/lwkt_caps.c @@ -62,6 +62,9 @@ #include #include #include + +#include + #include #include diff --git a/sys/kern/lwkt_thread.c b/sys/kern/lwkt_thread.c index 5111082fcb..b21100e338 100644 --- a/sys/kern/lwkt_thread.c +++ b/sys/kern/lwkt_thread.c @@ -55,6 +55,7 @@ #include #include +#include #include #include @@ -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,23 +137,8 @@ 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 diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 0059dcdafd..2592977251 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -52,6 +52,7 @@ #include /* for device_printf() */ #include +#include SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL); diff --git a/sys/kern/subr_prof.c b/sys/kern/subr_prof.c index 25becac1ea..8f46cf6aa4 100644 --- a/sys/kern/subr_prof.c +++ b/sys/kern/subr_prof.c @@ -42,7 +42,9 @@ #include #include #include + #include +#include #include diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 2463f5f672..8078bc6e7f 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -68,7 +68,9 @@ #endif #include #include + #include +#include #include diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index 88619c9645..9203d13f51 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -63,6 +63,7 @@ #include #include +#include #include diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 8267ead558..84cd8a3689 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -49,7 +49,9 @@ #include #include + #include +#include /* use the equivalent procfs code */ #if 0 diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c index 835f007b9b..6ce1948d18 100644 --- a/sys/kern/sys_socket.c +++ b/sys/kern/sys_socket.c @@ -51,6 +51,8 @@ #include #include +#include + #include #include diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c index 0aff652dd1..a53974bfb8 100644 --- a/sys/kern/sysv_msg.c +++ b/sys/kern/sysv_msg.c @@ -34,6 +34,8 @@ #include #include +#include + static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues"); static void msginit (void *); diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index fd800eeacc..ee0ae08b9f 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -22,6 +22,8 @@ #include #include +#include + static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores"); static void seminit (void *); diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 4a6eb45663..b29ae5dfaa 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -48,6 +48,8 @@ #include #include +#include + #include #include #include diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 0c4b5ab8d0..5aaa424e78 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -79,6 +79,7 @@ #include #include #include +#include #include #ifdef SCTP diff --git a/sys/kern/usched_bsd4.c b/sys/kern/usched_bsd4.c index f021acfc7a..8737423ccd 100644 --- a/sys/kern/usched_bsd4.c +++ b/sys/kern/usched_bsd4.c @@ -42,6 +42,7 @@ #include #include +#include /* * Priorities. Note that with 32 run queues per scheduler each queue diff --git a/sys/kern/usched_dummy.c b/sys/kern/usched_dummy.c index bd2d205a6e..aff357e1ca 100644 --- a/sys/kern/usched_dummy.c +++ b/sys/kern/usched_dummy.c @@ -50,6 +50,7 @@ #include #include +#include #define MAXPRI 128 #define PRIBASE_REALTIME 0 diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index ecb3e0e910..2e9dcc281d 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -47,10 +47,12 @@ #include #include #include + #include #include #include #include +#include #include #include "opt_vfs_aio.h" diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index cdf7d68e7e..5b6a55d99d 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include "opt_ddb.h" diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index 55984d62fc..8367997598 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -89,6 +89,7 @@ #include #include +#include #define MAX_RECURSION_DEPTH 64 diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 6f4616c9ac..0a517187bb 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -72,6 +72,7 @@ #include #include #include +#include #include #include diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index ee44f496ee..2e17d00b4f 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -58,6 +58,7 @@ #include #include +#include static int vn_closefile (struct file *fp); static int vn_ioctl (struct file *fp, u_long com, caddr_t data, diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 2924a282b7..cb795b7236 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -63,6 +63,7 @@ #include #include +#include #include #include diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index c26e452b31..2b736bc715 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -57,7 +57,9 @@ #include #include #include + #include +#include #include #include diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index ddba6ef675..ede54c8975 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -53,6 +53,8 @@ #include #include +#include + #include #include #include diff --git a/sys/net/ipfw/ip_fw2.c b/sys/net/ipfw/ip_fw2.c index 6210748d74..20bf240707 100644 --- a/sys/net/ipfw/ip_fw2.c +++ b/sys/net/ipfw/ip_fw2.c @@ -46,17 +46,19 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include +#include +#include +#include + #include #include #include diff --git a/sys/net/netisr.c b/sys/net/netisr.c index 2a3d620bf2..209aedec49 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -56,6 +56,7 @@ #include #include #include +#include #define NETISR_GET_MPLOCK(ni) \ do { \ diff --git a/sys/net/pfil.c b/sys/net/pfil.c index 6278664c1a..4dbc9c0e76 100644 --- a/sys/net/pfil.c +++ b/sys/net/pfil.c @@ -41,6 +41,7 @@ #include #include #include +#include #define PFIL_CFGPORT cpu_portfn(0) diff --git a/sys/net/tap/if_tap.c b/sys/net/tap/if_tap.c index 7d2e160745..2010b01cb5 100644 --- a/sys/net/tap/if_tap.c +++ b/sys/net/tap/if_tap.c @@ -54,12 +54,14 @@ #include #include #include -#include #include #include #include #include +#include +#include + #include #include #include diff --git a/sys/net/tun/if_tun.c b/sys/net/tun/if_tun.c index 91d55c0efe..7a06e71cee 100644 --- a/sys/net/tun/if_tun.c +++ b/sys/net/tun/if_tun.c @@ -44,6 +44,8 @@ #include #include +#include + #include #include #include diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 5667b9b6cb..11b86f6ad2 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -101,6 +101,7 @@ #include #include #include +#include #ifdef CARP #include diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 5de76347d0..02d1bfd007 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -56,7 +56,6 @@ #include #include #include -#include #include #include #ifdef SMP @@ -67,9 +66,12 @@ #include #include + #ifdef SMP #include #endif +#include +#include #include #include diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index fe74292845..226361401d 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -95,6 +95,8 @@ #include #include +#include + #include #include diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index ab53a0f73c..c6d7995b41 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -52,10 +52,12 @@ #include #include #include -#include #include #include +#include +#include + #include #include #include diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 942b0eebe4..99f96c070c 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -142,9 +142,10 @@ #endif #include -#include #include +#include +#include #include #if !defined(KTR_TCP) diff --git a/sys/netproto/ncp/ncp_mod.c b/sys/netproto/ncp/ncp_mod.c index f36a45bdcb..f702ed61b7 100644 --- a/sys/netproto/ncp/ncp_mod.c +++ b/sys/netproto/ncp/ncp_mod.c @@ -43,6 +43,8 @@ #include #include +#include + #include "ncp.h" #include "ncp_conn.h" #include "ncp_subr.h" diff --git a/sys/opencrypto/cryptodev.c b/sys/opencrypto/cryptodev.c index 401c9100ce..8ce8655d7f 100644 --- a/sys/opencrypto/cryptodev.c +++ b/sys/opencrypto/cryptodev.c @@ -50,8 +50,10 @@ #include #include #include + #include #include +#include #include #include diff --git a/sys/platform/pc32/conf/files b/sys/platform/pc32/conf/files index 1d5a9d8a72..f775a915f3 100644 --- a/sys/platform/pc32/conf/files +++ b/sys/platform/pc32/conf/files @@ -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 diff --git a/sys/platform/pc32/i386/busdma_machdep.c b/sys/platform/pc32/i386/busdma_machdep.c index 0ee2246334..b880bf7a02 100644 --- a/sys/platform/pc32/i386/busdma_machdep.c +++ b/sys/platform/pc32/i386/busdma_machdep.c @@ -32,12 +32,14 @@ #include #include #include -#include #include #include #include #include + +#include #include +#include #include #include diff --git a/sys/platform/pc32/i386/genassym.c b/sys/platform/pc32/i386/genassym.c index aa826df5a7..0980eae34c 100644 --- a/sys/platform/pc32/i386/genassym.c +++ b/sys/platform/pc32/i386/genassym.c @@ -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)); diff --git a/sys/platform/pc32/i386/machdep.c b/sys/platform/pc32/i386/machdep.c index 95815a317c..0903ec8ee2 100644 --- a/sys/platform/pc32/i386/machdep.c +++ b/sys/platform/pc32/i386/machdep.c @@ -88,6 +88,7 @@ #include #include +#include #include #include diff --git a/sys/platform/pc32/i386/mp_machdep.c b/sys/platform/pc32/i386/mp_machdep.c index dc3dfcaf36..b853258ca0 100644 --- a/sys/platform/pc32/i386/mp_machdep.c +++ b/sys/platform/pc32/i386/mp_machdep.c @@ -49,6 +49,8 @@ #include #endif +#include + #include #include #include diff --git a/sys/platform/pc32/i386/mplock.s b/sys/platform/pc32/i386/mplock.s deleted file mode 100644 index 45f1dc1ef0..0000000000 --- a/sys/platform/pc32/i386/mplock.s +++ /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 - * - * 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): - * 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 -#include - -#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 - diff --git a/sys/platform/pc32/i386/sys_machdep.c b/sys/platform/pc32/i386/sys_machdep.c index 9c7459fbb9..c9d4988afe 100644 --- a/sys/platform/pc32/i386/sys_machdep.c +++ b/sys/platform/pc32/i386/sys_machdep.c @@ -61,7 +61,9 @@ #include /* mdcpu */ #include /* for kernel_map */ + #include +#include #define MAX_LD 8192 #define LD_PER_PAGE 512 diff --git a/sys/platform/pc32/i386/trap.c b/sys/platform/pc32/i386/trap.c index 9eec21f8bd..e7f8758843 100644 --- a/sys/platform/pc32/i386/trap.c +++ b/sys/platform/pc32/i386/trap.c @@ -102,8 +102,10 @@ #include #include + #include #include +#include #ifdef SMP diff --git a/sys/platform/pc32/i386/vm86.c b/sys/platform/pc32/i386/vm86.c index 1d88690e88..b393fa3609 100644 --- a/sys/platform/pc32/i386/vm86.c +++ b/sys/platform/pc32/i386/vm86.c @@ -43,7 +43,9 @@ #include #include + #include +#include #include #include /* pcb.h included via sys/user.h */ diff --git a/sys/platform/pc32/i386/vm_machdep.c b/sys/platform/pc32/i386/vm_machdep.c index 14890030fa..a59a2a0ded 100644 --- a/sys/platform/pc32/i386/vm_machdep.c +++ b/sys/platform/pc32/i386/vm_machdep.c @@ -77,7 +77,9 @@ #include #include + #include +#include #include diff --git a/sys/platform/pc32/include/lock.h b/sys/platform/pc32/include/lock.h index 8d2bab3a4b..48346e28b0 100644 --- a/sys/platform/pc32/include/lock.h +++ b/sys/platform/pc32/include/lock.h @@ -42,13 +42,6 @@ #include #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_ */ diff --git a/sys/platform/pc32/isa/npx.c b/sys/platform/pc32/isa/npx.c index 5509800670..15163155b1 100644 --- a/sys/platform/pc32/isa/npx.c +++ b/sys/platform/pc32/isa/npx.c @@ -53,7 +53,9 @@ #include #endif #include + #include +#include #ifndef SMP #include diff --git a/sys/platform/pc64/conf/files b/sys/platform/pc64/conf/files index b92879c58c..4c39be3d97 100644 --- a/sys/platform/pc64/conf/files +++ b/sys/platform/pc64/conf/files @@ -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 diff --git a/sys/platform/pc64/include/lock.h b/sys/platform/pc64/include/lock.h index ce80365438..a6ccdfd532 100644 --- a/sys/platform/pc64/include/lock.h +++ b/sys/platform/pc64/include/lock.h @@ -42,13 +42,6 @@ #include #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_ */ diff --git a/sys/platform/pc64/isa/npx.c b/sys/platform/pc64/isa/npx.c index df35c5c60c..58a085bb2b 100644 --- a/sys/platform/pc64/isa/npx.c +++ b/sys/platform/pc64/isa/npx.c @@ -54,7 +54,9 @@ #include #endif #include + #include +#include #ifndef SMP #include diff --git a/sys/platform/pc64/x86_64/busdma_machdep.c b/sys/platform/pc64/x86_64/busdma_machdep.c index 0ee2246334..b880bf7a02 100644 --- a/sys/platform/pc64/x86_64/busdma_machdep.c +++ b/sys/platform/pc64/x86_64/busdma_machdep.c @@ -32,12 +32,14 @@ #include #include #include -#include #include #include #include #include + +#include #include +#include #include #include diff --git a/sys/platform/pc64/x86_64/machdep.c b/sys/platform/pc64/x86_64/machdep.c index fbad5daf4a..0c72a7a4fe 100644 --- a/sys/platform/pc64/x86_64/machdep.c +++ b/sys/platform/pc64/x86_64/machdep.c @@ -85,6 +85,7 @@ #include #include +#include #include #include diff --git a/sys/platform/pc64/x86_64/mp_machdep.c b/sys/platform/pc64/x86_64/mp_machdep.c index 4ba86bc322..560c600a6a 100644 --- a/sys/platform/pc64/x86_64/mp_machdep.c +++ b/sys/platform/pc64/x86_64/mp_machdep.c @@ -37,6 +37,8 @@ #include /* cngetc() */ #include +#include + #include #include #include diff --git a/sys/platform/pc64/x86_64/mplock.s b/sys/platform/pc64/x86_64/mplock.s deleted file mode 100644 index b0fc0a80a7..0000000000 --- a/sys/platform/pc64/x86_64/mplock.s +++ /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 - * - * 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): - * 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 -#include - -#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 - diff --git a/sys/platform/pc64/x86_64/npx.c b/sys/platform/pc64/x86_64/npx.c index a5d422d0e6..277006569c 100644 --- a/sys/platform/pc64/x86_64/npx.c +++ b/sys/platform/pc64/x86_64/npx.c @@ -51,7 +51,9 @@ #include #endif #include + #include +#include #ifndef SMP #include diff --git a/sys/platform/pc64/x86_64/trap.c b/sys/platform/pc64/x86_64/trap.c index d4da1de09f..1ad9f1da9b 100644 --- a/sys/platform/pc64/x86_64/trap.c +++ b/sys/platform/pc64/x86_64/trap.c @@ -81,7 +81,9 @@ #include #include + #include +#include #ifdef SMP diff --git a/sys/platform/pc64/x86_64/vm_machdep.c b/sys/platform/pc64/x86_64/vm_machdep.c index 8165d8d309..278d06d45e 100644 --- a/sys/platform/pc64/x86_64/vm_machdep.c +++ b/sys/platform/pc64/x86_64/vm_machdep.c @@ -72,6 +72,7 @@ #include #include +#include #include diff --git a/sys/platform/vkernel/conf/files b/sys/platform/vkernel/conf/files index ccc0d21b77..b639ce6c4a 100644 --- a/sys/platform/vkernel/conf/files +++ b/sys/platform/vkernel/conf/files @@ -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 diff --git a/sys/platform/vkernel/i386/cpu_regs.c b/sys/platform/vkernel/i386/cpu_regs.c index 88cd36756e..591632be0b 100644 --- a/sys/platform/vkernel/i386/cpu_regs.c +++ b/sys/platform/vkernel/i386/cpu_regs.c @@ -83,6 +83,7 @@ #include #include +#include #include #include diff --git a/sys/platform/vkernel/i386/genassym.c b/sys/platform/vkernel/i386/genassym.c index 8c4bdd93b6..743c5d5a40 100644 --- a/sys/platform/vkernel/i386/genassym.c +++ b/sys/platform/vkernel/i386/genassym.c @@ -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)); diff --git a/sys/platform/vkernel/i386/mp.c b/sys/platform/vkernel/i386/mp.c index 900d442cbc..c8fed9ee48 100644 --- a/sys/platform/vkernel/i386/mp.c +++ b/sys/platform/vkernel/i386/mp.c @@ -46,6 +46,8 @@ #include #include +#include + #include #include #include diff --git a/sys/platform/vkernel/i386/mplock.s b/sys/platform/vkernel/i386/mplock.s deleted file mode 100644 index 822a761f26..0000000000 --- a/sys/platform/vkernel/i386/mplock.s +++ /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 - * - * 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): - * 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 -#if 0 -#include -#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 - diff --git a/sys/platform/vkernel/i386/npx.c b/sys/platform/vkernel/i386/npx.c index b20276fe29..2f1426723c 100644 --- a/sys/platform/vkernel/i386/npx.c +++ b/sys/platform/vkernel/i386/npx.c @@ -54,7 +54,9 @@ #include #endif #include + #include +#include #ifndef SMP #include diff --git a/sys/platform/vkernel/i386/trap.c b/sys/platform/vkernel/i386/trap.c index 9333e6af49..664adc38c3 100644 --- a/sys/platform/vkernel/i386/trap.c +++ b/sys/platform/vkernel/i386/trap.c @@ -92,8 +92,10 @@ #include #include + #include #include +#include #ifdef SMP diff --git a/sys/platform/vkernel/i386/vm_machdep.c b/sys/platform/vkernel/i386/vm_machdep.c index ecf9b5b2dc..266c765fbb 100644 --- a/sys/platform/vkernel/i386/vm_machdep.c +++ b/sys/platform/vkernel/i386/vm_machdep.c @@ -76,7 +76,9 @@ #include #include + #include +#include #include diff --git a/sys/platform/vkernel/include/lock.h b/sys/platform/vkernel/include/lock.h index ad420a6cc0..20131d7e5c 100644 --- a/sys/platform/vkernel/include/lock.h +++ b/sys/platform/vkernel/include/lock.h @@ -42,56 +42,7 @@ #include #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_ */ diff --git a/sys/platform/vkernel/platform/busdma_machdep.c b/sys/platform/vkernel/platform/busdma_machdep.c index 92f6797a0d..2523dd1b1c 100644 --- a/sys/platform/vkernel/platform/busdma_machdep.c +++ b/sys/platform/vkernel/platform/busdma_machdep.c @@ -32,12 +32,14 @@ #include #include #include -#include #include #include #include #include + +#include #include +#include #include #include diff --git a/sys/platform/vkernel/platform/copyio.c b/sys/platform/vkernel/platform/copyio.c index 904e240007..9231995cbf 100644 --- a/sys/platform/vkernel/platform/copyio.c +++ b/sys/platform/vkernel/platform/copyio.c @@ -44,6 +44,8 @@ #include #include +#include + /* * 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 index 0000000000..1ea688a320 --- /dev/null +++ b/sys/sys/mplock2.h @@ -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 +#endif +#ifndef _SYS_THREAD_H_ +#include +#endif +#ifndef _SYS_GLOBALDATA_H_ +#include +#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 diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 46028d72b6..4b04fc46d7 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -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); diff --git a/sys/sys/thread.h b/sys/sys/thread.h index 4aacce7973..946cca7985 100644 --- a/sys/sys/thread.h +++ b/sys/sys/thread.h @@ -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 diff --git a/sys/vfs/devfs/devfs_vnops.c b/sys/vfs/devfs/devfs_vnops.c index 43c83c0085..e7ddd0c55f 100644 --- a/sys/vfs/devfs/devfs_vnops.c +++ b/sys/vfs/devfs/devfs_vnops.c @@ -61,9 +61,11 @@ #include #include -#include + #include #include +#include +#include MALLOC_DECLARE(M_DEVFS); #define DEVFS_BADOP (void *)devfs_badop diff --git a/sys/vfs/hammer/hammer_vnops.c b/sys/vfs/hammer/hammer_vnops.c index 31f02289d2..eedb090956 100644 --- a/sys/vfs/hammer/hammer_vnops.c +++ b/sys/vfs/hammer/hammer_vnops.c @@ -47,6 +47,9 @@ #include #include #include + +#include + #include "hammer.h" /* diff --git a/sys/vfs/nfs/nfs_syscalls.c b/sys/vfs/nfs/nfs_syscalls.c index 2058282009..99d279d0a1 100644 --- a/sys/vfs/nfs/nfs_syscalls.c +++ b/sys/vfs/nfs/nfs_syscalls.c @@ -62,6 +62,7 @@ #include #include +#include #include #include diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index d266f27ff3..af9d97f22a 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -80,6 +80,7 @@ #include #include +#include static int max_proc_mmap; SYSCTL_INT(_vm, OID_AUTO, max_proc_mmap, CTLFLAG_RW, &max_proc_mmap, 0, ""); diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c index 765457fe0c..8e73309e4c 100644 --- a/sys/vm/vm_swap.c +++ b/sys/vm/vm_swap.c @@ -52,12 +52,15 @@ #include #include #include -#include + #include #include #include #include +#include +#include + /* * Indirect driver for multi-controller paging. */ diff --git a/sys/vm/vm_unix.c b/sys/vm/vm_unix.c index a5658f66cf..b9745a1728 100644 --- a/sys/vm/vm_unix.c +++ b/sys/vm/vm_unix.c @@ -56,6 +56,8 @@ #include #include +#include + /* * obreak_args(char *nsize) * diff --git a/sys/vm/vm_vmspace.c b/sys/vm/vm_vmspace.c index 6d97b0eda4..49c90d9249 100644 --- a/sys/vm/vm_vmspace.c +++ b/sys/vm/vm_vmspace.c @@ -53,6 +53,7 @@ #include #include +#include static struct vmspace_entry *vkernel_find_vmspace(struct vkernel_proc *vkp, void *id); -- 2.41.0