# mailing list with the details.
+-----------------------------------------------------------------------+
++ UPGRADING DRAGONFLY FROM 3.2 to later versions +
++-----------------------------------------------------------------------+
+
+SMP OPTION REMOVED
+------------------
+
+The SMP kernel option has been removed. All kernels now feature SMP
+support. If you have 'options SMP' in your kernel config, you'll have
+to remove it.
+
++-----------------------------------------------------------------------+
+ UPGRADING DRAGONFLY FROM 3.0 to later versions +
+-----------------------------------------------------------------------+
int pmccfg;
pmccfg = pci_read_config(dev, 0x50, 2);
-#if defined(SMP)
if (pmccfg & 0x8000) {
kprintf("Correcting Natoma config for SMP\n");
pmccfg &= ~0x8000;
pci_write_config(dev, 0x50, pmccfg, 2);
}
-#else
- if ((pmccfg & 0x8000) == 0) {
- kprintf("Correcting Natoma config for non-SMP\n");
- pmccfg |= 0x8000;
- pci_write_config(dev, 0x50, pmccfg, 2);
- }
-#endif
}
/*
#ifdef PCIE_CFG_MECH
struct pcie_cfg_list *pcielist;
struct pcie_cfg_elem *pcie_array, *elem;
-#ifdef SMP
struct pcpu *pc;
-#endif
vm_offset_t va;
uint32_t val1, val2;
int i, slot;
kprintf("PCIe: Memory Mapped configuration base @ 0x%jx\n",
(uintmax_t)base);
-#ifdef SMP
SLIST_FOREACH(pc, &cpuhead, pc_allcpu)
-#endif
{
pcie_array = kmalloc(sizeof(struct pcie_cfg_elem) * PCIE_CACHE,
return (0);
}
-#ifdef SMP
pcielist = &pcie_list[pc->pc_cpuid];
-#else
- pcielist = &pcie_list[0];
-#endif
TAILQ_INIT(pcielist);
for (i = 0; i < PCIE_CACHE; i++) {
elem = &pcie_array[i];
# These are VM related options
NO_SWAPPING opt_vm.h
-# Standard SMP options
-SMP opt_global.h
-
# sys/netkey
KEY
#options ALTQ_NOPCC #don't use processor cycle counter
#options ALTQ_DEBUG #for debugging
-# Kernels configured with 'options SMP' should generally boot on both
-# SMP and UP boxes.
-#
-options SMP # Symmetric MultiProcessor Kernel
-
# Debugging for Development
options DDB
options DDB_TRACE
options ROOTDEVNAME=\"ufs:da0s2e\"
#####################################################################
-# SMP OPTIONS:
-#
-# SMP enables building of a Symmetric MultiProcessor Kernel. It will
-# boot on both SMP and UP boxes.
-#
-# Notes:
-#
-# An SMP kernel will ONLY run on an Intel MP spec. qualified motherboard.
-#
-# Be sure to disable 'cpu I486_CPU' for SMP kernels.
-#
-# Check the 'Rogue SMP hardware' section to see if additional options
-# are required by your hardware.
-#
-#options SMP # Symmetric MultiProcessor Kernel
-
-#####################################################################
# CPU OPTIONS
#
options ROOTDEVNAME=\"ufs:da0s2e\"
#####################################################################
-# SMP OPTIONS:
-#
-# SMP enables building of a Symmetric MultiProcessor Kernel. It will
-# boot on both SMP and UP boxes.
-#
-# Notes:
-#
-# An SMP kernel will ONLY run on an Intel MP spec. qualified motherboard.
-#
-# Check the 'Rogue SMP hardware' section to see if additional options
-# are required by your hardware.
-#
-#options SMP # Symmetric MultiProcessor Kernel
-
-#####################################################################
# CPU OPTIONS
cpu HAMMER_CPU
options _KPOSIX_PRIORITY_SCHEDULING
options ICMP_BANDLIM #Rate limit bad replies
-options SMP # Symmetric MultiProcessor Kernel
-
# Debugging for Development
options DDB
options DDB_TRACE
options _KPOSIX_PRIORITY_SCHEDULING
options ICMP_BANDLIM #Rate limit bad replies
-options SMP # Symmetric MultiProcessor Kernel
-
# Debugging for Development
options DDB
options DDB_TRACE
#options ALTQ_NOPCC #don't use processor cycle counter
#options ALTQ_DEBUG #for debugging
-
-# Kernels configured with 'options SMP' should generally boot on both
-# SMP and UP boxes.
-#
-options SMP # Symmetric MultiProcessor Kernel
-
# Debugging for Development
options DDB
options DDB_TRACE
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/include/atomic.h,v 1.9.2.1 2000/07/07 00:38:47 obrien Exp $
- * $DragonFly: src/sys/cpu/i386/include/atomic.h,v 1.25 2008/06/26 23:06:50 dillon Exp $
*/
#ifndef _CPU_ATOMIC_H_
#define _CPU_ATOMIC_H_
extern void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v); \
extern void atomic_##NAME##_##TYPE##_nonlocked(volatile u_##TYPE *p, u_##TYPE v);
#else /* !KLD_MODULE */
-#if defined(SMP) || !defined(_KERNEL)
#define MPLOCKED "lock ; "
-#else
-#define MPLOCKED
-#endif
/*
* The assembly is volatilized to demark potential before-and-after side
#else /* !KLD_MODULE */
-#if defined(_KERNEL) && !defined(SMP)
-/*
- * We assume that a = b will do atomic loads and stores. However, on a
- * PentiumPro or higher, reads may pass writes, so for that case we have
- * to use a serializing instruction (i.e. with LOCK) to do the load in
- * SMP kernels. For UP kernels, however, the cache of the single processor
- * is always consistent, so we don't need any memory barriers.
- */
-#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
-static __inline u_##TYPE \
-atomic_load_acq_##TYPE(volatile u_##TYPE *p) \
-{ \
- return (*p); \
-} \
- \
-static __inline void \
-atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
-{ \
- *p = v; \
-} \
-struct __hack
-
-#else /* !(_KERNEL && !SMP) */
-
#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
static __inline u_##TYPE \
atomic_load_acq_##TYPE(volatile u_##TYPE *p) \
} \
struct __hack
-#endif /* _KERNEL && !SMP */
-
#endif /* !KLD_MODULE */
ATOMIC_STORE_LOAD(char, "cmpxchgb %b0,%1", "xchgb %b1,%0");
#ifdef __GNUC__
-#ifdef SMP
#include <machine/lock.h> /* XXX */
-#endif
#ifdef SWTCH_OPTIM_STATS
extern int tlb_flush_count; /* XXX */
static __inline void
cpu_mfence(void)
{
-#ifdef SMP
#ifdef CPU_HAS_SSE2
__asm __volatile("mfence" : : : "memory");
#else
__asm __volatile("lock; addl $0,(%%esp)" : : : "memory");
#endif
-#else
- __asm __volatile("" : : : "memory");
-#endif
}
/*
static __inline void
cpu_lfence(void)
{
-#ifdef SMP
#ifdef CPU_HAS_SSE2
__asm __volatile("lfence" : : : "memory");
#else
__asm __volatile("lock; addl $0,(%%esp)" : : : "memory");
#endif
-#else
- __asm __volatile("" : : : "memory");
-#endif
}
/*
* will cause the invl*() functions to be equivalent to the cpu_invl*()
* functions.
*/
-#ifdef SMP
void smp_invltlb(void);
void smp_invltlb_intr(void);
-#else
-#define smp_invltlb()
-#endif
#ifndef _CPU_INVLPG_DEFINED
*
* from: @(#)param.h 5.8 (Berkeley) 6/28/91
* $FreeBSD: src/sys/i386/include/param.h,v 1.54.2.8 2002/08/31 21:15:55 dillon Exp $
- * $DragonFly: src/sys/cpu/i386/include/param.h,v 1.15 2008/08/25 17:01:35 dillon Exp $
*/
#ifndef _CPU_PARAM_H_
#ifndef SMP_MAXCPU
#define SMP_MAXCPU 16
#endif
-#ifdef SMP
#define MAXCPU SMP_MAXCPU
-#else
-#define MAXCPU 1
-#endif /* SMP */
#define ALIGNBYTES _ALIGNBYTES
#define ALIGN(p) _ALIGN(p)
*
* @(#)profile.h 8.1 (Berkeley) 6/11/93
* $FreeBSD: src/sys/i386/include/profile.h,v 1.20 1999/12/29 04:33:05 peter Exp $
- * $DragonFly: src/sys/cpu/i386/include/profile.h,v 1.9 2006/11/07 17:51:21 dillon Exp $
*/
#ifndef _CPU_PROFILE_H_
#define PC_TO_I(p, pc) ((uintfptr_t)(pc) - (uintfptr_t)(p)->lowpc)
#else
#define MCOUNT_DECL(s) u_long s;
-#ifdef SMP
struct spinlock_deprecated;
extern struct spinlock_deprecated mcount_spinlock;
void spin_lock_np(struct spinlock_deprecated *sp);
__asm __volatile("cli" : : : "memory"); \
spin_lock_np(&mcount_spinlock); }
#define MCOUNT_EXIT(s) { spin_unlock_np(&mcount_spinlock); write_eflags(s); }
-#else
-#define MCOUNT_ENTER(s) { s = read_eflags(); cpu_disable_intr(); }
-#define MCOUNT_EXIT(s) (write_eflags(s))
-#endif
#endif /* GUPROF */
#else /* !_KERNEL */
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/include/atomic.h,v 1.9.2.1 2000/07/07 00:38:47 obrien Exp $
- * $DragonFly: src/sys/cpu/i386/include/atomic.h,v 1.25 2008/06/26 23:06:50 dillon Exp $
*/
#ifndef _CPU_ATOMIC_H_
#define _CPU_ATOMIC_H_
extern void atomic_##NAME##_##TYPE(volatile u_##TYPE *p, u_##TYPE v); \
extern void atomic_##NAME##_##TYPE##_nonlocked(volatile u_##TYPE *p, u_##TYPE v);
#else /* !KLD_MODULE */
-#if defined(SMP) || !defined(_KERNEL)
#define MPLOCKED "lock ; "
-#else
-#define MPLOCKED
-#endif
/*
* The assembly is volatilized to demark potential before-and-after side
#else /* !KLD_MODULE */
-#if defined(_KERNEL) && !defined(SMP)
-/*
- * We assume that a = b will do atomic loads and stores. However, on a
- * PentiumPro or higher, reads may pass writes, so for that case we have
- * to use a serializing instruction (i.e. with LOCK) to do the load in
- * SMP kernels. For UP kernels, however, the cache of the single processor
- * is always consistent, so we don't need any memory barriers.
- */
-#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
-static __inline u_##TYPE \
-atomic_load_acq_##TYPE(volatile u_##TYPE *p) \
-{ \
- return (*p); \
-} \
- \
-static __inline void \
-atomic_store_rel_##TYPE(volatile u_##TYPE *p, u_##TYPE v)\
-{ \
- *p = v; \
-} \
-struct __hack
-
-#else /* !(_KERNEL && !SMP) */
-
#define ATOMIC_STORE_LOAD(TYPE, LOP, SOP) \
static __inline u_##TYPE \
atomic_load_acq_##TYPE(volatile u_##TYPE *p) \
} \
struct __hack
-#endif /* _KERNEL && !SMP */
-
#endif /* !KLD_MODULE */
ATOMIC_STORE_LOAD(char, "cmpxchgb %b0,%1", "xchgb %b1,%0");
#ifdef __GNUC__
-#ifdef SMP
#include <machine/lock.h> /* XXX */
-#endif
static __inline void
breakpoint(void)
static __inline void
cpu_mfence(void)
{
-#ifdef SMP
__asm __volatile("mfence" : : : "memory");
-#else
- __asm __volatile("" : : : "memory");
-#endif
}
/*
static __inline void
cpu_lfence(void)
{
-#ifdef SMP
__asm __volatile("lfence" : : : "memory");
-#else
- __asm __volatile("" : : : "memory");
-#endif
}
/*
* will cause the invl*() functions to be equivalent to the cpu_invl*()
* functions.
*/
-#ifdef SMP
void smp_invltlb(void);
void smp_invltlb_intr(void);
-#else
-#define smp_invltlb()
-#endif
#ifndef _CPU_INVLPG_DEFINED
* remain compatible between UP and SMP builds.
*/
#define SMP_MAXCPU 63
-#ifdef SMP
#define MAXCPU SMP_MAXCPU
-#else
-#define MAXCPU 1
-#endif /* SMP */
#define ALIGNBYTES _ALIGNBYTES
#define ALIGN(p) _ALIGN(p)
#define PC_TO_I(p, pc) ((uintfptr_t)(pc) - (uintfptr_t)(p)->lowpc)
#else
#define MCOUNT_DECL(s) u_long s;
-#ifdef SMP
extern int mcount_lock;
#define MCOUNT_ENTER(s) { s = read_rflags(); disable_intr(); \
while (!atomic_cmpset_acq_int(&mcount_lock, 0, 1)) \
/* nothing */ ; }
#define MCOUNT_EXIT(s) { atomic_store_rel_int(&mcount_lock, 0); \
write_rflags(s); }
-#else
-#define MCOUNT_ENTER(s) { s = read_rflags(); disable_intr(); }
-#define MCOUNT_EXIT(s) (write_rflags(s))
-#endif
#endif /* GUPROF */
#else /* !_KERNEL */
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/ddb/db_ps.c,v 1.20 1999/08/28 00:41:09 peter Exp $
- * $DragonFly: src/sys/ddb/db_ps.c,v 1.25 2008/06/29 21:38:21 dillon Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
tok = ref->tr_tok;
db_printf(" %p[tok=%p", ref, ref->tr_tok);
-#ifdef SMP
if (tok->t_ref && td == tok->t_ref->tr_owner)
db_printf(",held");
-#endif
db_printf("]");
}
db_printf("\n");
ia64_call_pal_static(PAL_HALT_LIGHT, 0, 0, 0);
#else
splz();
-#ifdef SMP
if ((mycpu->gd_reqflags & RQF_IDLECHECK_WK_MASK) == 0)
__asm __volatile("sti; hlt");
else
__asm __volatile("sti; pause");
-#else
- if ((mycpu->gd_reqflags & RQF_IDLECHECK_WK_MASK) == 0)
- __asm __volatile("sti; hlt");
- else
- __asm __volatile("sti");
-#endif
#endif /* !__ia64__ */
}
static void
aue_start_schedule(struct ifnet *ifp)
{
-#ifdef SMP
int cpu;
cpu = ifp->if_start_cpuid(ifp);
if (cpu != mycpuid)
lwkt_send_ipiq(globaldata_find(cpu), aue_start_ipifunc, ifp);
else
-#endif
- aue_start_ipifunc(ifp);
+ aue_start_ipifunc(ifp);
}
/*
static void
lgue_start_schedule(struct ifnet *ifp)
{
-#ifdef SMP
int cpu;
cpu = ifp->if_start_cpuid(ifp);
if (cpu != mycpuid)
lwkt_send_ipiq(globaldata_find(cpu), lgue_start_ipifunc, ifp);
else
-#endif
lgue_start_ipifunc(ifp);
}
#include <sys/syslog.h>
#include <sys/thread2.h>
#include <machine/clock.h>
-#ifndef SMP
-#include <machine/lock.h>
-#endif
#include <machine/psl.h>
#include <bus/isa/isa_device.h>
#include "cyreg.h"
#include <machine_base/isa/ic/cd1400.h>
-#ifdef SMP
#define disable_intr() com_lock()
#define enable_intr() com_unlock()
-#else
-#define disable_intr() ((void)0)
-#define enable_intr() ((void)0)
-#endif /* SMP */
/*
* Dictionary so that I can name everything *sio* or *com* to compare with
#include <machine/lock.h>
#include <machine/clock.h>
-#ifndef SMP
-#include <machine/lock.h>
-#endif
#include "sioreg.h"
#include "sio_private.h"
movl 12(%esp),%edx
cmpl $VM_MAX_USER_ADDRESS-4,%edx
ja futex_fault_pop
-#ifdef SMP
lock
-#endif
xaddl %eax,(%edx)
movl 16(%esp),%edx
movl %eax,(%edx)
movl (%edx),%eax
1: movl %eax,%ecx
orl 8(%esp),%ecx
-#ifdef SMP
lock
-#endif
cmpxchgl %ecx,(%edx)
jnz 1b
futex_tail:
movl (%edx),%eax
1: movl %eax,%ecx
andl 8(%esp),%ecx
-#ifdef SMP
lock
-#endif
cmpxchgl %ecx,(%edx)
jnz 1b
jmp futex_tail
movl (%edx),%eax
1: movl %eax,%ecx
xorl 8(%esp),%ecx
-#ifdef SMP
lock
-#endif
cmpxchgl %ecx,(%edx)
jnz 1b
jmp futex_tail
*
* @(#)kern_clock.c 8.5 (Berkeley) 1/21/94
* $FreeBSD: src/sys/kern/kern_clock.c,v 1.105.2.10 2002/10/17 13:19:40 maxim Exp $
- * $DragonFly: src/sys/kern/kern_clock.c,v 1.62 2008/09/09 04:06:13 dillon Exp $
*/
#include "opt_ntp.h"
struct kinfo_pctrack cputime_pctrack[MAXCPU][PCTRACK_SIZE];
#endif
-#ifdef SMP
static int
sysctl_cputime(SYSCTL_HANDLER_ARGS)
{
}
SYSCTL_PROC(_kern, OID_AUTO, cputime, (CTLTYPE_OPAQUE|CTLFLAG_RD), 0, 0,
sysctl_cputime, "S,kinfo_cputime", "CPU time statistics");
-#else
-SYSCTL_STRUCT(_kern, OID_AUTO, cputime, CTLFLAG_RD, &cpu_time, kinfo_cputime,
- "CPU time statistics");
-#endif
static int
sysctl_cp_time(SYSCTL_HANDLER_ARGS)
* We are NOT in a critical section, which will allow the scheduled
* interrupt to preempt us. The MP lock might *NOT* be held here.
*/
-#ifdef SMP
-
static void
sched_ithd_remote(void *arg)
{
sched_ithd_intern(arg);
}
-#endif
-
static void
sched_ithd_intern(struct intr_info *info)
{
if (info->i_reclist == NULL) {
report_stray_interrupt(info, "sched_ithd");
} else {
-#ifdef SMP
if (info->i_thread.td_gd == mycpu) {
if (info->i_running == 0) {
info->i_running = 1;
} else {
lwkt_send_ipiq(info->i_thread.td_gd, sched_ithd_remote, info);
}
-#else
- if (info->i_running == 0) {
- info->i_running = 1;
- if (info->i_state != ISTATE_LIVELOCKED)
- lwkt_schedule(&info->i_thread); /* MIGHT PREEMPT */
- }
-#endif
}
} else {
report_stray_interrupt(info, "sched_ithd");
struct intr_info *info;
struct intrec **list;
int must_schedule;
-#ifdef SMP
int got_mplock;
-#endif
TD_INVARIANTS_DECLARE;
intrec_t rec, nrec;
globaldata_t gd;
++gd->gd_intr_nesting_level;
++gd->gd_cnt.v_intr;
must_schedule = info->i_slow;
-#ifdef SMP
got_mplock = 0;
-#endif
TD_INVARIANTS_GET(td);
list = &info->i_reclist;
nrec = rec->next;
if (rec->intr_flags & INTR_CLOCK) {
-#ifdef SMP
if ((rec->intr_flags & INTR_MPSAFE) == 0 && got_mplock == 0) {
if (try_mplock() == 0) {
/* Couldn't get the MP lock; just schedule it. */
}
got_mplock = 1;
}
-#endif
if (rec->serializer) {
must_schedule += lwkt_serialize_handler_try(
rec->serializer, rec->handler,
* Cleanup
*/
--gd->gd_intr_nesting_level;
-#ifdef SMP
if (got_mplock)
rel_mplock();
-#endif
/*
* If we had a problem, or mixed fast and slow interrupt handlers are
* are MPSAFE. However, if intr_mpsafe has been turned off we
* always operate with the BGL.
*/
-#ifdef SMP
if (info->i_mplock_required != mpheld) {
if (info->i_mplock_required) {
KKASSERT(mpheld == 0);
mpheld = 0;
}
}
-#endif
TD_INVARIANTS_GET(gd->gd_curthread);
kl->kl_stat = LSSLEEP;
}
}
-#if defined(_KERNEL) && defined(SMP)
+#ifdef _KERNEL
kl->kl_mpcount = get_mplock_count(lwp->lwp_thread);
#else
kl->kl_mpcount = 0;
kp->kp_lwp.kl_pid = -1;
kp->kp_lwp.kl_tid = -1;
kp->kp_lwp.kl_tdflags = td->td_flags;
-#if defined(_KERNEL) && defined(SMP)
+#ifdef _KERNEL
kp->kp_lwp.kl_mpcount = get_mplock_count(td);
#else
kp->kp_lwp.kl_mpcount = 0;
KTR_INFO(KTR_TESTLOG, testlog, test4, 3, "test4");
KTR_INFO(KTR_TESTLOG, testlog, test5, 4, "test5");
KTR_INFO(KTR_TESTLOG, testlog, test6, 5, "test6");
-#ifdef SMP
KTR_INFO(KTR_TESTLOG, testlog, pingpong, 6, "pingpong");
KTR_INFO(KTR_TESTLOG, testlog, pipeline, 7, "pipeline");
KTR_INFO(KTR_TESTLOG, testlog, crit_beg, 8, "crit_beg");
KTR_INFO(KTR_TESTLOG, testlog, crit_end, 9, "crit_end");
KTR_INFO(KTR_TESTLOG, testlog, spin_beg, 10, "spin_beg");
KTR_INFO(KTR_TESTLOG, testlog, spin_end, 11, "spin_end");
-#endif
#define logtest(name) KTR_LOG(testlog_ ## name, 0, 0, 0, 0)
#define logtest_noargs(name) KTR_LOG(testlog_ ## name)
#endif
static int ktr_testlogcnt = 0;
SYSCTL_INT(_debug_ktr, OID_AUTO, testlogcnt, CTLFLAG_RW, &ktr_testlogcnt, 0, "");
static int ktr_testipicnt = 0;
-#ifdef SMP
static int ktr_testipicnt_remainder;
-#endif
SYSCTL_INT(_debug_ktr, OID_AUTO, testipicnt, CTLFLAG_RW, &ktr_testipicnt, 0, "");
static int ktr_testcritcnt = 0;
SYSCTL_INT(_debug_ktr, OID_AUTO, testcritcnt, CTLFLAG_RW, &ktr_testcritcnt, 0, "");
{ .core.ktr_buf = &ktr_buf0[0] }
};
-#ifdef SMP
static int64_t ktr_sync_tsc;
-#endif
struct callout ktr_resync_callout;
#ifdef KTR_VERBOSE
* This callback occurs on cpu0.
*/
#if KTR_TESTLOG
-#ifdef SMP
static void ktr_pingpong_remote(void *dummy);
static void ktr_pipeline_remote(void *dummy);
#endif
-#endif
-#if defined(SMP) && defined(_RDTSC_SUPPORTED_)
+#ifdef _RDTSC_SUPPORTED_
static void ktr_resync_remote(void *dummy);
extern cpumask_t smp_active_mask;
#endif
-#else /* !SMP */
+#else /* !_RDTSC_SUPPORTED_ */
/*
* The resync callback for UP doesn't do anything other then run the test
++kcpu->ktr_idx;
#ifdef _RDTSC_SUPPORTED_
if (cpu_feature & CPUID_TSC) {
-#ifdef SMP
entry->ktr_timestamp = rdtsc() - tsc_offsets[cpu];
-#else
- entry->ktr_timestamp = rdtsc();
-#endif
} else
#endif
{
cpu_ktr_caller(entry);
#ifdef KTR_VERBOSE
if (ktr_verbose && info->kf_format) {
-#ifdef SMP
kprintf("cpu%d ", mycpu->gd_cpuid);
-#endif
if (ktr_verbose > 1) {
kprintf("%s.%d\t", entry->ktr_file, entry->ktr_line);
}
{
if (kp->ktr_info == NULL)
return(0);
-#ifdef SMP
db_printf("cpu%d ", cpu);
-#endif
db_printf("%d: ", idx);
if (db_ktr_verbose) {
db_printf("%10.10lld %s.%d\t", (long long)kp->ktr_timestamp,
return (mem_range_softc.mr_op->set(&mem_range_softc, mrd, arg));
}
-#ifdef SMP
void
mem_range_AP_init(void)
{
if (mem_range_softc.mr_op && mem_range_softc.mr_op->initAP)
return (mem_range_softc.mr_op->initAP(&mem_range_softc));
}
-#endif
static int
random_ioctl(cdev_t dev, u_long cmd, caddr_t data, int flags, struct ucred *cred)
SYSCTL_STRING(_kern, KERN_BOOTFILE, bootfile, CTLFLAG_RW,
kernelname, sizeof kernelname, "Name of kernel file booted");
-#ifdef SMP
SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD,
&ncpus, 0, "Number of active CPUs");
-#else
-SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD,
- 0, 1, "Number of active CPUs");
-#endif
SYSCTL_INT(_hw, HW_BYTEORDER, byteorder, CTLFLAG_RD,
0, BYTE_ORDER, "System byte order");
/* collect extra flags that shutdown_nice might have set */
howto |= shutdown_howto;
-#ifdef SMP
/*
* We really want to shutdown on the BSP. Subsystems such as ACPI
* can't power-down the box otherwise.
kprintf("Switching to cpu #0 for shutdown\n");
lwkt_setcpu_self(globaldata_find(0));
}
-#endif
/*
* Do any callouts that should be done BEFORE syncing the filesystems.
*/
__va_list ap;
static char buf[256];
-#ifdef SMP
/*
* If a panic occurs on multiple cpus before the first is able to
* halt the other cpus, only one cpu is allowed to take the panic.
if (atomic_cmpset_ptr(&panic_cpu_gd, NULL, gd))
break;
}
-#else
- panic_cpu_gd = gd;
-#endif
/*
* Try to get the system into a working state. Save information
* we are about to destroy.
panicstr = buf;
__va_end(ap);
kprintf("panic: %s\n", buf);
-#ifdef SMP
/* two separate prints in case of an unmapped page and trap */
kprintf("cpuid = %d\n", mycpu->gd_cpuid);
-#endif
#if (NGPIO > 0) && defined(ERROR_LED_ON_PANIC)
led_switch("error", 1);
Debugger("panic");
else
#endif
-#ifdef SMP
if (newpanic)
stop_cpus(mycpu->gd_other_cpus);
-#else
- ;
-#endif
boot(bootopt);
}
int dump_stop_usertds = 0;
-#ifdef SMP
static
void
need_user_resched_remote(void *dummy)
{
need_user_resched();
}
-#endif
void
dump_reactivate_cpus(void)
{
-#ifdef SMP
globaldata_t gd;
int cpu, seq;
-#endif
dump_stop_usertds = 1;
need_user_resched();
-#ifdef SMP
for (cpu = 0; cpu < ncpus; cpu++) {
gd = globaldata_find(cpu);
seq = lwkt_send_ipiq(gd, need_user_resched_remote, NULL);
}
restart_cpus(stopped_cpus);
-#endif
}
static int sig_ffs(sigset_t *set);
static int sigprop(int sig);
static void lwp_signotify(struct lwp *lp);
-#ifdef SMP
static void lwp_signotify_remote(void *arg);
-#endif
static int kern_sigtimedwait(sigset_t set, siginfo_t *info,
struct timespec *timeout);
/*
* lwp is sitting in tsleep() with PCATCH set
*/
-#ifdef SMP
if (lp->lwp_thread->td_gd == mycpu) {
setrunnable(lp);
} else {
lwkt_send_ipiq(lp->lwp_thread->td_gd,
lwp_signotify_remote, lp);
}
-#else
- setrunnable(lp);
-#endif
} else if (lp->lwp_thread->td_flags & TDF_SINTR) {
/*
* lwp is sitting in lwkt_sleep() with PCATCH set.
*/
-#ifdef SMP
if (lp->lwp_thread->td_gd == mycpu) {
setrunnable(lp);
} else {
lwkt_send_ipiq(lp->lwp_thread->td_gd,
lwp_signotify_remote, lp);
}
-#else
- setrunnable(lp);
-#endif
} else {
/*
* Otherwise the lwp is either in some uninterruptable state
crit_exit();
}
-#ifdef SMP
-
/*
* This function is called via an IPI so we cannot call setrunnable() here
* (because while we hold the lp we don't own its token, and can't get it
}
}
-#endif
-
/*
* Caller must hold p->p_token
*/
KTR_INFO(KTR_MEMORY, memory, free_ovsz, 3, MEMORY_STRING, MEMORY_ARGS);
KTR_INFO(KTR_MEMORY, memory, free_ovsz_delayed, 4, MEMORY_STRING, MEMORY_ARGS);
KTR_INFO(KTR_MEMORY, memory, free_chunk, 5, MEMORY_STRING, MEMORY_ARGS);
-#ifdef SMP
KTR_INFO(KTR_MEMORY, memory, free_request, 6, MEMORY_STRING, MEMORY_ARGS);
KTR_INFO(KTR_MEMORY, memory, free_rem_beg, 7, MEMORY_STRING, MEMORY_ARGS);
KTR_INFO(KTR_MEMORY, memory, free_rem_end, 8, MEMORY_STRING, MEMORY_ARGS);
-#endif
KTR_INFO(KTR_MEMORY, memory, free_beg, 9, "free begin");
KTR_INFO(KTR_MEMORY, memory, free_end, 10, "free end");
if (type->ks_limit == 0)
panic("malloc_uninit on uninitialized type");
-#ifdef SMP
/* Make sure that all pending kfree()s are finished. */
lwkt_synchronize_ipiqs("muninit");
-#endif
#ifdef INVARIANTS
/*
{
SLZone *z;
SLChunk *chunk;
-#ifdef SMP
SLChunk *bchunk;
-#endif
SLGlobalData *slgd;
struct globaldata *gd;
unsigned long align;
if (--z->z_NFree <= 0) {
KKASSERT(z->z_NFree == 0);
-#ifdef SMP
/*
* WARNING! This code competes with other cpus. It is ok
* for us to not drain RChunks here but we might as well, and
break;
}
}
-#endif
/*
* Remove from the zone list if no free chunks remain.
* Clear RSignal
return(nstr);
}
-#ifdef SMP
/*
* Notify our cpu that a remote cpu has freed some chunks in a zone that
* we own. RCount will be bumped so the memory should be good, but validate
logmemory(free_rem_end, z, bchunk, 0L, 0);
}
-#endif
-
/*
* free (SLAB ALLOCATOR)
*
struct globaldata *gd;
int *kup;
unsigned long size;
-#ifdef SMP
SLChunk *bchunk;
int rsignal;
-#endif
logmemory_quick(free_beg);
gd = mycpu;
* (no critical section needed)
*/
if (z->z_CpuGd != gd) {
-#ifdef SMP
/*
* Making these adjustments now allow us to avoid passing (type)
* to the remote cpu. Note that ks_inuse/ks_memuse is being
atomic_subtract_int(&z->z_RCount, 1);
/* z can get ripped out from under us from this point on */
}
-#else
- panic("Corrupt SLZone");
-#endif
logmemory_quick(free_end);
return;
}
struct spinlock pmap_spin = SPINLOCK_INITIALIZER(pmap_spin);
-#ifdef SMP
-
struct indefinite_info {
sysclock_t base;
int secs;
0, 0, sysctl_spin_lock_test, "I", "Test spinlock wait code");
#endif /* INVARIANTS */
-#endif /* SMP */
*
* @(#)kern_synch.c 8.9 (Berkeley) 5/19/95
* $FreeBSD: src/sys/kern/kern_synch.c,v 1.87.2.6 2002/10/13 07:29:53 kbyanc Exp $
- * $DragonFly: src/sys/kern/kern_synch.c,v 1.91 2008/09/09 04:06:13 dillon Exp $
*/
#include "opt_ktrace.h"
struct thread *td;
struct thread *ntd;
globaldata_t gd;
-#ifdef SMP
cpumask_t mask;
-#endif
int id;
crit_enter();
}
}
-#ifdef SMP
/*
* We finished checking the current cpu but there still may be
* more work to do. Either wakeup_one was requested and no matching
lwkt_send_ipiq2_mask(mask, _wakeup, ident,
domain | PWAKEUP_MYCPU);
}
-#endif
done:
logtsleep1(wakeup_end);
crit_exit();
void
wakeup_oncpu(globaldata_t gd, const volatile void *ident)
{
-#ifdef SMP
globaldata_t mygd = mycpu;
if (gd == mycpu) {
_wakeup(__DEALL(ident), PWAKEUP_ENCODE(0, mygd->gd_cpuid) |
PWAKEUP_ENCODE(0, mygd->gd_cpuid) |
PWAKEUP_MYCPU);
}
-#else
- _wakeup(__DEALL(ident), PWAKEUP_MYCPU);
-#endif
}
/*
void
wakeup_oncpu_one(globaldata_t gd, const volatile void *ident)
{
-#ifdef SMP
globaldata_t mygd = mycpu;
if (gd == mygd) {
_wakeup(__DEALL(ident), PWAKEUP_ENCODE(0, mygd->gd_cpuid) |
PWAKEUP_ENCODE(0, mygd->gd_cpuid) |
PWAKEUP_MYCPU | PWAKEUP_ONE);
}
-#else
- _wakeup(__DEALL(ident), PWAKEUP_MYCPU | PWAKEUP_ONE);
-#endif
}
/*
* 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: src/sys/kern/kern_systimer.c,v 1.12 2007/10/16 11:12:59 sephe Exp $
*/
/*
info->flags = (info->flags | SYSTF_ONQUEUE) & ~SYSTF_IPIRUNNING;
info->queue = &gd->gd_systimerq;
} else {
-#ifdef SMP
KKASSERT((info->flags & SYSTF_IPIRUNNING) == 0);
info->flags |= SYSTF_IPIRUNNING;
lwkt_send_ipiq(info->gd, (ipifunc1_t)systimer_add, info);
-#else
- panic("systimer_add: bad gd in info %p", info);
-#endif
}
crit_exit();
}
struct callout_tailq *bucket;
void (*c_func)(void *);
void *c_arg;
-#ifdef SMP
int mpsafe = 1;
-#endif
/*
* Run the callout thread at the same priority as other kernel
sc->next = TAILQ_NEXT(c, c_links.tqe);
continue;
}
-#ifdef SMP
if (c->c_flags & CALLOUT_MPSAFE) {
if (mpsafe == 0) {
mpsafe = 1;
continue;
}
}
-#endif
sc->next = TAILQ_NEXT(c, c_links.tqe);
TAILQ_REMOVE(bucket, c, c_links.tqe);
c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING);
c->c_func = ftn;
c->c_time = sc->curticks + to_ticks;
-#ifdef SMP
c->c_gd = gd;
-#endif
TAILQ_INSERT_TAIL(&sc->callwheel[c->c_time & callwheelmask],
c, c_links.tqe);
crit_exit_gd(gd);
}
-#ifdef SMP
-
struct callout_remote_arg {
struct callout *c;
void (*ftn)(void *);
callout_reset(rmt->c, rmt->to_ticks, rmt->ftn, rmt->arg);
}
-#endif
-
void
callout_reset_bycpu(struct callout *c, int to_ticks, void (*ftn)(void *),
void *arg, int cpuid)
{
KASSERT(cpuid >= 0 && cpuid < ncpus, ("invalid cpuid %d", cpuid));
-#ifndef SMP
- callout_reset(c, to_ticks, ftn, arg);
-#else
if (cpuid == mycpuid) {
callout_reset(c, to_ticks, ftn, arg);
} else {
seq = lwkt_send_ipiq(target_gd, callout_reset_ipi, &rmt);
lwkt_wait_ipiq(target_gd, seq);
}
-#endif
}
/*
callout_stop(struct callout *c)
{
globaldata_t gd = mycpu;
-#ifdef SMP
globaldata_t tgd;
-#endif
softclock_pcpu_t sc;
#ifdef INVARIANTS
* cpu.
*/
if ((c->c_flags & CALLOUT_PENDING) == 0) {
-#ifdef SMP
if ((c->c_flags & CALLOUT_ACTIVE) == 0) {
crit_exit_gd(gd);
return (0);
crit_exit_gd(gd);
return (0);
}
- /* fall-through to the cpu-localization code. */
-#else
- c->c_flags &= ~CALLOUT_ACTIVE;
- crit_exit_gd(gd);
- return (0);
-#endif
}
-#ifdef SMP
if ((tgd = c->c_gd) != gd) {
/*
* If the callout is owned by a different CPU we have to
cpu_ccfence(); /* don't let tgd alias c_gd */
seq = lwkt_send_ipiq(tgd, (void *)callout_stop, c);
lwkt_wait_ipiq(tgd, seq);
- } else
-#endif
- {
+ } else {
/*
* If the callout is owned by the same CPU we can
* process it directly, but if we are racing our helper
while (c->c_flags & CALLOUT_DID_INIT) {
callout_stop(c);
-#ifdef SMP
if (c->c_gd) {
sc = &softclock_pcpu_ary[c->c_gd->gd_cpuid];
if (sc->running == c) {
tsleep(&sc->running, 0, "crace", 1);
}
}
-#else
- sc = &softclock_pcpu_ary[0];
- if (sc->running == c) {
- while (sc->running == c)
- tsleep(&sc->running, 0, "crace", 1);
- }
-#endif
if ((c->c_flags & (CALLOUT_PENDING | CALLOUT_ACTIVE)) == 0)
break;
kprintf("Warning: %s: callout race\n", curthread->td_comm);
if (c->c_flags & CALLOUT_DID_INIT) {
callout_stop(c);
-#ifdef SMP
sc = &softclock_pcpu_ary[c->c_gd->gd_cpuid];
-#else
- sc = &softclock_pcpu_ary[0];
-#endif
if (sc->running == c) {
while (sc->running == c)
tsleep(&sc->running, 0, "crace", 1);
MALLOC_DEFINE(M_UPCALL, "upcalls", "upcall registration structures");
-#ifdef SMP
-
static void
sigupcall_remote(void *arg)
{
sigupcall();
}
-#endif
-
/*
* upc_register:
*
targlp->lwp_proc->p_flags |= P_UPCALLPEND; /* XXX lwp flags */
if (targlp->lwp_proc->p_flags & P_UPCALLWAIT)
wakeup(&targlp->lwp_upcall);
-#ifdef SMP
if (targlp->lwp_thread->td_gd != mycpu)
lwkt_send_ipiq(targlp->lwp_thread->td_gd, sigupcall_remote, targlp);
else
sigupcall();
-#else
- sigupcall();
-#endif
break;
}
}
#include <machine/smp.h>
#include <machine/atomic.h>
-#ifdef SMP
static __int64_t ipiq_count; /* total calls to lwkt_send_ipiq*() */
static __int64_t ipiq_fifofull; /* number of fifo full conditions detected */
static __int64_t ipiq_avoided; /* interlock with target avoids cpu ipi */
static int panic_ipiq_cpu = -1;
static int panic_ipiq_count = 100;
#endif
-#endif
-#ifdef SMP
SYSCTL_QUAD(_lwkt, OID_AUTO, ipiq_count, CTLFLAG_RW, &ipiq_count, 0,
"Number of IPI's sent");
SYSCTL_QUAD(_lwkt, OID_AUTO, ipiq_fifofull, CTLFLAG_RW, &ipiq_fifofull, 0,
#define logipiq2(name, arg) \
KTR_LOG(ipiq_ ## name, arg)
-#endif /* SMP */
-
-#ifdef SMP
-
static int lwkt_process_ipiq_core(globaldata_t sgd, lwkt_ipiq_t ip,
struct intrframe *frame);
static void lwkt_cpusync_remote1(lwkt_cpusync_t cs);
}
}
-#endif
-
/*
* CPU Synchronization Support
*
void
lwkt_cpusync_interlock(lwkt_cpusync_t cs)
{
-#ifdef SMP
#if 0
const char *smsg = "SMPSYNL";
#endif
#endif
DEBUG_POP_INFO();
}
-#else
- cs->cs_mack = 0;
-#endif
}
/*
lwkt_cpusync_deinterlock(lwkt_cpusync_t cs)
{
globaldata_t gd = mycpu;
-#ifdef SMP
#if 0
const char *smsg = "SMPSYNU";
#endif
logipiq2(sync_end, (long)mask);
}
crit_exit_id("cpusync");
-#else
- if (cs->cs_func && (cs->cs_mask & gd->gd_cpumask))
- cs->cs_func(cs->cs_data);
-#endif
}
-#ifdef SMP
-
/*
* helper IPI remote messaging function.
*
}
}
}
-
-#endif
#include <machine/stdarg.h>
#include <machine/cpufunc.h>
-#ifdef SMP
#include <machine/smp.h>
-#endif
#include <sys/malloc.h>
MALLOC_DEFINE(M_LWKTMSG, "lwkt message", "lwkt message");
* message were headed to a different cpu.
*/
-#ifdef SMP
-
/*
* This function completes reply processing for the default case in the
* context of the originating cpu.
_lwkt_schedule_msg(port->mpu_td, flags);
}
-#endif
-
/*
* lwkt_thread_replyport() - Backend to lwkt_replymsg()
*
* Assume the target thread is non-preemptive, so no critical
* section is required.
*/
-#ifdef SMP
if (port->mpu_td->td_gd == mycpu) {
-#endif
flags = msg->ms_flags;
cpu_sfence();
msg->ms_flags |= MSGF_DONE | MSGF_REPLY;
if (port->mp_flags & MSGPORTF_WAITING)
_lwkt_schedule_msg(port->mpu_td, flags);
-#ifdef SMP
} else {
#ifdef INVARIANTS
msg->ms_flags |= MSGF_INTRANSIT;
lwkt_send_ipiq(port->mpu_td->td_gd,
(ipifunc1_t)lwkt_thread_replyport_remote, msg);
}
-#endif
} else {
/*
* If an asynchronous completion has been requested the message
*
* A critical section is required to interlock the port queue.
*/
-#ifdef SMP
if (port->mpu_td->td_gd == mycpu) {
-#endif
crit_enter();
_lwkt_enqueue_reply(port, msg);
if (port->mp_flags & MSGPORTF_WAITING)
_lwkt_schedule_msg(port->mpu_td, msg->ms_flags);
crit_exit();
-#ifdef SMP
} else {
#ifdef INVARIANTS
msg->ms_flags |= MSGF_INTRANSIT;
lwkt_send_ipiq(port->mpu_td->td_gd,
(ipifunc1_t)lwkt_thread_replyport_remote, msg);
}
-#endif
}
}
*
* The message must already have cleared MSGF_DONE and MSGF_REPLY
*/
-
-#ifdef SMP
-
static
void
lwkt_thread_putport_remote(lwkt_msg_t msg)
_lwkt_schedule_msg(port->mpu_td, msg->ms_flags);
}
-#endif
-
static
int
lwkt_thread_putport(lwkt_port_t port, lwkt_msg_t msg)
KKASSERT((msg->ms_flags & (MSGF_DONE | MSGF_REPLY)) == 0);
msg->ms_target_port = port;
-#ifdef SMP
if (port->mpu_td->td_gd == mycpu) {
-#endif
crit_enter();
_lwkt_pushmsg(port, msg);
if (port->mp_flags & MSGPORTF_WAITING)
_lwkt_schedule_msg(port->mpu_td, msg->ms_flags);
crit_exit();
-#ifdef SMP
} else {
#ifdef INVARIANTS
msg->ms_flags |= MSGF_INTRANSIT;
lwkt_send_ipiq(port->mpu_td->td_gd,
(ipifunc1_t)lwkt_thread_putport_remote, msg);
}
-#endif
return (EASYNC);
}
KTR_INFO(KTR_SERIALIZER, slz, try, 6, SLZ_KTR_STRING, SLZ_KTR_ARGS);
KTR_INFO(KTR_SERIALIZER, slz, tryfail, 7, SLZ_KTR_STRING, SLZ_KTR_ARGS);
KTR_INFO(KTR_SERIALIZER, slz, tryok, 8, SLZ_KTR_STRING, SLZ_KTR_ARGS);
-#ifdef SMP
KTR_INFO(KTR_SERIALIZER, slz, spinbo, 9,
"slz=%p bo1=%d bo=%d", lwkt_serialize_t slz, int backoff1, int backoff);
-#endif
KTR_INFO(KTR_SERIALIZER, slz, enter_end, 10, SLZ_KTR_STRING, SLZ_KTR_ARGS);
KTR_INFO(KTR_SERIALIZER, slz, exit_beg, 11, SLZ_KTR_STRING, SLZ_KTR_ARGS);
#define logslz(name, slz) KTR_LOG(slz_ ## name, slz)
-#ifdef SMP
#define logslz_spinbo(slz, bo1, bo) KTR_LOG(slz_spinbo, slz, bo1, bo)
-#endif
static void lwkt_serialize_sleep(void *info);
static void lwkt_serialize_wakeup(void *info);
-
-#ifdef SMP
static void lwkt_serialize_adaptive_sleep(void *bo);
static int slz_backoff_limit = 128;
SYSCTL_INT(_debug, OID_AUTO, serialize_boround, CTLFLAG_RW,
&slz_backoff_round, 0,
"Backoff rounding");
-#endif /* SMP */
void
lwkt_serialize_init(lwkt_serialize_t s)
#endif
}
-#ifdef SMP
void
lwkt_serialize_adaptive_enter(lwkt_serialize_t s)
{
s->last_td = curthread;
#endif
}
-#endif /* SMP */
void
lwkt_serialize_enter(lwkt_serialize_t s)
}
}
-#ifdef SMP
-
static void
lwkt_serialize_adaptive_sleep(void *arg)
{
}
}
-#endif /* SMP */
-
static void
lwkt_serialize_wakeup(void *info)
{
logslz(wakeup_end, info);
}
-#ifdef SMP
static void
lwkt_serialize_sysinit(void *dummy __unused)
{
}
SYSINIT(lwkt_serialize, SI_SUB_PRE_DRIVERS, SI_ORDER_SECOND,
lwkt_serialize_sysinit, NULL);
-#endif
static int lwkt_use_spin_port;
static struct objcache *thread_cache;
-#ifdef SMP
static void lwkt_schedule_remote(void *arg, int arg2, struct intrframe *frame);
static void lwkt_setcpu_remote(void *arg);
-#endif
extern void cpu_heavy_restore(void);
extern void cpu_lwkt_restore(void);
* NOTE! we have to be careful in regards to creating threads for other cpus
* if SMP has not yet been activated.
*/
-#ifdef SMP
-
static void
lwkt_init_thread_remote(void *arg)
{
TAILQ_INSERT_TAIL(&td->td_gd->gd_tdallq, td, td_allq);
}
-#endif
-
/*
* lwkt core thread structural initialization.
*
else
lwkt_initport_thread(&td->td_msgport, td);
pmap_init_thread(td);
-#ifdef SMP
/*
* Normally initializing a thread for a remote cpu requires sending an
* IPI. However, the idlethread is setup before the other cpus are
} else {
lwkt_send_ipiq(gd, lwkt_init_thread_remote, td);
}
-#else
- crit_enter_gd(mygd);
- TAILQ_INSERT_TAIL(&gd->gd_tdallq, td, td_allq);
- crit_exit_gd(mygd);
-#endif
-
dsched_new_thread(td);
}
gd->gd_spinlocks));
-#ifdef SMP
#ifdef INVARIANTS
if (td->td_cscount) {
kprintf("Diagnostic: attempt to switch while mastering cpusync: %p\n",
panic("switching while mastering cpusync");
}
#endif
-#endif
/*
* If we had preempted another thread on this cpu, resume the preempted
* Runq is empty, switch to idle to allow it to halt.
*/
ntd = &gd->gd_idlethread;
-#ifdef SMP
if (gd->gd_trap_nesting_level == 0 && panicstr == NULL)
ASSERT_NO_TOKENS_HELD(ntd);
-#endif
cpu_time.cp_msg[0] = 0;
cpu_time.cp_stallpc = 0;
goto haveidle;
*/
cpu_pause();
ntd = &gd->gd_idlethread;
-#ifdef SMP
if (gd->gd_trap_nesting_level == 0 && panicstr == NULL)
ASSERT_NO_TOKENS_HELD(ntd);
/* contention case, do not clear contention mask */
-#endif
/*
* We are going to have to retry but if the current thread is not
if (spinning < 0x7FFFFFFF)
++spinning;
-#ifdef SMP
/*
* lwkt_getalltokens() failed in sorted token mode, we can use
* monitor/mwait in this case.
(gd->gd_reqflags | RQF_SPINNING) &
~RQF_IDLECHECK_WK_MASK);
}
-#endif
/*
* We already checked that td is still scheduled so this should be
void
lwkt_switch_return(thread_t otd)
{
-#ifdef SMP
globaldata_t rgd;
/*
} else {
otd->td_flags &= ~TDF_RUNNING;
}
-#else
- otd->td_flags &= ~TDF_RUNNING;
-#endif
/*
* Final exit validations (see lwp_wait()). Note that otd becomes
++preempt_miss;
return;
}
-#ifdef SMP
if (td->td_cscount) {
++preempt_miss;
return;
++preempt_miss;
return;
}
-#endif
/*
* We don't have to check spinlocks here as they will also bump
* td_critcount.
* critical section). If we do not own the thread there might
* be a race but the target cpu will deal with it.
*/
-#ifdef SMP
if (td->td_gd == mygd) {
_lwkt_enqueue(td);
_lwkt_schedule_post(mygd, td, 1);
} else {
lwkt_send_ipiq3(td->td_gd, lwkt_schedule_remote, td, 0);
}
-#else
- _lwkt_enqueue(td);
- _lwkt_schedule_post(mygd, td, 1);
-#endif
}
crit_exit_gd(mygd);
}
_lwkt_schedule(td);
}
-#ifdef SMP
-
/*
* When scheduled remotely if frame != NULL the IPIQ is being
* run via doreti or an interrupt then preemption can be allowed.
crit_enter_gd(mygd);
DEBUG_PUSH_INFO("lwkt_acquire");
while (td->td_flags & (TDF_RUNNING|TDF_PREEMPT_LOCK)) {
-#ifdef SMP
lwkt_process_ipiq();
-#endif
cpu_lfence();
if (--retry == 0) {
kprintf("lwkt_acquire: stuck: td %p td->td_flags %08x\n",
}
}
-#endif
-
/*
* Generic deschedule. Descheduling threads other then your own should be
* done only in carefully controlled circumstances. Descheduling is
lwkt_deschedule(thread_t td)
{
crit_enter();
-#ifdef SMP
if (td == curthread) {
_lwkt_dequeue(td);
} else {
lwkt_send_ipiq(td->td_gd, (ipifunc1_t)lwkt_deschedule, td);
}
}
-#else
- _lwkt_dequeue(td);
-#endif
crit_exit();
}
void
lwkt_setcpu_self(globaldata_t rgd)
{
-#ifdef SMP
thread_t td = curthread;
if (td->td_gd != rgd) {
TAILQ_INSERT_TAIL(&rgd->gd_tdallq, td, td_allq);
crit_exit_quick(td);
}
-#endif
}
void
lwkt_migratecpu(int cpuid)
{
-#ifdef SMP
globaldata_t rgd;
rgd = globaldata_find(cpuid);
lwkt_setcpu_self(rgd);
-#endif
}
-#ifdef SMP
/*
* Remote IPI for cpu migration (called while in a critical section so we
* do not have to enter another one).
(td->td_lwp->lwp_mpflags & LWP_MP_ONRUNQ) == 0);
_lwkt_enqueue(td);
}
-#endif
struct lwp *
lwkt_preempted_proc(void)
/* NOT REACHED */
}
-#ifdef SMP
-
/*
* Called from debugger/panic on cpus which have been stopped. We must still
* process the IPIQ while stopped, even if we were stopped while in a critical
}
crit_exit_gd(gd);
}
-
-#endif
static int _lwkt_getalltokens_sorted(thread_t td);
-#ifdef SMP
/*
* Acquire the initial mplock
*
if (lwkt_trytoken(&mp_token) == FALSE)
panic("cpu_get_initial_mplock");
}
-#endif
/*
* Return a pool token given an address. Use a prime number to reduce
#include <machine/smp.h>
-#ifdef SMP
-
#ifndef NAPICID
#define NAPICID 256
#endif
}
SYSINIT(cpu_topology, SI_BOOT2_CPU_TOPOLOGY, SI_ORDER_FIRST,
init_cpu_topology, NULL)
-#endif
* are met.
*
* $FreeBSD: src/sys/kern/sys_pipe.c,v 1.60.2.13 2002/08/05 15:05:15 des Exp $
- * $DragonFly: src/sys/kern/sys_pipe.c,v 1.50 2008/09/09 04:06:13 dillon Exp $
*/
/*
CTLFLAG_RW, &pipe_maxcache, 0, "max pipes cached per-cpu");
SYSCTL_INT(_kern_pipe, OID_AUTO, maxbig,
CTLFLAG_RW, &pipe_maxbig, 0, "max number of big pipes");
-#ifdef SMP
static int pipe_delay = 5000; /* 5uS default */
SYSCTL_INT(_kern_pipe, OID_AUTO, delay,
CTLFLAG_RW, &pipe_delay, 0, "SMP delay optimization in ns");
-#endif
#if !defined(NO_PIPE_SYSCTL_STATS)
SYSCTL_INT(_kern_pipe, OID_AUTO, bcache_alloc,
CTLFLAG_RW, &pipe_bcache_alloc, 0, "pipe buffer from pcpu cache");
if (rpipe->pipe_buffer.windex != rpipe->pipe_buffer.rindex)
continue;
-#if defined(SMP) && defined(_RDTSC_SUPPORTED_)
+#ifdef _RDTSC_SUPPORTED_
if (pipe_delay) {
int64_t tsc_target;
int good = 0;
if (segsize > space)
segsize = space;
-#ifdef SMP
/*
* If this is the first loop and the reader is
* blocked, do a preemptive wakeup of the reader.
*/
if ((wpipe->pipe_state & PIPE_WANTR))
wakeup(wpipe);
-#endif
/*
* Transfer segment, which may include a wrap-around.
static void bsd4_exiting(struct lwp *lp, struct proc *);
static void bsd4_uload_update(struct lwp *lp);
static void bsd4_yield(struct lwp *lp);
-
-#ifdef SMP
static void bsd4_need_user_resched_remote(void *dummy);
static int bsd4_batchy_looser_pri_test(struct lwp* lp);
static struct lwp *bsd4_chooseproc_locked_cache_coherent(struct lwp *chklp);
static void bsd4_kick_helper(struct lwp *lp);
-#endif
static struct lwp *bsd4_chooseproc_locked(struct lwp *chklp);
static void bsd4_remrunqueue_locked(struct lwp *lp);
static void bsd4_setrunqueue_locked(struct lwp *lp);
short upri;
struct lwp *uschedcp;
struct lwp *old_uschedcp;
-#ifdef SMP
cpu_node_t *cpunode;
-#endif
};
typedef struct usched_bsd4_pcpu *bsd4_pcpu_t;
static cpumask_t bsd4_curprocmask = -1; /* currently running a user process */
static cpumask_t bsd4_rdyprocmask; /* ready to accept a user process */
static int bsd4_runqcount;
-#ifdef SMP
static volatile int bsd4_scancpu;
-#endif
static struct spinlock bsd4_spin;
static struct usched_bsd4_pcpu bsd4_pcpu[MAXCPU];
static struct sysctl_ctx_list usched_bsd4_sysctl_ctx;
"Print KTR debug information for this pid");
/* Tunning usched_bsd4 - configurable through kern.usched_bsd4.* */
-#ifdef SMP
static int usched_bsd4_smt = 0;
static int usched_bsd4_cache_coherent = 0;
static int usched_bsd4_upri_affinity = 16; /* 32 queues - half-way */
static int usched_bsd4_queue_checks = 5;
static int usched_bsd4_stick_to_level = 0;
static long usched_bsd4_kicks;
-#endif
static int usched_bsd4_rrinterval = (ESTCPUFREQ + 9) / 10;
static int usched_bsd4_decay = 8;
static int usched_bsd4_batch_time = 10;
"cpuid %d, old_pid %d, old_cpuid %d, curr_cpuid %d)",
pid_t pid, int cpuid, pid_t old_pid, int old_cpuid, int curr);
-#ifdef SMP
KTR_INFO(KTR_USCHED_BSD4, usched, batchy_test_false, 0,
"USCHED_BSD4(batchy_looser_pri_test false: pid %d, "
"cpuid %d, verify_mask %lu)",
"USCHED_BSD4(bsd4_setrunqueue found cpu: pid %d, cpuid %d, "
"mask %lu, found_cpuid %d, curr_cpuid %d)",
pid_t pid, int cpuid, cpumask_t mask, int found_cpuid, int curr);
-#endif
KTR_INFO(KTR_USCHED_BSD4, usched, chooseproc, 0,
"USCHED_BSD4(chooseproc: pid %d, old_cpuid %d, curr_cpuid %d)",
pid_t pid, int old_cpuid, int curr);
-#ifdef SMP
KTR_INFO(KTR_USCHED_BSD4, usched, chooseproc_cc, 0,
"USCHED_BSD4(chooseproc_cc: pid %d, old_cpuid %d, curr_cpuid %d)",
pid_t pid, int old_cpuid, int curr);
KTR_INFO(KTR_USCHED_BSD4, usched, sched_thread_no_process_found, 0,
"USCHED_BSD4(sched_thread %d no process found; tmpmask %lu)",
int id, cpumask_t tmpmask);
-#endif
/*
* Initialize the run queues at boot time.
crit_enter_gd(gd);
spin_lock(&bsd4_spin);
-#ifdef SMP
if(usched_bsd4_cache_coherent)
nlp = bsd4_chooseproc_locked_cache_coherent(dd->uschedcp);
else
-#endif
nlp = bsd4_chooseproc_locked(dd->uschedcp);
if (nlp) {
dd->uschedcp = nlp;
dd->rrcount = 0; /* reset round robin */
spin_unlock(&bsd4_spin);
-#ifdef SMP
lwkt_acquire(nlp->lwp_thread);
-#endif
lwkt_schedule(nlp->lwp_thread);
} else {
spin_unlock(&bsd4_spin);
#endif
crit_exit_gd(gd);
}
-#ifdef SMP
/*
* batchy_looser_pri_test() - determine if a process is batchy or not
return 1;
}
-#endif
/*
*
* BSD4_SETRUNQUEUE
{
globaldata_t gd;
bsd4_pcpu_t dd;
-#ifdef SMP
int cpuid;
cpumask_t mask;
cpumask_t tmpmask;
-#endif
/*
* First validate the process state relative to the current cpu.
*/
KKASSERT(dd->uschedcp != lp);
-#ifndef SMP
- /*
- * If we are not SMP we do not have a scheduler helper to kick
- * and must directly activate the process if none are scheduled.
- *
- * This is really only an issue when bootstrapping init since
- * the caller in all other cases will be a user process, and
- * even if released (dd->uschedcp == NULL), that process will
- * kickstart the scheduler when it returns to user mode from
- * the kernel.
- */
- if (dd->uschedcp == NULL) {
- atomic_set_cpumask(&bsd4_curprocmask, gd->gd_cpumask);
- dd->uschedcp = lp;
- dd->upri = lp->lwp_priority;
- lwkt_schedule(lp->lwp_thread);
- crit_exit();
- return;
- }
-#endif
-
-#ifdef SMP
/*
* XXX fixme. Could be part of a remrunqueue/setrunqueue
* operation when the priority is recalculated, so TDF_MIGRATING
*/
if ((lp->lwp_thread->td_flags & TDF_MIGRATING) == 0)
lwkt_giveaway(lp->lwp_thread);
-#endif
/*
* We lose control of lp the moment we release the spinlock after
bsd4_setrunqueue_locked(lp);
lp->lwp_rebal_ticks = sched_ticks;
-#ifdef SMP
/*
* Kick the scheduler helper on one of the other cpu's
* and request a reschedule if appropriate.
else
wakeup(&dd->helper_thread);
}
-#else
- /*
- * Request a reschedule if appropriate.
- */
- spin_unlock(&bsd4_spin);
- if ((dd->upri & ~PPQMASK) > (lp->lwp_priority & ~PPQMASK)) {
- need_user_resched();
- }
-#endif
crit_exit();
}
if ((bsd4_rdyprocmask & CPUMASK(reschedcpu)) &&
(checkpri == 0 ||
(dd->upri & ~PRIMASK) > (lp->lwp_priority & ~PRIMASK))) {
-#ifdef SMP
if (reschedcpu == mycpu->gd_cpuid) {
spin_unlock(&bsd4_spin);
need_user_resched();
bsd4_need_user_resched_remote,
NULL);
}
-#else
- spin_unlock(&bsd4_spin);
- need_user_resched();
-#endif
} else {
spin_unlock(&bsd4_spin);
}
cpumask = mycpu->gd_cpumask;
-#ifdef SMP
again:
-#endif
if (rtqbits) {
pri = bsfl(rtqbits);
q = &bsd4_rtqueues[pri];
lp = TAILQ_FIRST(q);
KASSERT(lp, ("chooseproc: no lwp on busy queue"));
-#ifdef SMP
while ((lp->lwp_cpumask & cpumask) == 0) {
lp = TAILQ_NEXT(lp, lwp_procq);
if (lp == NULL) {
goto again;
}
}
-#endif
/*
* If the passed lwp <chklp> is reasonably close to the selected
return(NULL);
}
-#ifdef SMP
/*
* If the chosen lwp does not reside on this cpu spend a few
* cycles looking for a better candidate at the same priority level.
lp = chklp;
}
}
-#endif
KTR_COND_LOG(usched_chooseproc,
lp->lwp_proc->p_pid == usched_bsd4_pid_debug,
return lp;
}
-#ifdef SMP
/*
* chooseproc() - with a cache coherence heuristic. Try to pull a process that
* has its home on the current CPU> If the process doesn't have its home here
wakeup_mycpu(&dd->helper_thread);
}
-#endif
-
/*
* bsd4_remrunqueue_locked() removes a given process from the run queue
* that it is on, clearing the queue busy bit if it becomes empty.
*which |= 1 << pri;
}
-#ifdef SMP
-
/*
* For SMP systems a user scheduler helper thread is created for each
* cpu and is used to allow one cpu to wakeup another for the purposes of
}
SYSINIT(uschedtd, SI_BOOT2_USCHED, SI_ORDER_SECOND,
sched_thread_cpu_init, NULL)
-
-#else /* No SMP options - just add the configurable parameters to sysctl */
-
-static void
-sched_sysctl_tree_init(void)
-{
- sysctl_ctx_init(&usched_bsd4_sysctl_ctx);
- usched_bsd4_sysctl_tree =
- SYSCTL_ADD_NODE(&usched_bsd4_sysctl_ctx,
- SYSCTL_STATIC_CHILDREN(_kern), OID_AUTO,
- "usched_bsd4", CTLFLAG_RD, 0, "");
-
- /* usched_bsd4 sysctl configurable parameters */
- SYSCTL_ADD_INT(&usched_bsd4_sysctl_ctx,
- SYSCTL_CHILDREN(usched_bsd4_sysctl_tree),
- OID_AUTO, "rrinterval", CTLFLAG_RW,
- &usched_bsd4_rrinterval, 0, "");
- SYSCTL_ADD_INT(&usched_bsd4_sysctl_ctx,
- SYSCTL_CHILDREN(usched_bsd4_sysctl_tree),
- OID_AUTO, "decay", CTLFLAG_RW,
- &usched_bsd4_decay, 0, "Extra decay when not running");
- SYSCTL_ADD_INT(&usched_bsd4_sysctl_ctx,
- SYSCTL_CHILDREN(usched_bsd4_sysctl_tree),
- OID_AUTO, "batch_time", CTLFLAG_RW,
- &usched_bsd4_batch_time, 0, "Min batch counter value");
-}
-SYSINIT(uschedtd, SI_BOOT2_USCHED, SI_ORDER_SECOND,
- sched_sysctl_tree_init, NULL)
-#endif
struct usched_dfly_pcpu {
struct spinlock spin;
-#ifdef SMP
struct thread helper_thread;
-#else
- struct thread helper_thread_UNUSED; /* field unused */
-#endif
short unusde01;
short upri;
int uload;
int runqcount;
int cpuid;
cpumask_t cpumask;
-#ifdef SMP
cpu_node_t *cpunode;
-#endif
};
typedef struct usched_dfly_pcpu *dfly_pcpu_t;
static void dfly_exiting(struct lwp *lp, struct proc *);
static void dfly_uload_update(struct lwp *lp);
static void dfly_yield(struct lwp *lp);
-#ifdef SMP
static void dfly_changeqcpu_locked(struct lwp *lp,
dfly_pcpu_t dd, dfly_pcpu_t rdd);
static dfly_pcpu_t dfly_choose_best_queue(struct lwp *lp);
static dfly_pcpu_t dfly_choose_worst_queue(dfly_pcpu_t dd);
static dfly_pcpu_t dfly_choose_queue_simple(dfly_pcpu_t dd, struct lwp *lp);
-#endif
-
-#ifdef SMP
static void dfly_need_user_resched_remote(void *dummy);
-#endif
static struct lwp *dfly_chooseproc_locked(dfly_pcpu_t rdd, dfly_pcpu_t dd,
struct lwp *chklp, int worst);
static void dfly_remrunqueue_locked(dfly_pcpu_t dd, struct lwp *lp);
*/
static cpumask_t dfly_curprocmask = -1; /* currently running a user process */
static cpumask_t dfly_rdyprocmask; /* ready to accept a user process */
-#ifdef SMP
static volatile int dfly_scancpu;
-#endif
static volatile int dfly_ucount; /* total running on whole system */
static struct usched_dfly_pcpu dfly_pcpu[MAXCPU];
static struct sysctl_ctx_list usched_dfly_sysctl_ctx;
* 0x40 choose current cpu for forked process
* 0x80 choose random cpu for forked process (default)
*/
-#ifdef SMP
static int usched_dfly_smt = 0;
static int usched_dfly_cache_coherent = 0;
static int usched_dfly_weight1 = 200; /* keep thread on current cpu */
static int usched_dfly_weight3 = 40; /* number of threads on queue */
static int usched_dfly_weight4 = 160; /* availability of idle cores */
static int usched_dfly_features = 0x8F; /* allow pulls */
-#endif
static int usched_dfly_fast_resched = 0;/* delta priority / resched */
static int usched_dfly_swmask = ~PPQMASK; /* allow pulls */
static int usched_dfly_rrinterval = (ESTCPUFREQ + 9) / 10;
{
globaldata_t gd;
dfly_pcpu_t dd;
-#ifdef SMP
dfly_pcpu_t rdd;
-#endif
thread_t td;
int force_resched;
* (if a reschedule was not requested we want to move this
* step after the uschedcp tests).
*/
-#ifdef SMP
if (force_resched &&
(usched_dfly_features & 0x08) &&
(rdd = dfly_choose_best_queue(lp)) != dd) {
dd = &dfly_pcpu[gd->gd_cpuid];
continue;
}
-#endif
/*
* Either no reschedule was requested or the best queue was
spin_unlock(&dd->spin);
break;
}
-#ifdef SMP
/*
* We are not the current lwp, figure out the best cpu
* to run on (our current cpu will be given significant
dd = &dfly_pcpu[gd->gd_cpuid];
continue;
}
-#endif
/*
* We cannot become the current lwp, place the lp on the
dd->rrcount = 0; /* reset round robin */
#endif
spin_unlock(&dd->spin);
-#ifdef SMP
lwkt_acquire(nlp->lwp_thread);
-#endif
lwkt_schedule(nlp->lwp_thread);
} else {
spin_unlock(&dd->spin);
*/
KKASSERT(rdd->uschedcp != lp);
-#ifndef SMP
- /*
- * If we are not SMP we do not have a scheduler helper to kick
- * and must directly activate the process if none are scheduled.
- *
- * This is really only an issue when bootstrapping init since
- * the caller in all other cases will be a user process, and
- * even if released (rdd->uschedcp == NULL), that process will
- * kickstart the scheduler when it returns to user mode from
- * the kernel.
- *
- * NOTE: On SMP we can't just set some other cpu's uschedcp.
- */
- if (rdd->uschedcp == NULL) {
- spin_lock(&rdd->spin);
- if (rdd->uschedcp == NULL) {
- atomic_set_cpumask(&dfly_curprocmask, 1);
- rdd->uschedcp = lp;
- rdd->upri = lp->lwp_priority;
- spin_unlock(&rdd->spin);
- lwkt_schedule(lp->lwp_thread);
- return;
- }
- spin_unlock(&rdd->spin);
- }
-#endif
-
-#ifdef SMP
/*
* Ok, we have to setrunqueue some target cpu and request a reschedule
* if necessary.
dfly_changeqcpu_locked(lp, dd, rdd);
spin_unlock(&dd->spin);
}
-#endif
dfly_setrunqueue_dd(rdd, lp);
}
-#ifdef SMP
-
/*
* Change qcpu to rdd->cpuid. The dd the lp is CURRENTLY on must be
* spin-locked on-call. rdd does not have to be.
}
}
-#endif
-
/*
* Place lp on rdd's runqueue. Nothing is locked on call. This function
* also performs all necessary ancillary notification actions.
static void
dfly_setrunqueue_dd(dfly_pcpu_t rdd, struct lwp *lp)
{
-#ifdef SMP
globaldata_t rgd;
/*
spin_unlock(&rdd->spin);
lwkt_send_ipiq(rgd, dfly_need_user_resched_remote, NULL);
}
-#else
- /*
- * Request a reschedule if appropriate.
- */
- spin_lock(&rdd->spin);
- dfly_setrunqueue_locked(rdd, lp);
- spin_unlock(&rdd->spin);
- if ((rdd->upri & ~PPQMASK) > (lp->lwp_priority & ~PPQMASK)) {
- need_user_resched();
- }
-#endif
}
/*
dfly_schedulerclock(struct lwp *lp, sysclock_t period, sysclock_t cpstamp)
{
globaldata_t gd = mycpu;
-#ifdef SMP
dfly_pcpu_t dd = &dfly_pcpu[gd->gd_cpuid];
-#endif
/*
* Spinlocks also hold a critical section so there should not be
* likely to be able to remain in place. Hopefully then any pairings,
* if applicable, migrate to where these threads are.
*/
-#ifdef SMP
if ((usched_dfly_features & 0x04) &&
((u_int)sched_ticks & 7) == 0 &&
(u_int)sched_ticks / 8 % ncpus == gd->gd_cpuid) {
spin_unlock(&dd->spin);
}
}
-#endif
}
/*
(checkpri == 0 ||
(rdd->upri & ~PRIMASK) >
(lp->lwp_priority & ~PRIMASK))) {
-#ifdef SMP
if (rcpu == mycpu->gd_cpuid) {
spin_unlock(&rdd->spin);
need_user_resched();
dfly_need_user_resched_remote,
NULL);
}
-#else
- spin_unlock(&rdd->spin);
- need_user_resched();
-#endif
} else {
spin_unlock(&rdd->spin);
}
return lp;
}
-#ifdef SMP
-
/*
* USED TO PUSH RUNNABLE LWPS TO THE LEAST LOADED CPU.
*
}
}
-#endif
-
/*
* dfly_remrunqueue_locked() removes a given process from the run queue
* that it is on, clearing the queue busy bit if it becomes empty.
*which |= 1 << pri;
}
-#ifdef SMP
-
/*
* For SMP systems a user scheduler helper thread is created for each
* cpu and is used to allow one cpu to wakeup another for the purposes of
}
#endif
-#endif
-
/*
* Setup the queues and scheduler helpers (scheduler helpers are SMP only).
* Note that curprocmask bit 0 has already been cleared by rqinit() and
{
int i;
int j;
-#ifdef SMP
int cpuid;
int smt_not_supported = 0;
int cache_coherent_not_supported = 0;
-#endif
if (bootverbose)
kprintf("Start scheduler helpers on cpus:\n");
continue;
spin_init(&dd->spin);
-#ifdef SMP
dd->cpunode = get_cpu_node_by_cpuid(i);
-#endif
dd->cpuid = i;
dd->cpumask = CPUMASK(i);
for (j = 0; j < NQS; j++) {
}
atomic_clear_cpumask(&dfly_curprocmask, 1);
-#ifdef SMP
if (dd->cpunode == NULL) {
smt_not_supported = 1;
cache_coherent_not_supported = 1;
lwkt_create(dfly_helper_thread, NULL, NULL, &dd->helper_thread,
0, i, "usched %d", i);
-#endif
/*
* Allow user scheduling on the target cpu. cpu #0 has already
OID_AUTO, "decay", CTLFLAG_RW,
&usched_dfly_decay, 0, "Extra decay when not running");
-#ifdef SMP
/* Add enable/disable option for SMT scheduling if supported */
if (smt_not_supported) {
usched_dfly_smt = 0;
"paremter hw.cpu_topology.level_description");
#endif
}
-#endif /* SMP */
}
SYSINIT(uschedtd, SI_BOOT2_USCHED, SI_ORDER_SECOND,
usched_dfly_cpu_init, NULL)
* 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: src/sys/kern/usched_dummy.c,v 1.9 2008/04/21 15:24:46 dillon Exp $
*/
#include <sys/param.h>
dd->uschedcp = lp;
atomic_set_cpumask(&dummy_curprocmask, gd->gd_cpumask);
spin_unlock(&dummy_spin);
-#ifdef SMP
lwkt_acquire(lp->lwp_thread);
-#endif
lwkt_schedule(lp->lwp_thread);
}
}
++dummy_runqcount;
TAILQ_INSERT_TAIL(&dummy_runq, lp, lwp_procq);
atomic_set_int(&lp->lwp_mpflags, LWP_MP_ONRUNQ);
-#ifdef SMP
lwkt_giveaway(lp->lwp_thread);
-#endif
/* lp = TAILQ_FIRST(&dummy_runq); */
*
* MPSAFE
*/
-#ifdef SMP
-
static void
dummy_sched_thread(void *dummy)
{
dd->uschedcp = lp;
atomic_set_cpumask(&dummy_curprocmask, cpumask);
spin_unlock(&dummy_spin);
-#ifdef SMP
lwkt_acquire(lp->lwp_thread);
-#endif
lwkt_schedule(lp->lwp_thread);
} else {
spin_unlock(&dummy_spin);
}
SYSINIT(uschedtd, SI_BOOT2_USCHED, SI_ORDER_SECOND,
dummy_sched_thread_cpu_init, NULL)
-
-#endif
-
*
* @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94
* $FreeBSD: src/sys/kern/vfs_vnops.c,v 1.87.2.13 2002/12/29 18:19:53 dillon Exp $
- * $DragonFly: src/sys/kern/vfs_vnops.c,v 1.58 2008/06/28 17:59:49 dillon Exp $
*/
#include <sys/param.h>
static __inline off_t
vn_poll_fpf_offset(struct file *fp)
{
-#if defined(__x86_64__) || !defined(SMP)
+#if defined(__x86_64__)
return(fp->f_offset);
#else
off_t off = vn_get_fpf_offset(fp);
#if !defined(__i386__) || defined(ALTQ_NOPCC)
machclk_usepcc = 0;
-#elif defined(__DragonFly__) && defined(SMP)
+#elif defined(__DragonFly__)
machclk_usepcc = 0;
#elif defined(__i386__)
/* check if TSC is available */
/* $KAME: if_altq.h,v 1.11 2003/07/10 12:07:50 kjc Exp $ */
-/* $DragonFly: src/sys/net/altq/if_altq.h,v 1.4 2008/05/14 11:59:23 sephe Exp $ */
/*
* Copyright (C) 1997-2003
int altq_started; /* ifnet.if_start interlock */
};
-#ifdef SMP
#define ALTQ_ASSERT_LOCKED(ifq) ASSERT_SERIALIZED(&(ifq)->altq_lock)
#define ALTQ_LOCK_INIT(ifq) lwkt_serialize_init(&(ifq)->altq_lock)
#define ALTQ_LOCK(ifq) lwkt_serialize_adaptive_enter(&(ifq)->altq_lock)
#define ALTQ_UNLOCK(ifq) lwkt_serialize_exit(&(ifq)->altq_lock)
-#else
-#define ALTQ_ASSERT_LOCKED(ifq) ((void)0) /* XXX */
-#define ALTQ_LOCK_INIT(ifq) ((void)0)
-#define ALTQ_LOCK(ifq) crit_enter()
-#define ALTQ_UNLOCK(ifq) crit_exit()
-#endif
#ifdef _KERNEL
IF_START_KTR_STRING, IF_START_KTR_ARGS);
KTR_INFO(KTR_IF_START, if_start, contend_sched, 3,
IF_START_KTR_STRING, IF_START_KTR_ARGS);
-#ifdef SMP
KTR_INFO(KTR_IF_START, if_start, chase_sched, 4,
IF_START_KTR_STRING, IF_START_KTR_ARGS);
-#endif
#define logifstart(name, arg) KTR_LOG(if_start_ ## name, arg)
TAILQ_HEAD(, ifg_group) ifg_head = TAILQ_HEAD_INITIALIZER(ifg_head);
static void
if_start_schedule(struct ifnet *ifp)
{
-#ifdef SMP
int cpu;
cpu = ifp->if_start_cpuid(ifp);
if (cpu != mycpuid)
lwkt_send_ipiq(globaldata_find(cpu), if_start_ipifunc, ifp);
else
-#endif
if_start_ipifunc(ifp);
}
lwkt_replymsg(lmsg, 0); /* reply ASAP */
crit_exit();
-#ifdef SMP
if (mycpuid != ifp->if_start_cpuid(ifp)) {
/*
* If the ifnet is still up, we need to
goto check;
}
}
-#endif
if (ifp->if_flags & IFF_UP) {
ifnet_serialize_tx(ifp); /* XXX try? */
}
ifnet_deserialize_tx(ifp);
}
-#ifdef SMP
check:
-#endif
if (if_start_need_schedule(ifq, running)) {
crit_enter();
if (lmsg->ms_flags & MSGF_DONE) { /* XXX necessary? */
KASSERT((num > 0 && num <= NELEM(netisrs)),
("schednetisr: bad isr %d", num));
KKASSERT(netisrs[num].ni_handler != NULL);
-#ifdef SMP
if (mycpu->gd_cpuid != 0) {
lwkt_send_ipiq(globaldata_find(0),
schednetisr_remote, (void *)(intptr_t)num);
schednetisr_remote((void *)(intptr_t)num);
crit_exit();
}
-#else
- crit_enter();
- schednetisr_remote((void *)(intptr_t)num);
- crit_exit();
-#endif
}
-#ifdef SMP
-
static void
netisr_barrier_dispatch(netmsg_t nmsg)
{
lwkt_replymsg(&nmsg->lmsg, 0);
}
-#endif
-
struct netisr_barrier *
netisr_barrier_create(void)
{
void
netisr_barrier_set(struct netisr_barrier *br)
{
-#ifdef SMP
volatile cpumask_t other_cpumask;
int i, cur_cpuid;
if (other_cpumask != 0)
tsleep(&other_cpumask, PINTERLOCKED, "nbrset", 0);
}
-#endif
br->br_isset = 1;
}
void
netisr_barrier_rem(struct netisr_barrier *br)
{
-#ifdef SMP
int i, cur_cpuid;
KKASSERT(&curthread->td_msgport == netisr_portfn(0));
if (done & NETISR_BR_WAITDONE)
wakeup(&msg->br_done);
}
-#endif
br->br_isset = 0;
}
return (r);
}
-#ifdef SMP
struct netmsg_hashlookup {
struct netmsg_base base;
struct inpcb **nm_pinp;
}
#endif /* PF_SOCKET_LOOKUP_DOMSG */
-#endif /* SMP */
-
int
pf_socket_lookup(int direction, struct pf_pdesc *pd)
{
u_int16_t sport, dport;
struct inpcbinfo *pi;
struct inpcb *inp;
-#ifdef SMP
struct netmsg_hashlookup *msg = NULL;
#ifdef PF_SOCKET_LOOKUP_DOMSG
struct netmsg_hashlookup msg0;
#endif
-#endif
int pi_cpu = 0;
if (pd == NULL)
pi_cpu = tcp_addrcpu(saddr->v4.s_addr, sport, daddr->v4.s_addr, dport);
pi = &tcbinfo[pi_cpu];
-#ifdef SMP
/*
* Our netstack runs lockless on MP systems
* (only for TCP connections at the moment).
return -1;
#endif /* PF_SOCKET_LOOKUP_DOMSG */
}
-#endif /* SMP */
break;
case IPPROTO_UDP:
if (pd->hdr.udp == NULL)
switch (pd->af) {
#ifdef INET6
case AF_INET6:
-#ifdef SMP
/*
* Query other CPU, second part
*
*
* Use some switch/case magic to avoid code duplication.
*/
- if (msg == NULL)
-#endif /* SMP */
- {
+ if (msg == NULL) {
inp = in6_pcblookup_hash(pi, &saddr->v6, sport,
&daddr->v6, dport, INPLOOKUP_WILDCARD, NULL);
/* FALLTHROUGH if SMP and on other CPU */
#endif /* INET6 */
case AF_INET:
-#ifdef SMP
if (msg != NULL) {
lwkt_domsg(netisr_portfn(pi_cpu),
&msg->base.lmsg, 0);
} else
-#endif /* SMP */
{
inp = in_pcblookup_hash(pi, saddr->v4, sport, daddr->v4,
dport, INPLOOKUP_WILDCARD, NULL);
#endif
static struct rtstatistics rtstatistics_percpu[MAXCPU];
-#ifdef SMP
#define rtstat rtstatistics_percpu[mycpuid]
-#else
-#define rtstat rtstatistics_percpu[0]
-#endif
struct radix_node_head *rt_tables[MAXCPU][AF_MAX+1];
struct lwkt_port *rt_ports[MAXCPU];
static void rtinit_rtrequest_callback(int, int, struct rt_addrinfo *,
struct rtentry *, void *);
-#ifdef SMP
static void rtredirect_msghandler(netmsg_t msg);
static void rtrequest1_msghandler(netmsg_t msg);
-#endif
static void rtsearch_msghandler(netmsg_t msg);
static void rtmask_add_msghandler(netmsg_t msg);
/*
* Routing statistics.
*/
-#ifdef SMP
static int
sysctl_rtstatistics(SYSCTL_HANDLER_ARGS)
{
}
SYSCTL_PROC(_net_route, OID_AUTO, stats, (CTLTYPE_OPAQUE|CTLFLAG_RW),
0, 0, sysctl_rtstatistics, "S,rtstatistics", "Routing statistics");
-#else
-SYSCTL_STRUCT(_net_route, OID_AUTO, stats, CTLFLAG_RW, &rtstat, rtstatistics,
-"Routing statistics");
-#endif
/*
* Packet routing routines.
return error;
}
-#ifdef SMP
-
struct netmsg_rtredirect {
struct netmsg_base base;
struct sockaddr *dst;
struct sockaddr *src;
};
-#endif
-
/*
* Force a routing table entry to the specified
* destination to go through the given gateway.
{
struct rt_addrinfo rtinfo;
int error;
-#ifdef SMP
struct netmsg_rtredirect msg;
netmsg_init(&msg.base, NULL, &curthread->td_msgport,
msg.flags = flags;
msg.src = src;
error = lwkt_domsg(rtable_portfn(0), &msg.base.lmsg, 0);
-#else
- error = rtredirect_oncpu(dst, gateway, netmask, flags, src);
-#endif
bzero(&rtinfo, sizeof(struct rt_addrinfo));
rtinfo.rti_info[RTAX_DST] = dst;
rtinfo.rti_info[RTAX_GATEWAY] = gateway;
rt_missmsg(RTM_REDIRECT, &rtinfo, flags, error);
}
-#ifdef SMP
-
static void
rtredirect_msghandler(netmsg_t msg)
{
lwkt_replymsg(&msg->lmsg, 0);
}
-#endif
-
/*
* Routing table ioctl interface.
*/
return rtrequest1_global(req, &rtinfo, NULL, NULL);
}
-#ifdef SMP
-
struct netmsg_rtq {
struct netmsg_base base;
int req;
void *arg;
};
-#endif
-
int
rtrequest1_global(int req, struct rt_addrinfo *rtinfo,
rtrequest1_callback_func_t callback, void *arg)
{
int error;
-#ifdef SMP
struct netmsg_rtq msg;
netmsg_init(&msg.base, NULL, &curthread->td_msgport,
msg.callback = callback;
msg.arg = arg;
error = lwkt_domsg(rtable_portfn(0), &msg.base.lmsg, 0);
-#else
- struct rtentry *rt = NULL;
-
- error = rtrequest1(req, rtinfo, &rt);
- if (rt)
- --rt->rt_refcnt;
- if (callback)
- callback(req, error, rtinfo, rt, arg);
-#endif
return (error);
}
* are supposed to be identical on each cpu, an error occuring later in the
* message chain is considered system-fatal.
*/
-#ifdef SMP
-
static void
rtrequest1_msghandler(netmsg_t msg)
{
}
}
-#endif
-
int
rtrequest1(int req, struct rt_addrinfo *rtinfo, struct rtentry **ret_nrt)
{
*
* @(#)if_ether.c 8.1 (Berkeley) 6/10/93
* $FreeBSD: src/sys/netinet/if_ether.c,v 1.64.2.23 2003/04/11 07:23:15 fjoe Exp $
- * $DragonFly: src/sys/netinet/if_ether.c,v 1.59 2008/11/22 11:03:35 sephe Exp $
*/
/*
}
}
-#ifdef SMP
-
struct netmsg_arp_update {
struct netmsg_base base;
struct mbuf *m;
static void arp_update_msghandler(netmsg_t msg);
-#endif
-
/*
* Called from arpintr() - this routine is run from a single cpu.
*/
struct in_ifaddr *ia = NULL;
struct sockaddr sa;
struct in_addr isaddr, itaddr, myaddr;
-#ifdef SMP
struct netmsg_arp_update msg;
-#endif
uint8_t *enaddr = NULL;
int op;
int req_len;
return;
}
-#ifdef SMP
netmsg_init(&msg.base, NULL, &curthread->td_msgport,
0, arp_update_msghandler);
msg.m = m;
msg.saddr = isaddr.s_addr;
msg.create = (itaddr.s_addr == myaddr.s_addr);
lwkt_domsg(rtable_portfn(0), &msg.base.lmsg, 0);
-#else
- arp_update_oncpu(m, isaddr.s_addr, (itaddr.s_addr == myaddr.s_addr),
- RTL_REPORTMSG, TRUE);
-#endif
reply:
if (op != ARPOP_REQUEST) {
m_freem(m);
ifp->if_output(ifp, m, &sa, NULL);
}
-#ifdef SMP
-
static void
arp_update_msghandler(netmsg_t msg)
{
lwkt_replymsg(&rmsg->base.lmsg, 0);
}
-#endif /* SMP */
-
#endif /* INET */
/*
lwkt_reltoken(&div_token);
}
-#ifdef SMP
-
static void
div_packet_handler(netmsg_t msg)
{
/* no reply, msg embedded in mbuf */
}
-#endif /* SMP */
-
static void
divert_packet(struct mbuf *m, int incoming)
{
port = divinfo->port;
KASSERT(port != 0, ("%s: port=0", __func__));
-#ifdef SMP
if (mycpuid != 0) {
struct netmsg_packet *nmp;
} else {
div_packet(m, incoming, port);
}
-#else
- div_packet(m, incoming, port);
-#endif
}
/*
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/netinet/ip_flow.c,v 1.9.2.2 2001/11/04 17:35:31 luigi Exp $
- * $DragonFly: src/sys/netinet/ip_flow.c,v 1.27 2008/10/28 07:09:26 sephe Exp $
*/
#include <sys/param.h>
void
ipflow_slowtimo(void)
{
-#ifdef SMP
cpumask_t mask = 0;
int i;
mask &= smp_active_mask;
if (mask != 0)
lwkt_send_ipiq_mask(mask, ipflow_timo_ipi, NULL);
-#else
- if (ipflow_inuse)
- ipflow_timo_ipi(NULL);
-#endif
}
void
u_long in_ifaddrhmask; /* mask for hash table */
struct ip_stats ipstats_percpu[MAXCPU];
-#ifdef SMP
+
static int
sysctl_ipstats(SYSCTL_HANDLER_ARGS)
{
}
SYSCTL_PROC(_net_inet_ip, IPCTL_STATS, stats, (CTLTYPE_OPAQUE | CTLFLAG_RW),
0, 0, sysctl_ipstats, "S,ip_stats", "IP statistics");
-#else
-SYSCTL_STRUCT(_net_inet_ip, IPCTL_STATS, stats, CTLFLAG_RW,
- &ipstat, ip_stats, "IP statistics");
-#endif
/* Packet reassembly stuff */
#define IPREASS_NHASH_LOG2 6
{
struct protosw *pr;
int i;
-#ifdef SMP
int cpu;
-#endif
/*
* Make sure we can handle a reasonable number of fragments but
* Initialize IP statistics counters for each CPU.
*
*/
-#ifdef SMP
for (cpu = 0; cpu < ncpus; ++cpu) {
bzero(&ipstats_percpu[cpu], sizeof(struct ip_stats));
}
-#else
- bzero(&ipstat, sizeof(struct ip_stats));
-#endif
netisr_register(NETISR_IP, ip_input_handler, ip_cpufn_in);
netisr_register_hashcheck(NETISR_IP, ip_hashcheck);
#ifdef _KERNEL
-#if defined(SMP)
#define ipstat ipstats_percpu[mycpuid]
-#else /* !SMP */
-#define ipstat ipstats_percpu[0]
-#endif
extern struct ip_stats ipstats_percpu[MAXCPU];
static void tcp_notify (struct inpcb *, int);
struct tcp_stats tcpstats_percpu[MAXCPU];
-#ifdef SMP
+
static int
sysctl_tcpstats(SYSCTL_HANDLER_ARGS)
{
}
SYSCTL_PROC(_net_inet_tcp, TCPCTL_STATS, stats, (CTLTYPE_OPAQUE | CTLFLAG_RW),
0, 0, sysctl_tcpstats, "S,tcp_stats", "TCP statistics");
-#else
-SYSCTL_STRUCT(_net_inet_tcp, TCPCTL_STATS, stats, CTLFLAG_RW,
- &tcpstat, tcp_stats, "TCP statistics");
-#endif
/*
* Target size of TCP PCB hash tables. Must be a power of two.
/*
* Initialize TCP statistics counters for each CPU.
*/
-#ifdef SMP
for (cpu = 0; cpu < ncpus; ++cpu) {
bzero(&tcpstats_percpu[cpu], sizeof(struct tcp_stats));
}
-#else
- bzero(&tcpstat, sizeof(struct tcp_stats));
-#endif
syncache_init();
netisr_register_rollup(tcp_willblock);
return (tcp_close(tp));
}
-#ifdef SMP
-
struct netmsg_listen_detach {
struct netmsg_base base;
struct tcpcb *nm_tp;
lwkt_replymsg(&nmsg->base.lmsg, 0);
}
-#endif
-
/*
* Close a TCP control block:
* discard all space held by the tcp
const boolean_t isipv6 = FALSE;
#endif
-#ifdef SMP
/*
* INP_WILDCARD_MP indicates that listen(2) has been called on
* this socket. This implies:
inp->inp_flags &= ~INP_WILDCARD_MP;
}
-#endif
KKASSERT(tp->t_state != TCPS_TERMINATING);
tp->t_state = TCPS_TERMINATING;
kfree(marker, M_TEMP);
}
-#ifdef SMP
struct netmsg_tcp_drain {
struct netmsg_base base;
struct inpcbhead *nm_head;
tcp_drain_oncpu(nm->nm_head);
lwkt_replymsg(&nm->base.lmsg, 0);
}
-#endif
void
tcp_drain(void)
{
-#ifdef SMP
int cpu;
-#endif
if (!do_tcpdrain)
return;
* where we're really low on mbufs, this is potentially
* useful.
*/
-#ifdef SMP
for (cpu = 0; cpu < ncpus2; cpu++) {
struct netmsg_tcp_drain *nm;
lwkt_sendmsg(netisr_portfn(cpu), &nm->base.lmsg);
}
}
-#else
- tcp_drain_oncpu(&tcbinfo[0].pcblisthead);
-#endif
}
/*
}
#endif /* INET6 */
-#ifdef SMP
-
struct netmsg_inswildcard {
struct netmsg_base base;
struct inpcb *nm_inp;
lwkt_replymsg(&nm->base.lmsg, 0);
}
-#endif
-
/*
* Prepare to accept connections.
*/
int error = 0;
struct inpcb *inp;
struct tcpcb *tp;
-#ifdef SMP
struct netmsg_inswildcard nm;
-#endif
COMMON_START(so, inp, 0);
tp->t_flags |= TF_LISTEN;
tp->tt_msg = NULL; /* Catch any invalid timer usage */
-#ifdef SMP
if (ncpus > 1) {
/*
* We have to set the flag because we can't have other cpus
nm.nm_inp = inp;
lwkt_domsg(netisr_portfn(1), &nm.base.lmsg, 0);
}
-#endif
in_pcbinswildcardhash(inp);
COMMON_END(PRU_LISTEN);
}
int error = 0;
struct inpcb *inp;
struct tcpcb *tp;
-#ifdef SMP
struct netmsg_inswildcard nm;
-#endif
COMMON_START(so, inp, 0);
tp->t_flags |= TF_LISTEN;
tp->tt_msg = NULL; /* Catch any invalid timer usage */
-#ifdef SMP
if (ncpus > 1) {
/*
* We have to set the flag because we can't have other cpus
nm.nm_inp = inp;
lwkt_domsg(netisr_portfn(1), &nm.base.lmsg, 0);
}
-#endif
in_pcbinswildcardhash(inp);
COMMON_END(PRU_LISTEN);
}
struct inpcb *inp;
struct tcpcb *tp;
int error, calc_laddr = 1;
-#ifdef SMP
lwkt_port_t port;
-#endif
COMMON_START(so, inp, 0);
}
KKASSERT(inp->inp_socket == so);
-#ifdef SMP
port = tcp_addrport(sin->sin_addr.s_addr, sin->sin_port,
(inp->inp_laddr.s_addr ?
inp->inp_laddr.s_addr : if_sin->sin_addr.s_addr),
/* msg invalid now */
return;
}
-#else
- KKASSERT(so->so_port == &curthread->td_msgport);
-#endif
error = tcp_connect_oncpu(tp, msg->connect.nm_flags,
msg->connect.nm_m, sin, if_sin);
msg->connect.nm_m = NULL;
struct inpcb *inp;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
struct in6_addr *addr6;
-#ifdef SMP
lwkt_port_t port;
-#endif
int error;
COMMON_START(so, inp, 0);
if (error)
goto out;
-#ifdef SMP
port = tcp6_addrport(); /* XXX hack for now, always cpu0 */
if (port != &curthread->td_msgport) {
/* msg invalid now */
return;
}
-#endif
error = tcp6_connect_oncpu(tp, msg->connect.nm_flags,
&msg->connect.nm_m, sin6, addr6);
/* nm_m may still be intact */
*
* @(#)tcp_var.h 8.4 (Berkeley) 5/24/95
* $FreeBSD: src/sys/netinet/tcp_var.h,v 1.56.2.13 2003/02/03 02:34:07 hsu Exp $
- * $DragonFly: src/sys/netinet/tcp_var.h,v 1.42 2008/10/27 02:56:30 sephe Exp $
*/
#ifndef _NETINET_TCP_VAR_H_
#ifdef _KERNEL
-#if defined(SMP)
#define tcpstat tcpstats_percpu[mycpuid]
-#else
-#define tcpstat tcpstats_percpu[0]
-#endif
struct sockopt;
static void
udp_rtchange(struct inpcb *inp, int err)
{
-#ifdef SMP
/* XXX Nuke this, once UDP inpcbs are CPU localized */
if (inp->inp_route.ro_rt && inp->inp_route.ro_rt->rt_cpuid == mycpuid) {
rtfree(inp->inp_route.ro_rt);
* output is attempted.
*/
}
-#else
- in_rtchange(inp, err);
-#endif
}
void
port = udp_addrport(sin->sin_addr.s_addr, sin->sin_port,
inp->inp_laddr.s_addr, inp->inp_lport);
-#ifdef SMP
if (port != &curthread->td_msgport) {
#ifdef notyet
struct route *ro = &inp->inp_route;
panic("UDP activity should only be in netisr0");
#endif
}
-#endif
KKASSERT(port == &curthread->td_msgport);
error = udp_connect_oncpu(so, td, sin, if_sin);
out:
* 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: src/sys/netproto/mpls/mpls_input.c,v 1.4 2008/09/24 14:26:39 sephe Exp $
*/
#include <sys/globaldata.h>
void
mpls_init(void)
{
-#ifdef SMP
int cpu;
-#endif
/*
* Initialize MPLS statistics counters for each CPU.
*
*/
-#ifdef SMP
for (cpu = 0; cpu < ncpus; ++cpu) {
bzero(&mplsstats_percpu[cpu], sizeof(struct mpls_stats));
}
-#else
- bzero(&mplsstat, sizeof(struct mpls_stats));
-#endif
netisr_register(NETISR_MPLS, mpls_input_handler, mpls_cpufn);
}
* 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: src/sys/netproto/mpls/mpls_var.h,v 1.2 2008/08/05 15:11:32 nant Exp $
*/
#ifndef _NETMPLS_MPLS_VAR_H_
#ifdef _KERNEL
-#if defined(SMP)
#define mplsstat mplsstats_percpu[mycpuid]
-#else /* !SMP */
-#define mplsstat mplsstats_percpu[0]
-#endif
extern struct mpls_stats mplsstats_percpu[MAXCPU];
/* convert an absolute IRQ# into ipending index */
#define IRQ_LIDX(irq_num) ((irq_num) >> 5)
-#ifdef SMP
#define MPLOCKED lock ;
-#else
-#define MPLOCKED
-#endif
/*
* Push an interrupt frame in a format acceptable to doreti, reload
iret
-#ifdef SMP
-
/*
* Handle TLB shootdowns.
*
MEXITCOUNT
jmp doreti_syscall_ret
-#endif /* SMP */
-
.text
SUPERALIGN_TEXT
.globl Xtimer
setidt(XTIMER_OFFSET, Xtimer,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
-#ifdef SMP
/* Install an inter-CPU IPI for TLB invalidation */
setidt(XINVLTLB_OFFSET, Xinvltlb,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
/* Install an inter-CPU IPI for CPU stop/restart */
setidt(XCPUSTOP_OFFSET, Xcpustop,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
-#endif
}
/*
static void
lapic_timer_intr_pmfixup(struct cputimer_intr *cti __unused)
{
-#ifdef SMP
lwkt_send_ipiq_mask(smp_active_mask,
lapic_timer_fixup_handler, NULL);
-#else
- lapic_timer_fixup_handler(NULL);
-#endif
}
static void
lapic_timer_intr_restart(struct cputimer_intr *cti __unused)
{
-#ifdef SMP
lwkt_send_ipiq_mask(smp_active_mask, lapic_timer_restart_handler, NULL);
-#else
- lapic_timer_restart_handler(NULL);
-#endif
}
lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr);
}
-#ifdef SMP
-
/*
* Inter Processor Interrupt functions.
*/
crit_exit();
}
-#endif /* SMP */
-
/*
* Timer code, in development...
* - suggested by rgrimes@gndrsh.aac.dev.com
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/include/mpapic.h,v 1.14.2.2 2000/09/30 02:49:34 ps Exp $
- * $DragonFly: src/sys/platform/pc32/apic/mpapic.h,v 1.12 2008/06/07 11:37:23 mneumann Exp $
*/
#ifndef _ARCH_APIC_LAPIC_H_
int lapic_unused_apic_id(int);
void lapic_fixup_noioapic(void);
-#ifdef SMP
-
#ifndef _MACHINE_SMP_H_
#include <machine/smp.h>
#endif
return apic_ipi(APIC_DEST_ALLESELF, vector, APIC_DELMODE_FIXED);
}
-#endif /* SMP */
-
#endif /* _ARCH_APIC_LAPIC_H_ */
platform/pc32/apic/ioapic_abi.c standard
platform/pc32/apic/ioapic_ipl.s standard
platform/pc32/apic/apic_vector.s standard
-platform/pc32/i386/mpboot.s optional smp
-platform/pc32/i386/mp_clock.c optional smp
-platform/pc32/i386/mp_machdep.c optional smp
+platform/pc32/i386/mpboot.s standard
+platform/pc32/i386/mp_clock.c standard
+platform/pc32/i386/mp_machdep.c standard
platform/pc32/i386/mptable.c standard
platform/pc32/i386/nexus.c standard
platform/pc32/i386/p4tcc.c optional cpu_enable_tcc
int map_count;
bus_dma_segment_t *segments;
struct bounce_zone *bounce_zone;
-#ifdef SMP
struct spinlock spin;
-#else
- int unused0;
-#endif
};
/*
STAILQ_ENTRY(bounce_zone) links;
STAILQ_HEAD(bp_list, bounce_page) bounce_page_list;
STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist;
-#ifdef SMP
struct spinlock spin;
-#else
- int unused0;
-#endif
int total_bpages;
int free_bpages;
int reserved_bpages;
struct sysctl_oid *sysctl_tree;
};
-#ifdef SMP
#define BZ_LOCK(bz) spin_lock(&(bz)->spin)
#define BZ_UNLOCK(bz) spin_unlock(&(bz)->spin)
-#else
-#define BZ_LOCK(bz) crit_enter()
-#define BZ_UNLOCK(bz) crit_exit()
-#endif
static struct lwkt_token bounce_zone_tok =
LWKT_TOKEN_INITIALIZER(bounce_zone_tok);
if (tag->nsegments <= BUS_DMA_CACHE_SEGMENTS)
return(cache);
-#ifdef SMP
spin_lock(&tag->spin);
-#endif
return(tag->segments);
}
void
bus_dma_tag_unlock(bus_dma_tag_t tag)
{
-#ifdef SMP
if (tag->flags & BUS_DMA_PROTECTED)
return;
if (tag->nsegments > BUS_DMA_CACHE_SEGMENTS)
spin_unlock(&tag->spin);
-#endif
}
/*
newtag = kmalloc(sizeof(*newtag), M_DEVBUF, M_INTWAIT | M_ZERO);
-#ifdef SMP
spin_init(&newtag->spin);
-#endif
newtag->parent = parent;
newtag->alignment = alignment;
newtag->boundary = boundary;
}
bz = new_bz;
-#ifdef SMP
spin_init(&bz->spin);
-#endif
STAILQ_INIT(&bz->bounce_page_list);
STAILQ_INIT(&bz->bounce_map_waitinglist);
bz->free_bpages = 0;
}
crit_enter();
-#ifdef SMP
db_printf("\nCPU%d stopping CPUs: 0x%08x\n",
mycpu->gd_cpuid, mycpu->gd_other_cpus);
stop_cpus(mycpu->gd_other_cpus);
db_printf(" stopped\n");
-#endif /* SMP */
setjmp(db_global_jmpbuf);
db_global_jmpbuf_valid = TRUE;
db_active--;
db_global_jmpbuf_valid = FALSE;
-#ifdef SMP
db_printf("\nCPU%d restarting CPUs: 0x%08x\n",
mycpu->gd_cpuid, stopped_cpus);
restart_cpus(stopped_cpus);
db_printf(" restarted\n");
-#endif /* SMP */
crit_exit();
regs->tf_eip = ddb_regs.tf_eip;
*
* from: @(#)genassym.c 5.11 (Berkeley) 5/10/91
* $FreeBSD: src/sys/i386/i386/genassym.c,v 1.86.2.3 2002/03/03 05:42:49 nyan Exp $
- * $DragonFly: src/sys/platform/pc32/i386/genassym.c,v 1.58 2008/05/09 06:35:11 dillon Exp $
*/
#include <sys/param.h>
ASSYM(TD_SAVEFPU, offsetof(struct thread, td_mach) + offsetof(struct md_thread, mtd_savefpu));
ASSYM(TDPRI_INT_SUPPORT, TDPRI_INT_SUPPORT);
-#ifdef SMP
ASSYM(CPUMASK_LOCK, CPUMASK_LOCK);
ASSYM(CPUMASK_BIT, CPUMASK_BIT);
-#endif
ASSYM(V_TRAP, offsetof(struct vmmeter, v_trap));
ASSYM(V_SYSCALL, offsetof(struct vmmeter, v_syscall));
static int i686_mtrrconflict(int flag1, int flag2);
static void i686_mrstore(struct mem_range_softc *sc);
static void i686_mrstoreone(void *arg);
-#ifdef SMP
static void i686_mrstoreone_cpusync(void *arg);
static void i686_mrAPinit_cpusync(void *arg);
-#endif
static struct mem_range_desc *i686_mtrrfixsearch(struct mem_range_softc *sc,
u_int64_t addr);
static int i686_mrsetlow(struct mem_range_softc *sc,
static void
i686_mrstore(struct mem_range_softc *sc)
{
-#ifdef SMP
/*
* We should use ipi_all_but_self() to call other CPUs into a
* locking gate, then call a target function to do this work.
* implementation, not ready yet.
*/
lwkt_cpusync_simple(-1, i686_mrstoreone_cpusync, sc);
-#else
- mpintr_lock();
- i686_mrstoreone(sc);
- mpintr_unlock();
-#endif
}
-#ifdef SMP
-
static void
i686_mrstoreone_cpusync(void *arg)
{
i686_mrstoreone(arg);
}
-#endif
-
/*
* Update the current CPU's MTRRs with those represented in the
* descriptor list. Note that we do this wholesale rather than just
}
}
-#ifdef SMP
-
static void
i686_mrAPinit_cpusync(void *arg)
{
i686_mrAPinit(arg);
}
-#endif
-
/*
* Initialise MTRRs on an AP after the BSP has run the init code.
*/
static void
i686_mrreinit(struct mem_range_softc *sc)
{
-#ifdef SMP
/*
* We should use ipi_all_but_self() to call other CPUs into a
* locking gate, then call a target function to do this work.
* implementation, not ready yet.
*/
lwkt_cpusync_simple(-1, i686_mrAPinit_cpusync, sc);
-#else
- mpintr_lock();
- i686_mrAPinit(sc);
- mpintr_unlock();
-#endif
}
static void
static void
init_ppro(void)
{
-#ifndef SMP
- u_int64_t apicbase;
-
- /*
- * Local APIC should be diabled in UP kernel.
- */
- apicbase = rdmsr(0x1b);
- apicbase &= ~0x800LL;
- wrmsr(0x1b, apicbase);
-#endif
}
/*
cli /* re-assert cli on loop */
movl %eax,%ecx /* irq mask unavailable due to BGL */
notl %ecx
-#ifdef SMP
testl $RQF_IPIQ,PCPU(reqflags)
jnz doreti_ipiq
-#endif
testl $RQF_TIMER,PCPU(reqflags)
jnz doreti_timer
/*
movl %esi,%eax /* restore cpl for loop */
jmp doreti_next
-#ifdef SMP
/*
* IPIQ message pending. We clear RQF_IPIQ automatically.
*/
decl PCPU(intr_nesting_level)
movl %esi,%eax /* restore cpl for loop */
jmp doreti_next
-#endif
doreti_timer:
movl %eax,%esi /* save cpl (can't use stack) */
cli
movl %eax,%ecx /* ecx = ~CPL */
notl %ecx
-#ifdef SMP
testl $RQF_IPIQ,PCPU(reqflags)
jnz splz_ipiq
-#endif
testl $RQF_TIMER,PCPU(reqflags)
jnz splz_timer
popl %eax
jmp splz_next
-#ifdef SMP
splz_ipiq:
andl $~RQF_IPIQ,PCPU(reqflags)
sti
call lwkt_process_ipiq
popl %eax
jmp splz_next
-#endif
splz_timer:
andl $~RQF_TIMER,PCPU(reqflags)
*
* from: @(#)locore.s 7.3 (Berkeley) 5/13/91
* $FreeBSD: src/sys/i386/i386/locore.s,v 1.132.2.10 2003/02/03 20:54:49 jhb Exp $
- * $DragonFly: src/sys/platform/pc32/i386/locore.s,v 1.13 2007/01/08 03:33:42 dillon Exp $
*
* originally from: locore.s, by William F. Jolitz
*
#endif
xorl %edx,%edx
-#if !defined(SMP)
- testl $CPUID_PGE, R(cpu_feature)
- jz 2f
- orl $PG_G,%edx
-#endif
-
2: movl $R(etext),%ecx
addl $PAGE_MASK,%ecx
shrl $PAGE_SHIFT,%ecx
andl $~PAGE_MASK, %eax
map_read_write:
movl $PG_RW,%edx
-#if !defined(SMP)
- testl $CPUID_PGE, R(cpu_feature)
- jz 1f
- orl $PG_G,%edx
-#endif
-
+
1: movl R(KERNend),%ecx
subl %eax,%ecx
shrl $PAGE_SHIFT,%ecx
int _udatasel, _ucodesel;
u_int atdevbase;
-#ifdef SMP
int64_t tsc_offsets[MAXCPU];
-#else
-int64_t tsc_offsets[1];
-#endif
#if defined(SWTCH_OPTIM_STATS)
extern int swtch_optim_stats;
}
}
-#ifdef SMP
-
/*
* This routine is called if a spinlock has been held through the
* exponential backoff period and is seriously contested. On a real cpu
cpu_pause();
}
-#endif
-
/*
* Clear registers on exec
*/
*/
base_memory = physmap[1];
-#ifdef SMP
/* make hole for AP bootstrap code YYY */
physmap[1] = mp_bootaddress(base_memory);
-#endif
/* Save EBDA address, if any */
ebda_addr = (u_long)(*(u_short *)(KERNBASE + 0x40e));
static void
init_locks(void)
{
-#ifdef SMP
/*
* Get the initial mplock with a count of 1 for the BSP.
* This uses a LOGICAL cpu ID, ie BSP == 0.
*/
cpu_get_initial_mplock();
-#endif
/* DEPRECATED */
spin_lock_init(&mcount_spinlock);
spin_lock_init(&intr_spinlock);
#include <sys/fcntl.h>
#include <sys/lock.h>
-#ifndef SMP
-#include <machine/cputypes.h>
-#endif
#include <machine/clock.h>
#include <machine/perfmon.h>
static int perfmon_inuse;
static int perfmon_cpuok;
-#ifndef SMP
-static int msr_ctl[NPMC];
-#endif
static int msr_pmc[NPMC];
static unsigned int ctl_shadow[NPMC];
static quad_t pmc_shadow[NPMC]; /* used when ctr is stopped on P5 */
static int (*writectl)(int);
-#ifndef SMP
-static int writectl5(int);
-static int writectl6(int);
-#endif
static d_close_t perfmon_close;
static d_open_t perfmon_open;
void
perfmon_init(void)
{
-#ifndef SMP
- switch(cpu_class) {
- case CPUCLASS_586:
- perfmon_cpuok = 1;
- msr_ctl[0] = 0x11;
- msr_ctl[1] = 0x11;
- msr_pmc[0] = 0x12;
- msr_pmc[1] = 0x13;
- writectl = writectl5;
- break;
- case CPUCLASS_686:
- perfmon_cpuok = 1;
- msr_ctl[0] = 0x186;
- msr_ctl[1] = 0x187;
- msr_pmc[0] = 0xc1;
- msr_pmc[1] = 0xc2;
- writectl = writectl6;
- break;
-
- default:
- perfmon_cpuok = 0;
- break;
- }
-#endif /* SMP */
}
int
return EBUSY;
}
-#ifndef SMP
-/*
- * Unfortunately, the performance-monitoring registers are laid out
- * differently in the P5 and P6. We keep everything in P6 format
- * internally (except for the event code), and convert to P5
- * format as needed on those CPUs. The writectl function pointer
- * is set up to point to one of these functions by perfmon_init().
- */
-int
-writectl6(int pmc)
-{
- if (pmc > 0 && !(ctl_shadow[pmc] & (PMCF_EN << 16))) {
- wrmsr(msr_ctl[pmc], 0);
- } else {
- wrmsr(msr_ctl[pmc], ctl_shadow[pmc]);
- }
- return 0;
-}
-
-#define P5FLAG_P 0x200
-#define P5FLAG_E 0x100
-#define P5FLAG_USR 0x80
-#define P5FLAG_OS 0x40
-
-int
-writectl5(int pmc)
-{
- quad_t newval = 0;
-
- if (ctl_shadow[1] & (PMCF_EN << 16)) {
- if (ctl_shadow[1] & (PMCF_USR << 16))
- newval |= P5FLAG_USR << 16;
- if (ctl_shadow[1] & (PMCF_OS << 16))
- newval |= P5FLAG_OS << 16;
- if (!(ctl_shadow[1] & (PMCF_E << 16)))
- newval |= P5FLAG_E << 16;
- newval |= (ctl_shadow[1] & 0x3f) << 16;
- }
- if (ctl_shadow[0] & (PMCF_EN << 16)) {
- if (ctl_shadow[0] & (PMCF_USR << 16))
- newval |= P5FLAG_USR;
- if (ctl_shadow[0] & (PMCF_OS << 16))
- newval |= P5FLAG_OS;
- if (!(ctl_shadow[0] & (PMCF_E << 16)))
- newval |= P5FLAG_E;
- newval |= ctl_shadow[0] & 0x3f;
- }
-
- wrmsr(msr_ctl[0], newval);
- return 0; /* XXX should check for unimplemented bits */
-}
-#endif /* !SMP */
-
/*
* Now the user-mode interface, called from a subdevice of mem.c.
*/
* cases rather then invl1pg. Actually, I don't even know why it
* works under UP because self-referential page table mappings
*/
-#ifdef SMP
pgeflag = 0;
-#else
- if (cpu_feature & CPUID_PGE)
- pgeflag = PG_G;
-#endif
/*
* Initialize the 4MB page size flag
ptditmp &= ~(NBPDR - 1);
ptditmp |= PG_V | PG_RW | PG_PS | PG_U | pgeflag;
pdir4mb = ptditmp;
-
-#ifndef SMP
- /*
- * Enable the PSE mode. If we are SMP we can't do this
- * now because the APs will not be able to use it when
- * they boot up.
- */
- load_cr4(rcr4() | CR4_PSE);
-
- /*
- * We can do the mapping here for the single processor
- * case. We simply ignore the old page table page from
- * now on.
- */
- /*
- * For SMP, we still need 4K pages to bootstrap APs,
- * PSE will be enabled as soon as all APs are up.
- */
- PTD[KPTDI] = (pd_entry_t)ptditmp;
- kernel_pmap.pm_pdir[KPTDI] = (pd_entry_t)ptditmp;
- cpu_invltlb();
-#endif
}
#endif
cpu_invltlb();
}
-#ifdef SMP
/*
* Set 4mb pdir for mp startup
*/
}
}
}
-#endif
/*
* Initialize the pmap module, called by vm_init()
va += PAGE_SIZE;
m++;
}
-#ifdef SMP
smp_invltlb(); /* XXX */
-#endif
}
/*
cpu_invlpg((void *)va);
va += PAGE_SIZE;
}
-#ifdef SMP
smp_invltlb();
-#endif
}
/*
* the pmap_inval_*() API that is)... it's ok to do this for simple
* wiring changes.
*/
-#ifdef SMP
if (wired)
atomic_set_int(pte, PG_W);
else
atomic_clear_int(pte, PG_W);
-#else
- if (wired)
- atomic_set_int_nonlocked(pte, PG_W);
- else
- atomic_clear_int_nonlocked(pte, PG_W);
-#endif
lwkt_reltoken(&vm_token);
}
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_va);
if (pte && (*pte & PG_A)) {
-#ifdef SMP
atomic_clear_int(pte, PG_A);
-#else
- atomic_clear_int_nonlocked(pte, PG_A);
-#endif
rtval++;
if (rtval > 4) {
break;
lp->lwp_vmspace = newvm;
if (curthread->td_lwp == lp) {
pmap = vmspace_pmap(newvm);
-#if defined(SMP)
atomic_set_cpumask(&pmap->pm_active, mycpu->gd_cpumask);
if (pmap->pm_active & CPUMASK_LOCK)
pmap_interlock_wait(newvm);
-#else
- pmap->pm_active |= 1;
-#endif
#if defined(SWTCH_OPTIM_STATS)
tlb_flush_count++;
#endif
curthread->td_pcb->pcb_cr3 = vtophys(pmap->pm_pdir);
load_cr3(curthread->td_pcb->pcb_cr3);
pmap = vmspace_pmap(oldvm);
-#if defined(SMP)
atomic_clear_cpumask(&pmap->pm_active,
mycpu->gd_cpumask);
-#else
- pmap->pm_active &= ~(cpumask_t)1;
-#endif
}
}
}
-#ifdef SMP
/*
* Called when switching to a locked pmap, used to interlock against pmaps
* undergoing modifications to prevent us from activating the MMU for the
}
}
-#endif
-
/*
* Return a page-directory alignment hint for device mappings which will
* allow the use of super-pages for the mapping.
pmap_inval_interlock(pmap_inval_info_t info, pmap_t pmap, vm_offset_t va)
{
cpumask_t oactive;
-#ifdef SMP
cpumask_t nactive;
DEBUG_PUSH_INFO("pmap_inval_interlock");
cpu_pause();
}
DEBUG_POP_INFO();
-#else
- oactive = pmap->pm_active & ~CPUMASK_LOCK;
-#endif
KKASSERT((info->pir_flags & PIRF_CPUSYNC) == 0);
info->pir_va = va;
info->pir_flags = PIRF_CPUSYNC;
pmap_inval_deinterlock(pmap_inval_info_t info, pmap_t pmap)
{
KKASSERT(info->pir_flags & PIRF_CPUSYNC);
-#ifdef SMP
atomic_clear_cpumask(&pmap->pm_active, CPUMASK_LOCK);
-#endif
lwkt_cpusync_deinterlock(&info->pir_cpusync);
info->pir_flags = 0;
}
cmpl $VM_MAX_USER_ADDRESS-4,%edx /* verify address is valid */
ja fusufault
-#ifdef SMP
lock
-#endif
cmpxchgl %ecx,(%edx) /* Compare and set. */
/*
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/i386/swtch.s,v 1.89.2.10 2003/01/23 03:36:24 ps Exp $
- * $DragonFly: src/sys/platform/pc32/i386/swtch.s,v 1.47 2007/06/29 21:54:10 dillon Exp $
*/
#include "use_npx.h"
#include "assym.s"
-#if defined(SMP)
#define MPLOCKED lock ;
-#else
-#define MPLOCKED
-#endif
.data
* wait for it to complete before we can continue.
*/
movl LWP_VMSPACE(%ecx), %ecx /* ECX = vmspace */
-#ifdef SMP
pushl %eax /* save curthread */
1:
movl VM_PMAP+PM_ACTIVE(%ecx),%eax /* old value for cmpxchgl */
jmp 2f
1:
popl %eax
-#else
- movl PCPU(cpumask), %esi
- orl %esi, VM_PMAP+PM_ACTIVE(%ecx)
-#endif
/*
* Restore the MMU address space. If it is the same as the last
movl %ecx,%cr3
andl $~TDF_RUNNING,TD_FLAGS(%ebx)
orl $TDF_RUNNING,TD_FLAGS(%eax) /* manual, no switch_return */
-#ifdef SMP
cmpl $0,PCPU(cpuid)
je 1f
call ap_init
1:
-#endif
/*
* ap_init can decide to enable interrupts early, but otherwise, or if
* we are UP, do it here.
{
struct thread *td = curthread;
int i;
-#ifdef SMP
int off = GTLS_START + mycpu->gd_cpuid * NGDT;
-#else
- const int off = GTLS_START;
-#endif
for (i = 0; i < NGTLS; ++i)
gdt[off + i].sd = td->td_tls.tls[i];
}
-#ifdef SMP
static
void
set_user_ldt_cpusync(void *arg)
{
set_user_ldt(arg);
}
-#endif
/*
* Update the GDT entry pointing to the LDT to point to the LDT of the
return;
pcb_ldt = pcb->pcb_ldt;
-#ifdef SMP
gdt[mycpu->gd_cpuid * NGDT + GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
-#else
- gdt[GUSERLDT_SEL].sd = pcb_ldt->ldt_sd;
-#endif
lldt(GSEL(GUSERLDT_SEL, SEL_KPL));
mdcpu->gd_currentldt = GSEL(GUSERLDT_SEL, SEL_KPL);
}
* reload it. XXX we need to track which cpus might be
* using the shared ldt and only signal those.
*/
-#ifdef SMP
lwkt_cpusync_simple(-1, set_user_ldt_cpusync, pcb);
-#else
- set_user_ldt(pcb);
-#endif
}
descs_size = uap->num * sizeof(union descriptor);
#include <sys/thread2.h>
#include <sys/mplock2.h>
-#ifdef SMP
-
#define MAKEMPSAFE(have_mplock) \
if (have_mplock == 0) { \
get_mplock(); \
have_mplock = 1; \
}
-#else
-
-#define MAKEMPSAFE(have_mplock)
-
-#endif
-
int (*pmath_emulate) (struct trapframe *);
extern void trap (struct trapframe *frame);
struct proc *p;
int sticks = 0;
int i = 0, ucode = 0, type, code;
-#ifdef SMP
int have_mplock = 0;
-#endif
#ifdef INVARIANTS
int crit_count = td->td_critcount;
lwkt_tokref_t curstop = td->td_toks_stop;
if (in_vm86call) {
if (frame->tf_eflags & PSL_VM &&
(type == T_PROTFLT || type == T_STKFLT)) {
-#ifdef SMP
KKASSERT(get_mplock_count(curthread) > 0);
-#endif
i = vm86_emulate((struct vm86frame *)frame);
-#ifdef SMP
KKASSERT(get_mplock_count(curthread) > 0);
-#endif
if (i != 0) {
/*
* returns to original process
*/
-#ifdef SMP
vm86_trap((struct vm86frame *)frame,
have_mplock);
-#else
- vm86_trap((struct vm86frame *)frame, 0);
-#endif
KKASSERT(0); /* NOT REACHED */
}
goto out2;
userret(lp, frame, sticks);
userexit(lp);
out2: ;
-#ifdef SMP
if (have_mplock)
rel_mplock();
-#endif
if (p != NULL && lp != NULL)
KTR_LOG(kernentry_trap_ret, p->p_pid, lp->lwp_tid);
#ifdef INVARIANTS
type, trap_msg[type],
frame->tf_eflags & PSL_VM ? "vm86" :
ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel");
-#ifdef SMP
/* three separate prints in case of a trap on an unmapped page */
kprintf("cpuid = %d; ", mycpu->gd_cpuid);
kprintf("lapic.id = %08x\n", lapic->id);
-#endif
if (type == T_PAGEFLT) {
kprintf("fault virtual address = %p\n", (void *)eva);
kprintf("fault code = %s %s, %s\n",
if (curthread->td_critcount)
kprintf("(CRIT)");
kprintf("\n");
-#ifdef SMP
/**
* XXX FIXME:
* we probably SHOULD have stopped the other CPUs before now!
* another CPU COULD have been touching cpl at this moment...
*/
kprintf(" <- SMP: XXX");
-#endif
kprintf("\n");
#ifdef KDB
kprintf("eip = 0x%x\n", gd->gd_common_tss.tss_eip);
kprintf("esp = 0x%x\n", gd->gd_common_tss.tss_esp);
kprintf("ebp = 0x%x\n", gd->gd_common_tss.tss_ebp);
-#ifdef SMP
/* three separate prints in case of a trap on an unmapped page */
kprintf("cpuid = %d; ", gd->mi.gd_cpuid);
kprintf("lapic.id = %08x\n", lapic->id);
-#endif
panic("double fault");
}
#ifdef INVARIANTS
int crit_count = td->td_critcount;
#endif
-#ifdef SMP
int have_mplock = 0;
-#endif
u_int code;
union sysunion args;
STOPEVENT(p, S_SCX, code);
userexit(lp);
-#ifdef SMP
/*
* Release the MP lock if we had to get it
*/
if (have_mplock)
rel_mplock();
-#endif
KTR_LOG(kernentry_syscall_ret, p->p_pid, lp->lwp_tid, error);
#ifdef INVARIANTS
KASSERT(crit_count == td->td_critcount,
#include <bus/isa/isa.h>
static void cpu_reset_real (void);
-#ifdef SMP
static void cpu_reset_proxy (void);
static u_int cpu_reset_proxyid;
static volatile u_int cpu_reset_proxy_active;
-#endif
extern int _ucodesel, _udatasel;
* Force reset the processor by invalidating the entire address space!
*/
-#ifdef SMP
static void
cpu_reset_proxy(void)
{
DELAY(1000000);
cpu_reset_real();
}
-#endif
void
cpu_reset(void)
{
-#ifdef SMP
if (smp_active_mask == 1) {
cpu_reset_real();
/* NOTREACHED */
/* NOTREACHED */
}
}
-#else
- cpu_reset_real();
-#endif
}
static void
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/isa/intr_machdep.h,v 1.19.2.2 2001/10/14 20:05:50 luigi Exp $
- * $DragonFly: src/sys/platform/pc32/isa/intr_machdep.h,v 1.25 2006/10/23 21:50:31 dillon Exp $
*/
#ifndef _ARCH_ISA_INTR_MACHDEP_H_
Xspuriousint, /* handle APIC "spurious INTs" */
Xtimer; /* handle LAPIC timer INT */
-#ifdef SMP
inthand_t
Xcpustop, /* CPU stops & waits for another CPU to restart it */
Xinvltlb, /* TLB shootdowns */
Xipiq; /* handle lwkt_send_ipiq() requests */
-#endif
#endif /* LOCORE */
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/include/lock.h,v 1.11.2.2 2000/09/30 02:49:34 ps Exp $
- * $DragonFly: src/sys/platform/pc32/include/lock.h,v 1.17 2008/06/19 21:32:55 aggelos Exp $
*/
#ifndef _MACHINE_LOCK_H_
* Under UP the spinlock routines still serve to disable/restore
* interrupts.
*/
-
-
-#ifdef SMP
-
#define SPIN_INIT(mem) \
movl $0,mem ; \
#define SPIN_UNLOCK_NOREG(mem) \
SPIN_UNLOCK(mem) ; \
-#else
-
-#define SPIN_LOCK(mem) \
- pushfl ; \
- cli ; \
- orl $PSL_C,(%esp) ; \
- popl mem ; \
-
-#define SPIN_LOCK_PUSH_RESG
-#define SPIN_LOCK_POP_REGS
-#define SPIN_LOCK_FRAME_SIZE 0
-
-#define SPIN_UNLOCK(mem) \
- pushl mem ; \
- movl $0,mem ; \
- popfl ; \
-
-#define SPIN_UNLOCK_PUSH_REGS
-#define SPIN_UNLOCK_POP_REGS
-#define SPIN_UNLOCK_FRAME_SIZE 0
-
-#endif /* SMP */
-
#else /* !LOCORE */
#ifdef _KERNEL
* from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
* from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
* $FreeBSD: src/sys/i386/include/pmap.h,v 1.65.2.3 2001/10/03 07:15:37 peter Exp $
- * $DragonFly: src/sys/platform/pc32/include/pmap.h,v 1.7 2007/06/08 00:57:04 dillon Exp $
*/
#ifndef _MACHINE_PMAP_H_
unsigned *pmap_kernel_pte (vm_offset_t) __pure2;
struct vm_page *pmap_use_pt (pmap_t, vm_offset_t);
int pmap_get_pgeflag(void);
-#ifdef SMP
void pmap_set_opt (void);
-#endif
#endif /* _KERNEL */
* ----------------------------------------------------------------------------
*
* $FreeBSD: src/sys/i386/include/smp.h,v 1.50.2.5 2001/02/13 22:32:45 tegge Exp $
- * $DragonFly: src/sys/platform/pc32/include/smp.h,v 1.20 2006/11/07 06:43:24 dillon Exp $
- *
*/
#ifndef _MACHINE_SMP_H_
#ifdef _KERNEL
-#if defined(SMP)
-
#ifndef LOCORE
/*
}
#endif /* !LOCORE */
-#else /* !SMP */
-
-#define smp_active_mask 1 /* smp_active_mask always 1 on UP machines */
-
-#endif
#endif /* _KERNEL */
#endif /* _MACHINE_SMP_H_ */
}
#define mycpu _get_mycpu()
-
-#ifdef SMP
#define mycpuid (_get_mycpu()->gd_cpuid)
-#else
-#define mycpuid 0
-#endif
/*
* note: curthread is never NULL, but curproc can be. Also note that
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/bus.h>
-#ifndef SMP
-#include <sys/lock.h>
-#endif
#include <sys/sysctl.h>
#include <sys/cons.h>
#include <sys/systimer.h>
{
static sysclock_t sysclock_count; /* NOTE! Must be static */
struct globaldata *gd = mycpu;
-#ifdef SMP
struct globaldata *gscan;
int n;
-#endif
/*
* SWSTROBE mode is a one-shot, the timer is no longer running
* usually *ALL* of them. We need to use the LAPIC timer for this.
*/
sysclock_count = sys_cputimer->count();
-#ifdef SMP
for (n = 0; n < ncpus; ++n) {
gscan = globaldata_find(n);
if (TAILQ_FIRST(&gscan->gd_systimerq) == NULL)
systimer_intr(&sysclock_count, 0, frame_arg);
}
}
-#else
- if (TAILQ_FIRST(&gd->gd_systimerq) != NULL)
- systimer_intr(&sysclock_count, 0, frame_arg);
-#endif
}
}
EVENTHANDLER_REGISTER(shutdown_post_sync, resettodr_on_shutdown, NULL, SHUTDOWN_PRI_LAST);
-
-#if !defined(SMP)
- /*
- * We can not use the TSC in SMP mode, until we figure out a
- * cheap (impossible), reliable and precise (yeah right!) way
- * to synchronize the TSCs of all the CPUs.
- * Curse Intel for leaving the counter out of the I/O APIC.
- */
-
-#if NAPM > 0
- /*
- * We can not use the TSC if we support APM. Precise timekeeping
- * on an APM'ed machine is at best a fools pursuit, since
- * any and all of the time spent in various SMM code can't
- * be reliably accounted for. Reading the RTC is your only
- * source of reliable time info. The i8254 looses too of course
- * but we need to have some kind of time...
- * We don't know at this point whether APM is going to be used
- * or not, nor when it might be activated. Play it safe.
- */
- return;
-#endif /* NAPM > 0 */
-
-#endif /* !defined(SMP) */
}
/*
#include <sys/thread2.h>
#include <sys/mplock2.h>
-#ifndef SMP
-#include <machine/asmacros.h>
-#endif
#include <machine/cputypes.h>
#include <machine/frame.h>
#include <machine/ipl.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/psl.h>
-#ifndef SMP
-#include <machine/clock.h>
-#endif
#include <machine/specialreg.h>
#include <machine/segments.h>
#include <machine/globaldata.h>
-#ifndef SMP
-#include <machine_base/icu/icu.h>
-#include <machine/intr_machdep.h>
-#include <bus/isa/isa.h>
-#endif
-
/*
* 387 and 287 Numeric Coprocessor Extension (NPX) Driver.
*/
"MMX/XMM optimized bcopy/copyin/copyout support");
#endif
-#ifndef SMP
-static u_int npx0_imask;
-static struct gate_descriptor npx_idt_probeintr;
-static int npx_intrno;
-static volatile u_int npx_intrs_while_probing;
-static volatile u_int npx_traps_while_probing;
-#endif
-
static bool_t npx_ex16;
static bool_t npx_exists;
static bool_t npx_irq13;
static int npx_irq; /* irq number */
-#ifndef SMP
-/*
- * Special interrupt handlers. Someday intr0-intr15 will be used to count
- * interrupts. We'll still need a special exception 16 handler. The busy
- * latch stuff in probeintr() can be moved to npxprobe().
- */
-inthand_t probeintr;
-__asm(" \n\
- .text \n\
- .p2align 2,0x90 \n\
- .type " __XSTRING(CNAME(probeintr)) ",@function \n\
-" __XSTRING(CNAME(probeintr)) ": \n\
- ss \n\
- incl " __XSTRING(CNAME(npx_intrs_while_probing)) " \n\
- pushl %eax \n\
- movb $0x20,%al # EOI (asm in strings loses cpp features) \n\
- outb %al,$0xa0 # IO_ICU2 \n\
- outb %al,$0x20 # IO_ICU1 \n\
- movb $0,%al \n\
- outb %al,$0xf0 # clear BUSY# latch \n\
- popl %eax \n\
- iret \n\
-");
-
-inthand_t probetrap;
-__asm(" \n\
- .text \n\
- .p2align 2,0x90 \n\
- .type " __XSTRING(CNAME(probetrap)) ",@function \n\
-" __XSTRING(CNAME(probetrap)) ": \n\
- ss \n\
- incl " __XSTRING(CNAME(npx_traps_while_probing)) " \n\
- fnclex \n\
- iret \n\
-");
-#endif /* SMP */
-
static struct krate badfprate = { 1 };
/*
static int
npx_probe(device_t dev)
{
-#ifdef SMP
-
if (resource_int_value("npx", 0, "irq", &npx_irq) != 0)
npx_irq = 13;
return npx_probe1(dev);
-
-#else /* SMP */
-
- int result;
- u_long save_eflags;
- u_char save_icu1_mask;
- u_char save_icu2_mask;
- struct gate_descriptor save_idt_npxintr;
- struct gate_descriptor save_idt_npxtrap;
- /*
- * This routine is now just a wrapper for npxprobe1(), to install
- * special npx interrupt and trap handlers, to enable npx interrupts
- * and to disable other interrupts. Someday isa_configure() will
- * install suitable handlers and run with interrupts enabled so we
- * won't need to do so much here.
- */
- if (resource_int_value("npx", 0, "irq", &npx_irq) != 0)
- npx_irq = 13;
- npx_intrno = IDT_OFFSET + npx_irq;
- save_eflags = read_eflags();
- cpu_disable_intr();
- save_icu1_mask = inb(IO_ICU1 + 1);
- save_icu2_mask = inb(IO_ICU2 + 1);
- save_idt_npxintr = idt[npx_intrno];
- save_idt_npxtrap = idt[16];
- outb(IO_ICU1 + 1, ~(1 << ICU_IRQ_SLAVE));
- outb(IO_ICU2 + 1, ~(1 << (npx_irq - 8)));
- setidt(16, probetrap, SDT_SYS386TGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
- setidt(npx_intrno, probeintr, SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
- npx_idt_probeintr = idt[npx_intrno];
- cpu_enable_intr();
- result = npx_probe1(dev);
- cpu_disable_intr();
- outb(IO_ICU1 + 1, save_icu1_mask);
- outb(IO_ICU2 + 1, save_icu2_mask);
- idt[npx_intrno] = save_idt_npxintr;
- idt[16] = save_idt_npxtrap;
- write_eflags(save_eflags);
- return (result);
-
-#endif /* SMP */
}
static int
npx_probe1(device_t dev)
{
-#ifndef SMP
- u_short control;
- u_short status;
-#endif
-
/*
* Partially reset the coprocessor, if any. Some BIOS's don't reset
* it after a warm boot.
return (0);
}
-#ifndef SMP
- /*
- * Don't use fwait here because it might hang.
- * Don't use fnop here because it usually hangs if there is no FPU.
- */
- DELAY(1000); /* wait for any IRQ13 */
-#ifdef DIAGNOSTIC
- if (npx_intrs_while_probing != 0)
- kprintf("fninit caused %u bogus npx interrupt(s)\n",
- npx_intrs_while_probing);
- if (npx_traps_while_probing != 0)
- kprintf("fninit caused %u bogus npx trap(s)\n",
- npx_traps_while_probing);
-#endif
- /*
- * Check for a status of mostly zero.
- */
- status = 0x5a5a;
- fnstsw(&status);
- if ((status & 0xb8ff) == 0) {
- /*
- * Good, now check for a proper control word.
- */
- control = 0x5a5a;
- fnstcw(&control);
- if ((control & 0x1f3f) == 0x033f) {
- hw_float = npx_exists = 1;
- /*
- * We have an npx, now divide by 0 to see if exception
- * 16 works.
- */
- control &= ~(1 << 2); /* enable divide by 0 trap */
- fldcw(&control);
- npx_traps_while_probing = npx_intrs_while_probing = 0;
- fp_divide_by_0();
- if (npx_traps_while_probing != 0) {
- /*
- * Good, exception 16 works.
- */
- npx_ex16 = 1;
- return (0);
- }
- if (npx_intrs_while_probing != 0) {
- int rid;
- struct resource *r;
- void *intr;
- /*
- * Bad, we are stuck with IRQ13.
- */
- npx_irq13 = 1;
- /*
- * npxattach would be too late to set npx0_imask
- */
- npx0_imask |= (1 << npx_irq);
-
- /*
- * We allocate these resources permanently,
- * so there is no need to keep track of them.
- */
- rid = 0;
- r = bus_alloc_resource(dev, SYS_RES_IOPORT,
- &rid, IO_NPX, IO_NPX,
- IO_NPXSIZE, RF_ACTIVE);
- if (r == NULL)
- panic("npx: can't get ports");
- rid = 0;
- r = bus_alloc_legacy_irq_resource(dev, &rid,
- npx_irq, RF_ACTIVE);
- if (r == NULL)
- panic("npx: can't get IRQ");
- BUS_SETUP_INTR(device_get_parent(dev),
- dev, r, 0,
- npx_intr, 0, &intr, NULL, NULL);
- if (intr == NULL)
- panic("npx: can't create intr");
-
- return (0);
- }
- /*
- * Worse, even IRQ13 is broken. Use emulator.
- */
- }
- }
-#endif /* SMP */
/*
* Probe failed, but we want to get to npxattach to initialize the
* emulator and say that it has been installed. XXX handle devices
void
npxsave(union savefpu *addr)
{
-#if defined(SMP) || !defined(CPU_DISABLE_SSE)
-
crit_enter();
stop_emulating();
fpusave(addr);
fninit();
start_emulating();
crit_exit();
-
-#else /* !SMP and CPU_DISABLE_SSE */
-
- u_char icu1_mask;
- u_char icu2_mask;
- u_char old_icu1_mask;
- u_char old_icu2_mask;
- struct gate_descriptor save_idt_npxintr;
- u_long save_eflags;
-
- save_eflags = read_eflags();
- cpu_disable_intr();
- old_icu1_mask = inb(IO_ICU1 + 1);
- old_icu2_mask = inb(IO_ICU2 + 1);
- save_idt_npxintr = idt[npx_intrno];
- outb(IO_ICU1 + 1, old_icu1_mask & ~((1 << ICU_IRQ_SLAVE) | npx0_imask));
- outb(IO_ICU2 + 1, old_icu2_mask & ~(npx0_imask >> 8));
- idt[npx_intrno] = npx_idt_probeintr;
- cpu_enable_intr();
- stop_emulating();
- fnsave(addr);
- fnop();
- cpu_disable_intr();
- mdcpu->gd_npxthread = NULL;
- start_emulating();
- icu1_mask = inb(IO_ICU1 + 1); /* masks may have changed */
- icu2_mask = inb(IO_ICU2 + 1);
- outb(IO_ICU1 + 1,
- (icu1_mask & ~npx0_imask) | (old_icu1_mask & npx0_imask));
- outb(IO_ICU2 + 1,
- (icu2_mask & ~(npx0_imask >> 8))
- | (old_icu2_mask & (npx0_imask >> 8)));
- idt[npx_intrno] = save_idt_npxintr;
- write_eflags(save_eflags); /* back to usual state */
-
-#endif /* SMP */
}
static void
{
u_int count;
int delta;
-#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) && \
- defined(PERFMON) && defined(I586_PMC_GUPROF)
- u_quad_t event_count;
-#endif
u_char high, low;
static u_int prev_count;
-#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP)
- if (cputime_clock == CPUTIME_CLOCK_TSC) {
- count = (u_int)rdtsc();
- delta = (int)(count - prev_count);
- prev_count = count;
- return (delta);
- }
-#if defined(PERFMON) && defined(I586_PMC_GUPROF)
- if (cputime_clock == CPUTIME_CLOCK_I586_PMC) {
- /*
- * XXX permon_read() should be inlined so that the
- * perfmon module doesn't need to be compiled with
- * profiling disabled and so that it is fast.
- */
- perfmon_read(0, &event_count);
-
- count = (u_int)event_count;
- delta = (int)(count - prev_count);
- prev_count = count;
- return (delta);
- }
-#endif /* PERFMON && I586_PMC_GUPROF */
-#endif /* (I586_CPU || I686_CPU) && !SMP */
-
/*
* Read the current value of the 8254 timer counter 0.
*/
void
startguprof(struct gmonparam *gp)
{
- if (cputime_clock == CPUTIME_CLOCK_UNINITIALIZED) {
+ if (cputime_clock == CPUTIME_CLOCK_UNINITIALIZED)
cputime_clock = CPUTIME_CLOCK_I8254;
-#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP)
- if (tsc_frequency != 0)
- cputime_clock = CPUTIME_CLOCK_TSC;
-#endif
- }
gp->profrate = timer_freq << CPUTIME_CLOCK_I8254_SHIFT;
-#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP)
- if (cputime_clock == CPUTIME_CLOCK_TSC)
- gp->profrate = (u_int)tsc_frequency; /* XXX */
-#if defined(PERFMON) && defined(I586_PMC_GUPROF)
- else if (cputime_clock == CPUTIME_CLOCK_I586_PMC) {
- if (perfmon_avail() &&
- perfmon_setup(0, cputime_clock_pmc_conf) == 0) {
- if (perfmon_start(0) != 0)
- perfmon_fini(0);
- else {
- /* XXX 1 event == 1 us. */
- gp->profrate = 1000000;
-
- saved_gmp = *gp;
-
- /* Zap overheads. They are invalid. */
- gp->cputime_overhead = 0;
- gp->mcount_overhead = 0;
- gp->mcount_post_overhead = 0;
- gp->mcount_pre_overhead = 0;
- gp->mexitcount_overhead = 0;
- gp->mexitcount_post_overhead = 0;
- gp->mexitcount_pre_overhead = 0;
-
- cputime_clock_pmc_init = TRUE;
- }
- }
- }
-#endif /* PERFMON && I586_PMC_GUPROF */
-#endif /* (I586_CPU || I686_CPU) && !SMP */
cputime_bias = 0;
cputime();
}
/* convert an absolute IRQ# into gd_ipending index */
#define IRQ_LIDX(irq_num) ((irq_num) >> 6)
-#ifdef SMP
#define MPLOCKED lock ;
-#else
-#define MPLOCKED
-#endif
#define APIC_PUSH_FRAME \
PUSH_FRAME ; /* 15 regs + space for 5 extras */ \
APIC_POP_FRAME
jmp doreti_iret
-#ifdef SMP
-
/*
* Handle TLB shootdowns.
*
APIC_POP_FRAME
jmp doreti_iret
-#endif /* SMP */
-
.text
SUPERALIGN_TEXT
.globl Xtimer
setidt_global(XTIMER_OFFSET, Xtimer,
SDT_SYSIGT, SEL_KPL, 0);
-#ifdef SMP
/* Install an inter-CPU IPI for TLB invalidation */
setidt_global(XINVLTLB_OFFSET, Xinvltlb,
SDT_SYSIGT, SEL_KPL, 0);
/* Install an inter-CPU IPI for CPU stop/restart */
setidt_global(XCPUSTOP_OFFSET, Xcpustop,
SDT_SYSIGT, SEL_KPL, 0);
-#endif
}
/*
static void
lapic_timer_intr_pmfixup(struct cputimer_intr *cti __unused)
{
-#ifdef SMP
lwkt_send_ipiq_mask(smp_active_mask,
lapic_timer_fixup_handler, NULL);
-#else
- lapic_timer_fixup_handler(NULL);
-#endif
}
static void
lapic_timer_intr_restart(struct cputimer_intr *cti __unused)
{
-#ifdef SMP
lwkt_send_ipiq_mask(smp_active_mask, lapic_timer_restart_handler, NULL);
-#else
- lapic_timer_restart_handler(NULL);
-#endif
}
lapic->lvt_lint0, lapic->lvt_lint1, lapic->tpr, lapic->svr);
}
-#ifdef SMP
-
/*
* Inter Processor Interrupt functions.
*/
crit_exit();
}
-#endif /* SMP */
-
/*
* Timer code, in development...
* - suggested by rgrimes@gndrsh.aac.dev.com
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/include/mpapic.h,v 1.14.2.2 2000/09/30 02:49:34 ps Exp $
- * $DragonFly: src/sys/platform/pc64/apic/mpapic.h,v 1.1 2008/08/29 17:07:12 dillon Exp $
*/
#ifndef _ARCH_APIC_LAPIC_H_
int lapic_unused_apic_id(int);
void lapic_fixup_noioapic(void);
-#ifdef SMP
-
#ifndef _MACHINE_SMP_H_
#include <machine/smp.h>
#endif
return apic_ipi(APIC_DEST_ALLESELF, vector, APIC_DELMODE_FIXED);
}
-#endif /* SMP */
-
#endif /* _ARCH_APIC_LAPIC_H_ */
cpu/x86_64/misc/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/mpboot.S standard
# DDB XXX
cpu/x86_64/misc/x86_64-gdbstub.c optional ddb
platform/pc64/x86_64/sysarch.c standard
platform/pc64/x86_64/ipl_funcs.c standard
kern/syscalls.c standard
-platform/pc64/x86_64/mp_machdep.c optional smp
+platform/pc64/x86_64/mp_machdep.c standard
platform/pc64/x86_64/mptable.c standard
platform/pc64/acpica5/acpi_sdt.c standard
platform/pc64/acpica5/acpi_fadt.c standard
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/isa/intr_machdep.h,v 1.19.2.2 2001/10/14 20:05:50 luigi Exp $
- * $DragonFly: src/sys/platform/pc64/isa/intr_machdep.h,v 1.1 2008/08/29 17:07:19 dillon Exp $
*/
#ifndef _ARCH_INTR_MACHDEP_H_
Xspuriousint, /* handle APIC "spurious INTs" */
Xtimer; /* handle LAPIC timer INT */
-#ifdef SMP
inthand_t
Xinvltlb, /* TLB shootdowns */
Xcpustop, /* CPU stops & waits for another CPU to restart it */
Xipiq; /* handle lwkt_send_ipiq() requests */
-#endif
#endif /* LOCORE */
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/i386/include/lock.h,v 1.11.2.2 2000/09/30 02:49:34 ps Exp $
- * $DragonFly: src/sys/platform/pc32/include/lock.h,v 1.17 2008/06/19 21:32:55 aggelos Exp $
*/
#ifndef _MACHINE_LOCK_H_
* interrupts.
*/
-
-#ifdef SMP
-
#define SPIN_INIT(mem) \
movq $0,mem ; \
#define SPIN_UNLOCK_NOREG(mem) \
SPIN_UNLOCK(mem) ; \
-#else /* !SMP */
-
-#define SPIN_LOCK(mem) \
- pushfq ; \
- cli ; \
- orq $PSL_C,(%rsp) ; \
- popq mem ; \
-
-#define SPIN_LOCK_PUSH_RESG
-#define SPIN_LOCK_POP_REGS
-#define SPIN_LOCK_FRAME_SIZE 0
-
-#define SPIN_UNLOCK(mem) \
- pushq mem ; \
- movq $0,mem ; \
- popfq ; \
-
-#define SPIN_UNLOCK_PUSH_REGS
-#define SPIN_UNLOCK_POP_REGS
-#define SPIN_UNLOCK_FRAME_SIZE 0
-
-#endif /* SMP */
-
#else /* !LOCORE */
#ifdef _KERNEL
* from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
* from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
* $FreeBSD: src/sys/i386/include/pmap.h,v 1.65.2.3 2001/10/03 07:15:37 peter Exp $
- * $DragonFly: src/sys/platform/pc64/include/pmap.h,v 1.1 2008/08/29 17:07:17 dillon Exp $
*/
#ifndef _MACHINE_PMAP_H_
void *pmap_mapdev_uncacheable(vm_paddr_t, vm_size_t);
void pmap_unmapdev (vm_offset_t, vm_size_t);
struct vm_page *pmap_use_pt (pmap_t, vm_offset_t);
-#ifdef SMP
void pmap_set_opt (void);
-#endif
vm_paddr_t pmap_kextract(vm_offset_t);
#endif /* _KERNEL */
* ----------------------------------------------------------------------------
*
* $FreeBSD: src/sys/i386/include/smp.h,v 1.50.2.5 2001/02/13 22:32:45 tegge Exp $
- * $DragonFly: src/sys/platform/pc32/include/smp.h,v 1.20 2006/11/07 06:43:24 dillon Exp $
- *
*/
#ifndef _MACHINE_SMP_H_
#endif /* LOCORE */
-#if defined(SMP)
-
#ifndef LOCORE
/*
}
#endif /* !LOCORE */
-#else /* !SMP */
-
-#define smp_active_mask 1 /* smp_active_mask always 1 on UP machines */
-
-#endif
#endif /* _KERNEL */
#endif /* _MACHINE_SMP_H_ */
}
#define mycpu _get_mycpu()
-
-#ifdef SMP
#define mycpuid (_get_mycpu()->gd_cpuid)
-#else
-#define mycpuid 0
-#endif
/*
* note: curthread is never NULL, but curproc can be. Also note that
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/bus.h>
-#ifndef SMP
-#include <sys/lock.h>
-#endif
#include <sys/sysctl.h>
#include <sys/cons.h>
#include <sys/systimer.h>
{
static sysclock_t sysclock_count; /* NOTE! Must be static */
struct globaldata *gd = mycpu;
-#ifdef SMP
struct globaldata *gscan;
int n;
-#endif
/*
* SWSTROBE mode is a one-shot, the timer is no longer running
* usually *ALL* of them. We need to use the LAPIC timer for this.
*/
sysclock_count = sys_cputimer->count();
-#ifdef SMP
for (n = 0; n < ncpus; ++n) {
gscan = globaldata_find(n);
if (TAILQ_FIRST(&gscan->gd_systimerq) == NULL)
systimer_intr(&sysclock_count, 0, frame_arg);
}
}
-#else
- if (TAILQ_FIRST(&gd->gd_systimerq) != NULL)
- systimer_intr(&sysclock_count, 0, frame_arg);
-#endif
}
}
EVENTHANDLER_REGISTER(shutdown_post_sync, resettodr_on_shutdown, NULL, SHUTDOWN_PRI_LAST);
-
-#if !defined(SMP)
- /*
- * We can not use the TSC in SMP mode, until we figure out a
- * cheap (impossible), reliable and precise (yeah right!) way
- * to synchronize the TSCs of all the CPUs.
- * Curse Intel for leaving the counter out of the I/O APIC.
- */
-
-#if NAPM > 0
- /*
- * We can not use the TSC if we support APM. Precise timekeeping
- * on an APM'ed machine is at best a fools pursuit, since
- * any and all of the time spent in various SMM code can't
- * be reliably accounted for. Reading the RTC is your only
- * source of reliable time info. The i8254 looses too of course
- * but we need to have some kind of time...
- * We don't know at this point whether APM is going to be used
- * or not, nor when it might be activated. Play it safe.
- */
- return;
-#endif /* NAPM > 0 */
-
-#endif /* !defined(SMP) */
}
/*
{
u_int count;
int delta;
-#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP) && \
- defined(PERFMON) && defined(I586_PMC_GUPROF)
- u_quad_t event_count;
-#endif
u_char high, low;
static u_int prev_count;
-#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP)
- if (cputime_clock == CPUTIME_CLOCK_TSC) {
- count = (u_int)rdtsc();
- delta = (int)(count - prev_count);
- prev_count = count;
- return (delta);
- }
-#if defined(PERFMON) && defined(I586_PMC_GUPROF)
- if (cputime_clock == CPUTIME_CLOCK_I586_PMC) {
- /*
- * XXX permon_read() should be inlined so that the
- * perfmon module doesn't need to be compiled with
- * profiling disabled and so that it is fast.
- */
- perfmon_read(0, &event_count);
-
- count = (u_int)event_count;
- delta = (int)(count - prev_count);
- prev_count = count;
- return (delta);
- }
-#endif /* PERFMON && I586_PMC_GUPROF */
-#endif /* (I586_CPU || I686_CPU) && !SMP */
-
/*
* Read the current value of the 8254 timer counter 0.
*/
void
startguprof(struct gmonparam *gp)
{
- if (cputime_clock == CPUTIME_CLOCK_UNINITIALIZED) {
+ if (cputime_clock == CPUTIME_CLOCK_UNINITIALIZED)
cputime_clock = CPUTIME_CLOCK_I8254;
-#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP)
- if (tsc_frequency != 0)
- cputime_clock = CPUTIME_CLOCK_TSC;
-#endif
- }
gp->profrate = timer_freq << CPUTIME_CLOCK_I8254_SHIFT;
-#if (defined(I586_CPU) || defined(I686_CPU)) && !defined(SMP)
- if (cputime_clock == CPUTIME_CLOCK_TSC)
- gp->profrate = (u_int)tsc_frequency; /* XXX */
-#if defined(PERFMON) && defined(I586_PMC_GUPROF)
- else if (cputime_clock == CPUTIME_CLOCK_I586_PMC) {
- if (perfmon_avail() &&
- perfmon_setup(0, cputime_clock_pmc_conf) == 0) {
- if (perfmon_start(0) != 0)
- perfmon_fini(0);
- else {
- /* XXX 1 event == 1 us. */
- gp->profrate = 1000000;
-
- saved_gmp = *gp;
-
- /* Zap overheads. They are invalid. */
- gp->cputime_overhead = 0;
- gp->mcount_overhead = 0;
- gp->mcount_post_overhead = 0;
- gp->mcount_pre_overhead = 0;
- gp->mexitcount_overhead = 0;
- gp->mexitcount_post_overhead = 0;
- gp->mexitcount_pre_overhead = 0;
-
- cputime_clock_pmc_init = TRUE;
- }
- }
- }
-#endif /* PERFMON && I586_PMC_GUPROF */
-#endif /* (I586_CPU || I686_CPU) && !SMP */
cputime_bias = 0;
cputime();
}
static void
amd64_mrstore(struct mem_range_softc *sc)
{
-#ifdef SMP
/*
* We should use ipi_all_but_self() to call other CPUs into a
* locking gate, then call a target function to do this work.
* implementation, not ready yet.
*/
lwkt_send_ipiq_mask(smp_active_mask, (void *)amd64_mrstoreone, sc);
-#else
- crit_enter();
- amd64_mrstoreone(sc);
- crit_exit();
-#endif
}
/*
static void
amd64_mrreinit(struct mem_range_softc *sc)
{
-#ifdef SMP
/*
* We should use ipi_all_but_self() to call other CPUs into a
* locking gate, then call a target function to do this work.
* implementation, not ready yet.
*/
lwkt_send_ipiq_mask(smp_active_mask, (void *)amd64_mrAPinit, sc);
-#else
- crit_enter();
- amd64_mrAPinit(sc);
- crit_exit();
-#endif
}
static void
int map_count;
bus_dma_segment_t *segments;
struct bounce_zone *bounce_zone;
-#ifdef SMP
struct spinlock spin;
-#else
- int unused0;
-#endif
};
/*
STAILQ_ENTRY(bounce_zone) links;
STAILQ_HEAD(bp_list, bounce_page) bounce_page_list;
STAILQ_HEAD(, bus_dmamap) bounce_map_waitinglist;
-#ifdef SMP
struct spinlock spin;
-#else
- int unused0;
-#endif
int total_bpages;
int free_bpages;
int reserved_bpages;
struct sysctl_oid *sysctl_tree;
};
-#ifdef SMP
#define BZ_LOCK(bz) spin_lock(&(bz)->spin)
#define BZ_UNLOCK(bz) spin_unlock(&(bz)->spin)
-#else
-#define BZ_LOCK(bz) crit_enter()
-#define BZ_UNLOCK(bz) crit_exit()
-#endif
static struct lwkt_token bounce_zone_tok =
LWKT_TOKEN_INITIALIZER(bounce_zone_token);
if (tag->nsegments <= BUS_DMA_CACHE_SEGMENTS)
return(cache);
-#ifdef SMP
spin_lock(&tag->spin);
-#endif
return(tag->segments);
}
void
bus_dma_tag_unlock(bus_dma_tag_t tag)
{
-#ifdef SMP
if (tag->flags & BUS_DMA_PROTECTED)
return;
if (tag->nsegments > BUS_DMA_CACHE_SEGMENTS)
spin_unlock(&tag->spin);
-#endif
}
/*
newtag = kmalloc(sizeof(*newtag), M_DEVBUF, M_INTWAIT | M_ZERO);
-#ifdef SMP
spin_init(&newtag->spin);
-#endif
newtag->parent = parent;
newtag->alignment = alignment;
newtag->boundary = boundary;
}
bz = new_bz;
-#ifdef SMP
spin_init(&bz->spin);
-#endif
STAILQ_INIT(&bz->bounce_page_list);
STAILQ_INIT(&bz->bounce_map_waitinglist);
bz->free_bpages = 0;
ddb_regs = *regs;
crit_enter();
-#ifdef SMP
db_printf("\nCPU%d stopping CPUs: 0x%08jx\n",
mycpu->gd_cpuid, (uintmax_t)mycpu->gd_other_cpus);
stop_cpus(mycpu->gd_other_cpus);
db_printf(" stopped\n");
-#endif /* SMP */
setjmp(db_global_jmpbuf);
db_global_jmpbuf_valid = TRUE;
/* vcons_set_mode(0); */
db_global_jmpbuf_valid = FALSE;
-#ifdef SMP
db_printf("\nCPU%d restarting CPUs: 0x%016jx\n",
mycpu->gd_cpuid, (uintmax_t)stopped_cpus);
restart_cpus(stopped_cpus);
db_printf(" restarted\n");
-#endif /* SMP */
crit_exit();
regs->tf_rip = ddb_regs.tf_rip;
ASSYM(MACHINTR_INTREN, offsetof(struct machintr_abi, intr_enable));
ASSYM(TDPRI_INT_SUPPORT, TDPRI_INT_SUPPORT);
-#ifdef SMP
ASSYM(CPUMASK_LOCK, CPUMASK_LOCK);
ASSYM(CPUMASK_BIT, CPUMASK_BIT);
-#endif
ASSYM(IOAPIC_IRQI_ADDR, offsetof(struct ioapic_irqinfo, io_addr));
ASSYM(IOAPIC_IRQI_IDX, offsetof(struct ioapic_irqinfo, io_idx));
cli /* re-assert cli on loop */
movq %rax,%rcx /* irq mask unavailable due to BGL */
notq %rcx
-#ifdef SMP
testl $RQF_IPIQ,PCPU(reqflags)
jnz doreti_ipiq
-#endif
testl $RQF_TIMER,PCPU(reqflags)
jnz doreti_timer
/*
movl %r12d,%eax /* restore cpl for loop */
jmp doreti_next
-#ifdef SMP
/*
* IPIQ message pending. We clear RQF_IPIQ automatically.
*/
decl PCPU(intr_nesting_level)
movl %r12d,%eax /* restore cpl for loop */
jmp doreti_next
-#endif
doreti_timer:
movl %eax,%r12d /* save cpl (can't use stack) */
cli
movq %rax,%rcx /* rcx = ~CPL */
notq %rcx
-#ifdef SMP
testl $RQF_IPIQ,PCPU(reqflags)
jnz splz_ipiq
-#endif
testl $RQF_TIMER,PCPU(reqflags)
jnz splz_timer
/*
popq %rax
jmp splz_next
-#ifdef SMP
splz_ipiq:
andl $~RQF_IPIQ,PCPU(reqflags)
sti
call lwkt_process_ipiq
popq %rax
jmp splz_next
-#endif
splz_timer:
andl $~RQF_TIMER,PCPU(reqflags)
int _udatasel, _ucodesel, _ucode32sel;
u_long atdevbase;
-#ifdef SMP
int64_t tsc_offsets[MAXCPU];
-#else
-int64_t tsc_offsets[1];
-#endif
#if defined(SWTCH_OPTIM_STATS)
extern int swtch_optim_stats;
}
}
-#ifdef SMP
-
/*
* This routine is called if a spinlock has been held through the
* exponential backoff period and is seriously contested. On a real cpu
cpu_pause();
}
-#endif
-
/*
* Clear registers on exec
*/
}
base_memory = physmap[1] / 1024;
-#ifdef SMP
/* make hole for AP bootstrap code */
physmap[1] = mp_bootaddress(base_memory);
-#endif
/* Save EBDA address, if any */
ebda_addr = (u_long)(*(u_short *)(KERNBASE + 0x40e));
static void
init_locks(void)
{
-#ifdef SMP
/*
* Get the initial mplock with a count of 1 for the BSP.
* This uses a LOGICAL cpu ID, ie BSP == 0.
*/
cpu_get_initial_mplock();
-#endif
/* DEPRECATED */
spin_lock_init(&mcount_spinlock);
spin_lock_init(&intr_spinlock);
#include <sys/thread2.h>
#include <sys/mplock2.h>
-#ifndef SMP
-#include <machine/asmacros.h>
-#endif
#include <machine/cputypes.h>
#include <machine/frame.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/psl.h>
-#ifndef SMP
-#include <machine/clock.h>
-#endif
#include <machine/specialreg.h>
#include <machine/segments.h>
#include <machine/globaldata.h>
* cases rather then invl1pg. Actually, I don't even know why it
* works under UP because self-referential page table mappings
*/
-#ifdef SMP
pgeflag = 0;
-#else
- if (cpu_feature & CPUID_PGE)
- pgeflag = PG_G;
-#endif
-
+
/*
* Initialize the 4MB page size flag
*/
ptditmp &= ~(NBPDR - 1);
ptditmp |= PG_V | PG_RW | PG_PS | PG_U | pgeflag;
pdir4mb = ptditmp;
-
-#ifndef SMP
- /*
- * Enable the PSE mode. If we are SMP we can't do this
- * now because the APs will not be able to use it when
- * they boot up.
- */
- load_cr4(rcr4() | CR4_PSE);
-
- /*
- * We can do the mapping here for the single processor
- * case. We simply ignore the old page table page from
- * now on.
- */
- /*
- * For SMP, we still need 4K pages to bootstrap APs,
- * PSE will be enabled as soon as all APs are up.
- */
- PTD[KPTDI] = (pd_entry_t)ptditmp;
- cpu_invltlb();
-#endif
}
#endif
cpu_invltlb();
}
-#ifdef SMP
/*
* Set 4mb pdir for mp startup
*/
}
}
}
-#endif
/*
* Initialize the pmap module.
* the pmap_inval_*() API that is)... it's ok to do this for simple
* wiring changes.
*/
-#ifdef SMP
if (wired)
atomic_set_long(ptep, PG_W);
else
atomic_clear_long(ptep, PG_W);
-#else
- if (wired)
- atomic_set_long_nonlocked(ptep, PG_W);
- else
- atomic_clear_long_nonlocked(ptep, PG_W);
-#endif
pv_put(pv);
lwkt_reltoken(&pmap->pm_token);
}
continue;
pte = pmap_pte_quick(pv->pv_pmap, pv->pv_pindex << PAGE_SHIFT);
if (pte && (*pte & PG_A)) {
-#ifdef SMP
atomic_clear_long(pte, PG_A);
-#else
- atomic_clear_long_nonlocked(pte, PG_A);
-#endif
rtval++;
if (rtval > 4)
break;
lp->lwp_vmspace = newvm;
if (curthread->td_lwp == lp) {
pmap = vmspace_pmap(newvm);
-#if defined(SMP)
atomic_set_cpumask(&pmap->pm_active, mycpu->gd_cpumask);
if (pmap->pm_active & CPUMASK_LOCK)
pmap_interlock_wait(newvm);
-#else
- pmap->pm_active |= 1;
-#endif
#if defined(SWTCH_OPTIM_STATS)
tlb_flush_count++;
#endif
curthread->td_pcb->pcb_cr3 |= PG_RW | PG_U | PG_V;
load_cr3(curthread->td_pcb->pcb_cr3);
pmap = vmspace_pmap(oldvm);
-#if defined(SMP)
atomic_clear_cpumask(&pmap->pm_active, mycpu->gd_cpumask);
-#else
- pmap->pm_active &= ~(cpumask_t)1;
-#endif
}
crit_exit();
}
}
-#ifdef SMP
-
/*
* Called when switching to a locked pmap, used to interlock against pmaps
* undergoing modifications to prevent us from activating the MMU for the
}
}
-#endif
-
vm_offset_t
pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
{
pmap_inval_interlock(pmap_inval_info_t info, pmap_t pmap, vm_offset_t va)
{
cpumask_t oactive;
-#ifdef SMP
cpumask_t nactive;
DEBUG_PUSH_INFO("pmap_inval_interlock");
cpu_pause();
}
DEBUG_POP_INFO();
-#else
- oactive = pmap->pm_active & ~CPUMASK_LOCK;
-#endif
KKASSERT((info->pir_flags & PIRF_CPUSYNC) == 0);
info->pir_va = va;
info->pir_flags = PIRF_CPUSYNC;
pmap_inval_deinterlock(pmap_inval_info_t info, pmap_t pmap)
{
KKASSERT(info->pir_flags & PIRF_CPUSYNC);
-#ifdef SMP
atomic_clear_cpumask(&pmap->pm_active, CPUMASK_LOCK);
-#endif
lwkt_cpusync_deinterlock(&info->pir_cpusync);
info->pir_flags = 0;
}
ja fusufault
movl %esi,%eax /* old */
-#ifdef SMP
lock
-#endif
cmpxchgl %edx,(%rdi) /* new = %edx */
/*
ja fusufault
movq %rsi,%rax /* old */
-#ifdef SMP
lock
-#endif
cmpxchgq %rdx,(%rdi) /* new = %rdx */
/*
#include "assym.s"
-#if defined(SMP)
#define MPLOCKED lock ;
-#else
-#define MPLOCKED
-#endif
.data
*/
movq TD_LWP(%rax),%rcx
movq LWP_VMSPACE(%rcx),%rcx /* RCX = vmspace */
-#ifdef SMP
movq %rax,%r12 /* save newthread ptr */
1:
movq VM_PMAP+PM_ACTIVE(%rcx),%rax /* old contents */
jmp 2f /* unconditional reload */
1:
movq %r12,%rax /* restore RAX = newthread */
-#else
- movq PCPU(cpumask),%rsi
- orq %rsi,VM_PMAP+PM_ACTIVE(%rcx)
-#endif
/*
* Restore the MMU address space. If it is the same as the last
* thread we don't have to invalidate the tlb (i.e. reload cr3).
movq %rcx,%cr3
andl $~TDF_RUNNING,TD_FLAGS(%rbx)
orl $TDF_RUNNING,TD_FLAGS(%rax) /* manual, no switch_return */
-#ifdef SMP
cmpl $0,PCPU(cpuid)
je 1f
call ap_init
1:
-#endif
/*
* ap_init can decide to enable interrupts early, but otherwise, or if
* we are UP, do it here.
#include <sys/thread2.h>
#include <sys/mplock2.h>
-#ifdef SMP
-
#define MAKEMPSAFE(have_mplock) \
if (have_mplock == 0) { \
get_mplock(); \
have_mplock = 1; \
}
-#else
-
-#define MAKEMPSAFE(have_mplock)
-
-#endif
-
extern void trap(struct trapframe *frame);
static int trap_pfault(struct trapframe *, int);
struct proc *p;
int sticks = 0;
int i = 0, ucode = 0, type, code;
-#ifdef SMP
int have_mplock = 0;
-#endif
#ifdef INVARIANTS
int crit_count = td->td_critcount;
lwkt_tokref_t curstop = td->td_toks_stop;
userret(lp, frame, sticks);
userexit(lp);
out2: ;
-#ifdef SMP
if (have_mplock)
rel_mplock();
-#endif
if (p != NULL && lp != NULL)
KTR_LOG(kernentry_trap_ret, p->p_pid, lp->lwp_tid);
#ifdef INVARIANTS
msg = "UNKNOWN";
kprintf("\n\nFatal trap %d: %s while in %s mode\n", type, msg,
ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel");
-#ifdef SMP
/* three separate prints in case of a trap on an unmapped page */
kprintf("cpuid = %d; ", mycpu->gd_cpuid);
kprintf("lapic->id = %08x\n", lapic->id);
-#endif
if (type == T_PAGEFLT) {
kprintf("fault virtual address = 0x%lx\n", eva);
kprintf("fault code = %s %s %s, %s\n",
kprintf("rip = 0x%lx\n", frame->tf_rip);
kprintf("rsp = 0x%lx\n", frame->tf_rsp);
kprintf("rbp = 0x%lx\n", frame->tf_rbp);
-#ifdef SMP
/* three separate prints in case of a trap on an unmapped page */
kprintf("cpuid = %d; ", mycpu->gd_cpuid);
kprintf("lapic->id = %08x\n", lapic->id);
-#endif
panic("double fault");
}
#ifdef INVARIANTS
int crit_count = td->td_critcount;
#endif
-#ifdef SMP
int have_mplock = 0;
-#endif
register_t *argp;
u_int code;
int reg, regcnt;
STOPEVENT(p, S_SCX, code);
userexit(lp);
-#ifdef SMP
/*
* Release the MP lock if we had to get it
*/
if (have_mplock)
rel_mplock();
-#endif
KTR_LOG(kernentry_syscall_ret, p->p_pid, lp->lwp_tid, error);
#ifdef INVARIANTS
KASSERT(crit_count == td->td_critcount,
cpu/i386/misc/atomic.c standard \
compile-with "${CC} -c ${CFLAGS} ${WERROR} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}"
platform/vkernel/i386/autoconf.c standard
-platform/vkernel/i386/mp.c optional smp \
+platform/vkernel/i386/mp.c standard \
compile-with "${CC} -c -pthread ${CFLAGS} ${WERROR} -I/usr/include ${.IMPSRC}"
#
# DDB XXX
(uintmax_t)ptoa(vmstats.v_free_count) / 1024 / 1024);
bufinit();
vm_pager_bufferinit();
-#ifdef SMP
mp_start();
mp_announce();
-#endif
cpu_setregs();
}
extern void ffs_rawread_setup(void);
#endif /* DIRECTIO */
-#ifdef SMP
int64_t tsc_offsets[MAXCPU];
-#else
-int64_t tsc_offsets[1];
-#endif
#if defined(SWTCH_OPTIM_STATS)
extern int swtch_optim_stats;
if (cpu_idle_hlt &&
(td->td_gd->gd_reqflags & RQF_IDLECHECK_WK_MASK) == 0) {
splz();
-#ifdef SMP
KKASSERT(MP_LOCK_HELD() == 0);
-#endif
if ((td->td_gd->gd_reqflags & RQF_IDLECHECK_WK_MASK) == 0) {
#ifdef DEBUGIDLE
struct timeval tv1, tv2;
++cpu_idle_hltcnt;
} else {
splz();
-#ifdef SMP
__asm __volatile("pause");
-#endif
++cpu_idle_spincnt;
}
}
}
-#ifdef SMP
-
/*
* Called by the spinlock code with or without a critical section held
* when a spinlock is found to be seriously constested.
cpu_pause();
}
-#endif
-
/*
* Clear registers on exec
*/
}
crit_enter();
-#ifdef SMP
db_printf("\nCPU%d stopping CPUs: 0x%08x\n",
mycpu->gd_cpuid, mycpu->gd_other_cpus);
stop_cpus(mycpu->gd_other_cpus);
db_printf(" stopped\n");
-#endif /* SMP */
setjmp(db_global_jmpbuf);
db_global_jmpbuf_valid = TRUE;
vcons_set_mode(0);
db_global_jmpbuf_valid = FALSE;
-#ifdef SMP
db_printf("\nCPU%d restarting CPUs: 0x%016jx\n",
mycpu->gd_cpuid, (uintmax_t)stopped_cpus);
restart_cpus(stopped_cpus);
db_printf(" restarted\n");
-#endif /* SMP */
crit_exit();
regs->tf_eip = ddb_regs.tf_eip;
* 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: src/sys/platform/vkernel/i386/exception.c,v 1.11 2008/04/28 07:05:09 dillon Exp $
*/
#include "opt_ddb.h"
static void exc_debugger(int signo, siginfo_t *info, void *ctx);
#endif
-#ifdef SMP
-
/*
* IPIs are 'fast' interrupts, so we deal with them directly from our
* signal handler.
--curthread->td_critcount;
}
-#endif
-
#if 0
/*
sa.sa_sigaction = exc_debugger;
sigaction(SIGQUIT, &sa, NULL);
#endif
-#ifdef SMP
sa.sa_sigaction = ipisig;
sigaction(SIGUSR1, &sa, NULL);
sa.sa_sigaction = stopsig;
sigaction(SIGXCPU, &sa, NULL);
-#endif
#if 0
sa.sa_sigaction = iosig;
sigaction(SIGIO, &sa, NULL);