summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/mp_machdep.c205
1 files changed, 102 insertions, 103 deletions
diff --git a/sys/alpha/alpha/mp_machdep.c b/sys/alpha/alpha/mp_machdep.c
index e2a2be5..d5cc451 100644
--- a/sys/alpha/alpha/mp_machdep.c
+++ b/sys/alpha/alpha/mp_machdep.c
@@ -55,32 +55,27 @@
#define CHECKSTATE_SYS 1
#define CHECKSTATE_INTR 2
-volatile u_int stopped_cpus;
-volatile u_int started_cpus;
-volatile u_int checkstate_probed_cpus;
-volatile u_int checkstate_need_ast;
-volatile u_int checkstate_pending_ast;
-struct proc* checkstate_curproc[MAXCPU];
-int checkstate_cpustate[MAXCPU];
-u_long checkstate_pc[MAXCPU];
-volatile u_int resched_cpus;
+volatile u_int stopped_cpus;
+volatile u_int started_cpus;
+volatile u_int checkstate_probed_cpus;
+volatile u_int checkstate_need_ast;
+volatile u_int checkstate_pending_ast;
+struct proc* checkstate_curproc[MAXCPU];
+int checkstate_cpustate[MAXCPU];
+u_long checkstate_pc[MAXCPU];
+volatile u_int resched_cpus;
void (*cpustop_restartfunc) __P((void));
-int mp_ncpus;
+int mp_ncpus;
-int smp_started;
-int boot_cpu_id;
-u_int32_t all_cpus;
+int smp_started;
+int boot_cpu_id;
+u_int32_t all_cpus;
-static struct globaldata *cpuno_to_globaldata[MAXCPU];
+static struct globaldata *cpuid_to_globaldata[MAXCPU];
int smp_active = 0; /* are the APs allowed to run? */
SYSCTL_INT(_machdep, OID_AUTO, smp_active, CTLFLAG_RW, &smp_active, 0, "");
-/* Is forwarding of a interrupt to the CPU holding the ISR lock enabled ? */
-int forward_irq_enabled = 1;
-SYSCTL_INT(_machdep, OID_AUTO, forward_irq_enabled, CTLFLAG_RW,
- &forward_irq_enabled, 0, "");
-
/* Enable forwarding of a signal to a process running on a different CPU */
static int forward_signal_enabled = 1;
SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW,
@@ -96,10 +91,10 @@ SYSCTL_INT(_machdep, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
* Return 1 on failure.
*/
static int
-smp_send_secondary_command(const char *command, int cpuno)
+smp_send_secondary_command(const char *command, int cpuid)
{
- u_int64_t mask = 1L << cpuno;
- struct pcs *cpu = LOCATE_PCS(hwrpb, cpuno);
+ u_int64_t mask = 1L << cpuid;
+ struct pcs *cpu = LOCATE_PCS(hwrpb, cpuid);
int i, len;
/*
@@ -176,8 +171,8 @@ smp_init_secondary(void)
* Add to mask.
*/
smp_started = 1;
- if (PCPU_GET(cpuno) + 1 > mp_ncpus)
- mp_ncpus = PCPU_GET(cpuno) + 1;
+ if (PCPU_GET(cpuid) + 1 > mp_ncpus)
+ mp_ncpus = PCPU_GET(cpuid) + 1;
spl0();
smp_ipi_all(0);
@@ -187,9 +182,9 @@ smp_init_secondary(void)
extern void smp_init_secondary_glue(void);
static int
-smp_start_secondary(int cpuno)
+smp_start_secondary(int cpuid)
{
- struct pcs *cpu = LOCATE_PCS(hwrpb, cpuno);
+ struct pcs *cpu = LOCATE_PCS(hwrpb, cpuid);
struct pcs *bootcpu = LOCATE_PCS(hwrpb, hwrpb->rpb_primary_cpu_id);
struct alpha_pcb *pcb = (struct alpha_pcb *) cpu->pcs_hwpcb;
struct globaldata *globaldata;
@@ -197,11 +192,11 @@ smp_start_secondary(int cpuno)
size_t sz;
if ((cpu->pcs_flags & PCS_PV) == 0) {
- printf("smp_start_secondary: cpu %d PALcode invalid\n", cpuno);
+ printf("smp_start_secondary: cpu %d PALcode invalid\n", cpuid);
return 0;
}
- printf("smp_start_secondary: starting cpu %d\n", cpuno);
+ printf("smp_start_secondary: starting cpu %d\n", cpuid);
sz = round_page(UPAGES * PAGE_SIZE);
globaldata = malloc(sz, M_TEMP, M_NOWAIT);
@@ -210,7 +205,7 @@ smp_start_secondary(int cpuno)
return 0;
}
- globaldata_init(globaldata, cpuno, sz);
+ globaldata_init(globaldata, cpuid, sz);
/*
* Copy the idle pcb and setup the address to start executing.
@@ -239,7 +234,7 @@ smp_start_secondary(int cpuno)
/*
* Fire it up and hope for the best.
*/
- if (!smp_send_secondary_command("START\r\n", cpuno)) {
+ if (!smp_send_secondary_command("START\r\n", cpuid)) {
printf("smp_init_secondary: can't send START command\n");
free(globaldata, M_TEMP);
return 0;
@@ -262,34 +257,24 @@ smp_start_secondary(int cpuno)
* It worked (I think).
*/
/* if (bootverbose) */
- printf("smp_init_secondary: cpu %d started\n", cpuno);
+ printf("smp_init_secondary: cpu %d started\n", cpuid);
return 1;
}
/*
- * Initialise a struct globaldata.
+ * Register a struct globaldata.
*/
void
-globaldata_init(struct globaldata *globaldata, int cpuno, size_t sz)
+globaldata_register(struct globaldata *globaldata)
{
- bzero(globaldata, sz);
- globaldata->gd_idlepcbphys = vtophys((vm_offset_t) &globaldata->gd_idlepcb);
- globaldata->gd_idlepcb.apcb_ksp = (u_int64_t)
- ((caddr_t) globaldata + sz - sizeof(struct trapframe));
- globaldata->gd_idlepcb.apcb_ptbr = proc0.p_addr->u_pcb.pcb_hw.apcb_ptbr;
- globaldata->gd_cpuno = cpuno;
- globaldata->gd_other_cpus = all_cpus & ~(1 << cpuno);
- globaldata->gd_next_asn = 0;
- globaldata->gd_current_asngen = 1;
- globaldata->gd_cpuid = cpuno;
- cpuno_to_globaldata[cpuno] = globaldata;
+ cpuid_to_globaldata[globaldata->cpuid] = globaldata;
}
struct globaldata *
-globaldata_find(int cpuno)
+globaldata_find(int cpuid)
{
- return cpuno_to_globaldata[cpuno];
+ return cpuid_to_globaldata[cpuid];
}
/* Implementation of simplelocks */
@@ -384,18 +369,18 @@ void
mp_start()
{
int i;
- int cpuno = PCPU_GET(cpuno);
+ int cpuid = PCPU_GET(cpuid);
init_locks();
- if (cpuno + 1 > mp_ncpus)
- mp_ncpus = cpuno + 1;
+ if (cpuid + 1 > mp_ncpus)
+ mp_ncpus = cpuid + 1;
- all_cpus = 1<<cpuno;
+ all_cpus = 1<<cpuid;
for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
struct pcs *pcsp;
- if (i == cpuno)
+ if (i == cpuid)
continue;
pcsp = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off +
(i * hwrpb->rpb_pcs_size));
@@ -404,12 +389,12 @@ mp_start()
break; /* only one for now */
}
}
- PCPU_SET(other_cpus, all_cpus & ~(1<<cpuno));
+ PCPU_SET(other_cpus, all_cpus & ~(1<<cpuid));
for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
struct pcs *pcsp;
- if (i == cpuno)
+ if (i == cpuid)
continue;
pcsp = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off +
(i * hwrpb->rpb_pcs_size));
@@ -436,7 +421,7 @@ smp_invltlb()
(u_quad_t)((prof)->pr_scale)) >> 16) & ~1)
static void
-addugd_intr_forwarded(struct proc *p, int id, int *astmap)
+addupc_intr_forwarded(struct proc *p, int id, int *astmap)
{
int i;
struct uprof *prof;
@@ -446,10 +431,10 @@ addugd_intr_forwarded(struct proc *p, int id, int *astmap)
prof = &p->p_stats->p_prof;
if (pc >= prof->pr_off &&
(i = GD_TO_INDEX(pc, prof)) < prof->pr_size) {
- if ((p->p_flag & P_OWEUPC) == 0) {
+ if ((p->p_sflag & PS_OWEUPC) == 0) {
prof->pr_addr = pc;
prof->pr_ticks = 1;
- p->p_flag |= P_OWEUPC;
+ p->p_sflag |= PS_OWEUPC;
}
*astmap |= (1 << id);
}
@@ -472,10 +457,16 @@ forwarded_statclock(int id, int pscnt, int *astmap)
p = checkstate_curproc[id];
cpustate = checkstate_cpustate[id];
+ /* XXX */
+ if (p->p_ithd)
+ cpustate = CHECKSTATE_INTR;
+ else if (p == cpuid_to_globaldata[id]->gd_idleproc)
+ cpustate = CHECKSTATE_SYS;
+
switch (cpustate) {
case CHECKSTATE_USER:
- if (p->p_flag & P_PROFIL)
- addugd_intr_forwarded(p, id, astmap);
+ if (p->p_sflag & PS_PROFIL)
+ addupc_intr_forwarded(p, id, astmap);
if (pscnt > 1)
return;
p->p_uticks++;
@@ -487,7 +478,7 @@ forwarded_statclock(int id, int pscnt, int *astmap)
case CHECKSTATE_SYS:
#ifdef GPROF
/*
- * Kernel statistics are just like addugd_intr, only easier.
+ * Kernel statistics are just like addupc_intr, only easier.
*/
g = &_gmonparam;
if (g->state == GMON_PROF_ON) {
@@ -501,18 +492,17 @@ forwarded_statclock(int id, int pscnt, int *astmap)
if (pscnt > 1)
return;
- if (!p)
+ p->p_sticks++;
+ if (p == cpuid_to_globaldata[id]->gd_idleproc)
cp_time[CP_IDLE]++;
- else {
- p->p_sticks++;
+ else
cp_time[CP_SYS]++;
- }
break;
case CHECKSTATE_INTR:
default:
#ifdef GPROF
/*
- * Kernel statistics are just like addugd_intr, only easier.
+ * Kernel statistics are just like addupc_intr, only easier.
*/
g = &_gmonparam;
if (g->state == GMON_PROF_ON) {
@@ -525,25 +515,24 @@ forwarded_statclock(int id, int pscnt, int *astmap)
#endif
if (pscnt > 1)
return;
- if (p)
- p->p_iticks++;
+ KASSERT(p != NULL, ("NULL process in interrupt state"));
+ p->p_iticks++;
cp_time[CP_INTR]++;
}
- if (p != NULL) {
- schedclock(p);
+
+ schedclock(p);
- /* Update resource usage integrals and maximums. */
- if ((pstats = p->p_stats) != NULL &&
- (ru = &pstats->p_ru) != NULL &&
- (vm = p->p_vmspace) != NULL) {
- ru->ru_ixrss += pgtok(vm->vm_tsize);
- ru->ru_idrss += pgtok(vm->vm_dsize);
- ru->ru_isrss += pgtok(vm->vm_ssize);
- rss = pgtok(vmspace_resident_count(vm));
- if (ru->ru_maxrss < rss)
- ru->ru_maxrss = rss;
- }
- }
+ /* Update resource usage integrals and maximums. */
+ if ((pstats = p->p_stats) != NULL &&
+ (ru = &pstats->p_ru) != NULL &&
+ (vm = p->p_vmspace) != NULL) {
+ ru->ru_ixrss += pgtok(vm->vm_tsize);
+ ru->ru_idrss += pgtok(vm->vm_dsize);
+ ru->ru_isrss += pgtok(vm->vm_ssize);
+ rss = pgtok(vmspace_resident_count(vm));
+ if (ru->ru_maxrss < rss)
+ ru->ru_maxrss = rss;
+ }
}
#define BETTER_CLOCK_DIAGNOSTIC
@@ -686,12 +675,12 @@ forward_hardclock(int pscnt)
if (checkstate_cpustate[id] == CHECKSTATE_USER &&
timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value) &&
itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL], tick) == 0) {
- psignal(p, SIGVTALRM);
+ p->p_sflag |= PS_ALRMPEND;
map |= (1 << id);
}
if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value) &&
itimerdecr(&pstats->p_timer[ITIMER_PROF], tick) == 0) {
- psignal(p, SIGPROF);
+ p->p_sflag |= PS_PROFPEND;
map |= (1 << id);
}
}
@@ -741,10 +730,14 @@ forward_signal(struct proc *p)
return;
if (!forward_signal_enabled)
return;
+ mtx_enter(&sched_lock, MTX_SPIN);
while (1) {
- if (p->p_stat != SRUN)
+ if (p->p_stat != SRUN) {
+ mtx_exit(&sched_lock, MTX_SPIN);
return;
+ }
id = p->p_oncpu;
+ mtx_exit(&sched_lock, MTX_SPIN);
if (id == 0xff)
return;
map = (1<<id);
@@ -762,8 +755,11 @@ forward_signal(struct proc *p)
break;
}
}
- if (id == p->p_oncpu)
+ mtx_enter(&sched_lock, MTX_SPIN);
+ if (id == p->p_oncpu) {
+ mtx_exit(&sched_lock, MTX_SPIN);
return;
+ }
}
}
@@ -957,15 +953,15 @@ smp_ipi_selected(u_int32_t cpus, u_int64_t ipi)
CTR2(KTR_SMP, "smp_ipi_selected: cpus: %x ipi: %lx", cpus, ipi);
alpha_mb();
while (cpus) {
- int cpuno = ffs(cpus) - 1;
- cpus &= ~(1 << cpuno);
+ int cpuid = ffs(cpus) - 1;
+ cpus &= ~(1 << cpuid);
- globaldata = cpuno_to_globaldata[cpuno];
+ globaldata = cpuid_to_globaldata[cpuid];
if (globaldata) {
atomic_set_64(&globaldata->gd_pending_ipis, ipi);
alpha_mb();
- CTR1(KTR_SMP, "calling alpha_pal_wripir(%d)", cpuno);
- alpha_pal_wripir(cpuno);
+ CTR1(KTR_SMP, "calling alpha_pal_wripir(%d)", cpuid);
+ alpha_pal_wripir(cpuid);
}
}
}
@@ -994,7 +990,7 @@ smp_ipi_all_but_self(u_int64_t ipi)
void
smp_ipi_self(u_int64_t ipi)
{
- smp_ipi_selected(1 << PCPU_GET(cpuno), ipi);
+ smp_ipi_selected(1 << PCPU_GET(cpuid), ipi);
}
static u_int64_t
@@ -1024,7 +1020,9 @@ smp_handle_ipi(struct trapframe *frame)
{
u_int64_t ipis = atomic_readandclear(PCPU_PTR(pending_ipis));
u_int64_t ipi;
- int cpuno = PCPU_GET(cpuno);
+ int cpumask;
+
+ cpumask = 1 << PCPU_GET(cpuid);
CTR1(KTR_SMP, "smp_handle_ipi(), ipis=%lx", ipis);
while (ipis) {
@@ -1032,6 +1030,7 @@ smp_handle_ipi(struct trapframe *frame)
* Find the lowest set bit.
*/
ipi = ipis & ~(ipis - 1);
+ ipis &= ~ipi;
switch (ipi) {
case IPI_INVLTLB:
break;
@@ -1043,8 +1042,8 @@ smp_handle_ipi(struct trapframe *frame)
case IPI_AST:
CTR0(KTR_SMP, "IPI_AST");
- atomic_clear_int(&checkstate_need_ast, 1<<cpuno);
- atomic_set_int(&checkstate_pending_ast, 1<<cpuno);
+ atomic_clear_int(&checkstate_need_ast, cpumask);
+ atomic_set_int(&checkstate_pending_ast, cpumask);
if (frame->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE)
ast(frame); /* XXX */
break;
@@ -1052,22 +1051,22 @@ smp_handle_ipi(struct trapframe *frame)
case IPI_CHECKSTATE:
CTR0(KTR_SMP, "IPI_CHECKSTATE");
if (frame->tf_regs[FRAME_PS] & ALPHA_PSL_USERMODE)
- checkstate_cpustate[cpuno] = CHECKSTATE_USER;
+ checkstate_cpustate[cpuid] = CHECKSTATE_USER;
else if (curproc->p_intr_nesting_level == 1)
- checkstate_cpustate[cpuno] = CHECKSTATE_SYS;
+ checkstate_cpustate[cpuid] = CHECKSTATE_SYS;
else
- checkstate_cpustate[cpuno] = CHECKSTATE_INTR;
- checkstate_curproc[cpuno] = PCPU_GET(curproc);
- atomic_set_int(&checkstate_probed_cpus, 1<<cpuno);
+ checkstate_cpustate[cpuid] = CHECKSTATE_INTR;
+ checkstate_curproc[cpuid] = PCPU_GET(curproc);
+ atomic_set_int(&checkstate_probed_cpus, cpumask);
break;
case IPI_STOP:
CTR0(KTR_SMP, "IPI_STOP");
- atomic_set_int(&stopped_cpus, 1<<cpuno);
- while ((started_cpus & (1<<cpuno)) == 0)
+ atomic_set_int(&stopped_cpus, cpumask);
+ while ((started_cpus & cpumask) == 0)
alpha_mb();
- atomic_clear_int(&started_cpus, 1<<cpuno);
- atomic_clear_int(&stopped_cpus, 1<<cpuno);
+ atomic_clear_int(&started_cpus, cpumask);
+ atomic_clear_int(&stopped_cpus, cpumask);
break;
}
}
@@ -1075,7 +1074,7 @@ smp_handle_ipi(struct trapframe *frame)
/*
* Drop console messages on the floor.
*/
- if (PCPU_GET(cpuno) == hwrpb->rpb_primary_cpu_id
+ if (PCPU_GET(cpuid) == hwrpb->rpb_primary_cpu_id
&& hwrpb->rpb_txrdy != 0) {
hwrpb->rpb_txrdy = 0;
alpha_mb();
OpenPOWER on IntegriCloud