- Move the code to deal with handling an IPI_STOP IPI out of
ipi_nmi_handler() and into a new cpustop_handler() function. Change the Xcpustop IPI_STOP handler to call this function instead of duplicating all the same logic in assembly. - EOI the local APIC for the lapic timer interrupt in C rather than assembly. - Bump the lazypmap IPI counter if COUNT_IPIS is defined in C rather than assembly.
This commit is contained in:
parent
7e70788a5c
commit
f0b9813920
@ -102,10 +102,6 @@ IDTVEC(spuriousint)
|
||||
IDTVEC(timerint)
|
||||
PUSH_FRAME
|
||||
SET_KERNEL_SREGS
|
||||
|
||||
movl lapic, %edx
|
||||
movl $0, LA_EOI(%edx) /* End Of Interrupt to APIC */
|
||||
|
||||
FAKE_MCOUNT(TF_EIP(%esp))
|
||||
|
||||
pushl $0 /* XXX convert trapframe to clockframe */
|
||||
@ -260,11 +256,7 @@ IDTVEC(ipi_intr_bitmap_handler)
|
||||
jmp doreti
|
||||
|
||||
/*
|
||||
* Executed by a CPU when it receives an Xcpustop IPI from another CPU,
|
||||
*
|
||||
* - Signals its receipt.
|
||||
* - Waits for permission to restart.
|
||||
* - Signals its restart.
|
||||
* Executed by a CPU when it receives an IPI_STOP from another CPU.
|
||||
*/
|
||||
.text
|
||||
SUPERALIGN_TEXT
|
||||
@ -275,36 +267,8 @@ IDTVEC(cpustop)
|
||||
movl lapic, %eax
|
||||
movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */
|
||||
|
||||
movl PCPU(CPUID), %eax
|
||||
imull $PCB_SIZE, %eax
|
||||
leal CNAME(stoppcbs)(%eax), %eax
|
||||
pushl %eax
|
||||
call CNAME(savectx) /* Save process context */
|
||||
addl $4, %esp
|
||||
call cpustop_handler
|
||||
|
||||
movl PCPU(CPUID), %eax
|
||||
|
||||
lock
|
||||
btsl %eax, CNAME(stopped_cpus) /* stopped_cpus |= (1<<id) */
|
||||
1:
|
||||
btl %eax, CNAME(started_cpus) /* while (!(started_cpus & (1<<id))) */
|
||||
jnc 1b
|
||||
|
||||
lock
|
||||
btrl %eax, CNAME(started_cpus) /* started_cpus &= ~(1<<id) */
|
||||
lock
|
||||
btrl %eax, CNAME(stopped_cpus) /* stopped_cpus &= ~(1<<id) */
|
||||
|
||||
test %eax, %eax
|
||||
jnz 2f
|
||||
|
||||
movl CNAME(cpustop_restartfunc), %eax
|
||||
test %eax, %eax
|
||||
jz 2f
|
||||
movl $0, CNAME(cpustop_restartfunc) /* One-shot */
|
||||
|
||||
call *%eax
|
||||
2:
|
||||
POP_FRAME
|
||||
iret
|
||||
|
||||
@ -340,11 +304,6 @@ IDTVEC(lazypmap)
|
||||
PUSH_FRAME
|
||||
SET_KERNEL_SREGS
|
||||
|
||||
#ifdef COUNT_IPIS
|
||||
movl PCPU(CPUID), %eax
|
||||
movl ipi_lazypmap_counts(,%eax,4), %eax
|
||||
incl (%eax)
|
||||
#endif
|
||||
call pmap_lazyfix_action
|
||||
|
||||
movl lapic, %eax
|
||||
|
@ -623,6 +623,10 @@ lapic_handle_timer(struct clockframe frame)
|
||||
{
|
||||
struct lapic *la;
|
||||
|
||||
/* Send EOI first thing. */
|
||||
lapic_eoi();
|
||||
|
||||
/* Look up our local APIC structure for the tick counters. */
|
||||
la = &lapics[PCPU_GET(apic_id)];
|
||||
(*la->la_timer_count)++;
|
||||
critical_enter();
|
||||
|
@ -1276,15 +1276,29 @@ ipi_nmi_selected(u_int32_t cpus)
|
||||
}
|
||||
|
||||
int
|
||||
ipi_nmi_handler()
|
||||
ipi_nmi_handler(void)
|
||||
{
|
||||
int cpu = PCPU_GET(cpuid);
|
||||
int cpumask = PCPU_GET(cpumask);
|
||||
|
||||
if (!(ipi_nmi_pending & cpumask))
|
||||
return 1;
|
||||
|
||||
atomic_clear_int(&ipi_nmi_pending, cpumask);
|
||||
cpustop_handler();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* STOP_NMI */
|
||||
|
||||
/*
|
||||
* Handle an IPI_STOP by saving our current context and spinning until we
|
||||
* are resumed.
|
||||
*/
|
||||
void
|
||||
cpustop_handler(void)
|
||||
{
|
||||
int cpu = PCPU_GET(cpuid);
|
||||
int cpumask = PCPU_GET(cpumask);
|
||||
|
||||
savectx(&stoppcbs[cpu]);
|
||||
|
||||
@ -1302,12 +1316,8 @@ ipi_nmi_handler()
|
||||
cpustop_restartfunc();
|
||||
cpustop_restartfunc = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* STOP_NMI */
|
||||
|
||||
/*
|
||||
* This is called once the rest of the system is up and running and we're
|
||||
* ready to let the AP's out of the pen.
|
||||
|
@ -106,6 +106,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "opt_cpu.h"
|
||||
#include "opt_pmap.h"
|
||||
#include "opt_msgbuf.h"
|
||||
#include "opt_smp.h"
|
||||
#include "opt_xbox.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -1224,6 +1225,9 @@ pmap_lazyfix_action(void)
|
||||
{
|
||||
u_int mymask = PCPU_GET(cpumask);
|
||||
|
||||
#ifdef COUNT_IPIS
|
||||
*ipi_lazypmap_counts[PCPU_GET(cpuid)]++;
|
||||
#endif
|
||||
if (rcr3() == lazyptd)
|
||||
load_cr3(PCPU_GET(curpcb)->pcb_cr3);
|
||||
atomic_clear_int(lazymask, mymask);
|
||||
|
@ -35,6 +35,13 @@ extern int mp_naps;
|
||||
extern int boot_cpu_id;
|
||||
extern struct pcb stoppcbs[];
|
||||
extern struct mtx smp_tlb_mtx;
|
||||
#ifdef COUNT_IPIS
|
||||
extern u_long *ipi_invltlb_counts[MAXCPU];
|
||||
extern u_long *ipi_invlrng_counts[MAXCPU];
|
||||
extern u_long *ipi_invlpg_counts[MAXCPU];
|
||||
extern u_long *ipi_rendezvous_counts[MAXCPU];
|
||||
extern u_long *ipi_lazypmap_counts[MAXCPU];
|
||||
#endif
|
||||
|
||||
/* IPI handlers */
|
||||
inthand_t
|
||||
@ -48,6 +55,7 @@ inthand_t
|
||||
|
||||
/* functions in mp_machdep.c */
|
||||
void cpu_add(u_int apic_id, char boot_cpu);
|
||||
void cpustop_handler(void);
|
||||
void init_secondary(void);
|
||||
void ipi_selected(u_int cpus, u_int ipi);
|
||||
void ipi_all(u_int ipi);
|
||||
|
Loading…
Reference in New Issue
Block a user