Port-sparc64 archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: sparc[64] smp
>>> Martin Husemann <martin%duskware.de@localhost> wrote
> Not quite, sorry. Loking is solved "good enough" now (or so I think), but
> tlb shootdown is not completely adapted (actually it is mostly disabled
> right now) and some interrupt changes are missing. I'm working on it.
I made a patch to make interrupt pending list per-CPU and tickintr
MP-safe. (and remove unused port-sparc derived interrupt code.)
Please review this patch.
-- Takeshi Nakayama
Index: include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/include/cpu.h,v
retrieving revision 1.74
diff -u -d -r1.74 cpu.h
--- include/cpu.h 28 Feb 2008 11:50:40 -0000 1.74
+++ include/cpu.h 2 Mar 2008 12:50:10 -0000
@@ -70,6 +70,7 @@
#include <sparc64/sparc64/intreg.h>
#include <sys/cpu_data.h>
+#include <sys/evcnt.h>
/*
* The cpu_info structure is part of a 64KB structure mapped both the kernel
* pmap and a single locked TTE a CPUINFO_VA for that particular processor.
@@ -124,6 +125,11 @@
u_long ci_tick_increment;
uint64_t ci_cpu_clockrate[2];
+ /* Interrupts */
+ struct intrhand *ci_intrpending[16];
+ struct intrhand *ci_intrlev0;
+ struct evcnt ci_tick_evcnt;
+
int ci_flags;
int ci_want_ast;
int ci_want_resched;
@@ -317,6 +323,7 @@
int tickintr(void *); /* level 10 (tick) interrupt code */
int clockintr(void *); /* level 10 (clock) interrupt code */
int statintr(void *); /* level 14 (statclock) interrupt code */
+void tickintr_establish(void);
/* locore.s */
struct fpstate64;
void savefpstate(struct fpstate64 *);
Index: sparc64/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/clock.c,v
retrieving revision 1.88
diff -u -d -r1.88 clock.c
--- sparc64/clock.c 17 Oct 2007 19:57:30 -0000 1.88
+++ sparc64/clock.c 2 Mar 2008 12:50:10 -0000
@@ -112,11 +112,9 @@
int schedintr(void *);
static struct intrhand level10 = { .ih_fun = clockintr };
-static struct intrhand level0 = { .ih_fun = tickintr };
static struct intrhand level14 = { .ih_fun = statintr };
static struct intrhand schedint = { .ih_fun = schedintr };
-void tickintr_establish(void);
static int timermatch(struct device *, struct cfdata *, void *);
static void timerattach(struct device *, struct device *, void *);
@@ -262,21 +260,23 @@
void
tickintr_establish()
{
- static bool done = false; /* only do this once */
+ struct intrhand *ih;
- if (!done) {
- done = true;
+ ih = malloc(sizeof(struct intrhand), M_DEVBUF, M_NOWAIT|M_ZERO);
+ KASSERT(ih != NULL);
- level0.ih_clr = 0;
- /*
- * Establish a level 10 interrupt handler
- *
- * We will have a conflict with the softint handler,
- * so we set the ih_number to 1.
- */
- level0.ih_number = 1;
- intr_establish(10, &level0);
+ ih->ih_fun = tickintr;
+ ih->ih_arg = 0;
+ ih->ih_clr = 0;
+ ih->ih_number = 1;
+ if (CPU_IS_PRIMARY(curcpu()))
+ intr_establish(10, ih);
+ else {
+ ih->ih_pil = 10;
+ ih->ih_pending = 0;
+ ih->ih_next = NULL;
}
+ curcpu()->ci_intrlev0 = ih;
/* set the next interrupt time */
curcpu()->ci_tick_increment = curcpu()->ci_cpu_clockrate[0] / hz;
@@ -476,6 +476,7 @@
/* Reset the interrupt */
next_tick(curcpu()->ci_tick_increment);
splx(s);
+ curcpu()->ci_tick_evcnt.ev_count++;
return (1);
}
Index: sparc64/cpu.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/cpu.c,v
retrieving revision 1.67
diff -u -d -r1.67 cpu.c
--- sparc64/cpu.c 28 Feb 2008 11:50:40 -0000 1.67
+++ sparc64/cpu.c 2 Mar 2008 12:50:10 -0000
@@ -54,6 +54,8 @@
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.67 2008/02/28 11:50:40 martin Exp $");
+#include "opt_multiprocessor.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
@@ -150,13 +152,16 @@
cpi->ci_self = cpi;
cpi->ci_node = cpu_node;
cpi->ci_idepth = -1;
+ memset(cpi->ci_intrpending, -1, sizeof(cpi->ci_intrpending));
/*
* Finally, add itself to the list of active cpus.
*/
for (ci = cpus; ci->ci_next != NULL; ci = ci->ci_next)
;
+#ifdef MULTIPROCESSOR
ci->ci_next = cpi;
+#endif
return (cpi);
}
@@ -231,6 +236,8 @@
mi_cpu_attach(ci);
ci->ci_cpcb = (struct pcb *)ci->ci_data.cpu_idlelwp->l_addr;
}
+ evcnt_attach_dynamic(&ci->ci_tick_evcnt, EVCNT_TYPE_INTR, NULL,
+ dev->dv_xname, "timer");
#endif
clk = prom_getpropint(node, "clock-frequency", 0);
@@ -401,6 +408,7 @@
cpu_reset_fpustate();
curlwp = curcpu()->ci_data.cpu_idlelwp;
membar_sync();
+ tickintr_establish();
spl0();
}
#endif /* MULTIPROCESSOR */
Index: sparc64/genassym.cf
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/genassym.cf,v
retrieving revision 1.52
diff -u -d -r1.52 genassym.cf
--- sparc64/genassym.cf 28 Feb 2008 11:50:40 -0000 1.52
+++ sparc64/genassym.cf 2 Mar 2008 12:50:10 -0000
@@ -173,6 +173,8 @@
define CI_IDLELWP offsetof(struct cpu_info, ci_data.cpu_idlelwp)
define CI_CLOCKRATE offsetof(struct cpu_info, ci_cpu_clockrate)
define CI_IDEPTH offsetof(struct cpu_info, ci_idepth)
+define CI_INTRPENDING offsetof(struct cpu_info, ci_intrpending)
+define CI_INTRLEV0 offsetof(struct cpu_info, ci_intrlev0)
define CI_CTXBUSY offsetof(struct cpu_info, ci_ctxbusy)
define CI_TSB_DMMU offsetof(struct cpu_info, ci_tsb_dmmu)
define CI_TSB_IMMU offsetof(struct cpu_info, ci_tsb_immu)
Index: sparc64/intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/intr.c,v
retrieving revision 1.55
diff -u -d -r1.55 intr.c
--- sparc64/intr.c 18 Feb 2008 12:16:37 -0000 1.55
+++ sparc64/intr.c 2 Mar 2008 12:50:10 -0000
@@ -44,7 +44,7 @@
__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.55 2008/02/18 12:16:37 martin Exp $");
#include "opt_ddb.h"
-#include "pcons.h"
+#include "opt_multiprocessor.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -67,7 +67,6 @@
struct intrhand *intrlev[MAXINTNUM];
void strayintr(const struct trapframe64 *, int);
-int softintr(void *);
int intr_list_handler(void *);
/*
@@ -116,57 +115,6 @@
}
/*
- * Level 1 software interrupt (could also be Sbus level 1 interrupt).
- * Three possible reasons:
- * Network software interrupt
- * Soft clock interrupt
- */
-int
-softintr(void *fp)
-{
-#if NPCONS >0
- extern void pcons_dopoll(void);
-
- pcons_dopoll();
-#endif
- return (1);
-}
-
-
-struct intrhand soft01intr = { .ih_fun = softintr, .ih_number = 1 };
-
-#if 0
-void
-setsoftint() {
- send_softint(-1, IPL_SOFTINT, &soft01intr);
-}
-#endif
-
-/*
- * Level 15 interrupts are special, and not vectored here.
- * Only `prewired' interrupts appear here; boot-time configured devices
- * are attached via intr_establish() below.
- */
-struct intrhand *intrhand[16] = {
- NULL, /* 0 = error */
- &soft01intr, /* 1 = software level 1 + Sbus */
- NULL, /* 2 = Sbus level 2 (4m: Sbus L1) */
- NULL, /* 3 = SCSI + DMA + Sbus level 3 (4m: L2,lpt)*/
- NULL, /* 4 = software level 4 (tty softint) (scsi) */
- NULL, /* 5 = Ethernet + Sbus level 4 (4m: Sbus L3) */
- NULL, /* 6 = software level 6 (not used) (4m: enet)*/
- NULL, /* 7 = video + Sbus level 5 */
- NULL, /* 8 = Sbus level 6 */
- NULL, /* 9 = Sbus level 7 */
- NULL, /* 10 = counter 0 = clock */
- NULL, /* 11 = floppy */
- NULL, /* 12 = zs hardware interrupt */
- NULL, /* 13 = audio chip */
- NULL, /* 14 = counter 1 = profiling timer */
- NULL /* 15 = async faults */
-};
-
-/*
* PCI devices can share interrupts so we need to have
* a handler to hand out interrupts.
*/
@@ -217,7 +165,7 @@
void
intr_establish(int level, struct intrhand *ih)
{
- struct intrhand **p, *q = NULL;
+ struct intrhand *q = NULL;
#ifdef MULTIPROCESSOR
bool mpsafe = (level != IPL_VM);
#endif
@@ -289,12 +237,5 @@
} else
panic("intr_establish: bad intr number %x", ih->ih_number);
- /* If it's not shared, stick it in the intrhand list for that level. */
- if (q == NULL) {
- for (p = &intrhand[level]; (q = *p) != NULL; p = &q->ih_next)
- ;
- *p = ih;
- }
-
splx(s);
}
Index: sparc64/locore.s
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/locore.s,v
retrieving revision 1.268
diff -u -d -r1.268 locore.s
--- sparc64/locore.s 2 Mar 2008 12:19:00 -0000 1.268
+++ sparc64/locore.s 2 Mar 2008 12:50:13 -0000
@@ -3595,16 +3595,14 @@
* and invokes the interrupt handler.
*/
- .data
- .globl intrpending
-intrpending:
- .space 16 * 8 * PTRSZ, -1
+/* intrpending array is now in per-CPU structure. */
#ifdef DEBUG
#define INTRDEBUG_VECTOR 0x1
#define INTRDEBUG_LEVEL 0x2
#define INTRDEBUG_FUNC 0x4
#define INTRDEBUG_SPUR 0x8
+ .data
.globl _C_LABEL(intrdebug)
_C_LABEL(intrdebug): .word 0x0
/*
@@ -3672,9 +3670,9 @@
LDPTR [%g5+IH_PEND], %g6 ! Read pending flag
brnz,pn %g6, ret_from_intr_vector ! Skip it if it's running
ldub [%g5+IH_PIL], %g6 ! Read interrupt mask
- sethi %hi(intrpending), %g1
- sll %g6, PTRSHFT+3, %g3 ! Find start of table for this IPL
- or %g1, %lo(intrpending), %g1
+ sethi %hi(CPUINFO_VA+CI_INTRPENDING), %g1
+ sll %g6, PTRSHFT, %g3 ! Find start of table for this IPL
+ or %g1, %lo(CPUINFO_VA+CI_INTRPENDING), %g1
add %g1, %g3, %g1
1:
LDPTR [%g1], %g3 ! Load list head
@@ -4017,18 +4015,17 @@
rd SOFTINT, %g1
btst 1, %g1
bz,pt %icc, 0f
- set _C_LABEL(intrlev), %g3
+ sethi %hi(CPUINFO_VA+CI_INTRLEV0), %g3
wr %g0, 1, CLEAR_SOFTINT
- DLFLUSH(%g3, %g2)
ba,pt %icc, setup_sparcintr
- LDPTR [%g3 + PTRSZ], %g5 ! intrlev[1] is reserved for %tick intr.
+ LDPTR [%g3 + %lo(CPUINFO_VA+CI_INTRLEV0)], %g5
0:
! Increment the per-cpu interrupt level
- set CPUINFO_VA+CI_IDEPTH, %g1
- ld [%g1], %g2
+ sethi %hi(CPUINFO_VA+CI_IDEPTH), %g1
+ ld [%g1 + %lo(CPUINFO_VA+CI_IDEPTH)], %g2
inc %g2
- st %g2, [%g1]
+ st %g2, [%g1 + %lo(CPUINFO_VA+CI_IDEPTH)]
#ifdef TRAPSTATS
sethi %hi(_C_LABEL(kintrcnt)), %g1
@@ -4112,10 +4109,9 @@
sparc_intr_retry:
wr %l3, 0, CLEAR_SOFTINT ! (don't clear possible %tick IRQ)
- sll %l6, PTRSHFT+3, %l2
- sethi %hi(intrpending), %l4
- or %l4, %lo(intrpending), %l4
- mov 8, %l7
+ sethi %hi(CPUINFO_VA+CI_INTRPENDING), %l4
+ sll %l6, PTRSHFT, %l2
+ or %l4, %lo(CPUINFO_VA+CI_INTRPENDING), %l4
add %l2, %l4, %l4
1:
@@ -4128,8 +4124,9 @@
CASPTR [%l4] ASI_N, %l2, %l7 ! Grab the entire list
cmp %l7, %l2
bne,pn %icc, 1b
- add %sp, CC64FSZ+STKB, %o2 ! tf = %sp + CC64FSZ + STKB
+ nop
2:
+ add %sp, CC64FSZ+STKB, %o2 ! tf = %sp + CC64FSZ + STKB
LDPTR [%l2 + IH_PEND], %l7 ! save ih->ih_pending
membar #LoadStore
STPTR %g0, [%l2 + IH_PEND] ! Clear pending flag
@@ -4166,10 +4163,10 @@
mov 1, %l5 ! initialize intr count for next run
! Decrement this cpu's interrupt depth
- set CPUINFO_VA+CI_IDEPTH, %l4
- ld [%l4], %l5
+ sethi %hi(CPUINFO_VA+CI_IDEPTH), %l4
+ ld [%l4 + %lo(CPUINFO_VA+CI_IDEPTH)], %l5
dec %l5
- st %l5, [%l4]
+ st %l5, [%l4 + %lo(CPUINFO_VA+CI_IDEPTH)]
#ifdef DEBUG
set _C_LABEL(intrdebug), %o2
@@ -5121,6 +5118,10 @@
* %g2 = cpu_args
*/
ENTRY(cpu_mp_startup)
+ mov 1, %o0
+ sllx %o0, 63, %o0
+ wr %o0, TICK_CMPR ! XXXXXXX clear and disable %tick_cmpr for now
+ wrpr %g0, 0, %tick ! XXXXXXX clear %tick register as well
wrpr %g0, 0, %cleanwin
wrpr %g0, 0, %tl ! Make sure we're not in
NUCLEUS mode
wrpr %g0, WSTATE_KERN, %wstate
@@ -9528,10 +9529,11 @@
ldx [%o0 + FS_FSR], %o4 ! if (f->fs_fsr & QNE)
btst %o2, %o4
- add %o0, FS_REGS, %o2
bnz Lfp_storeq ! goto storeq;
+ nop
Lfp_finish:
- btst BLOCK_ALIGN, %o2 ! Needs to be re-executed
+ add %o0, FS_REGS, %o2
+ btst BLOCK_ALIGN, %o2 ! Needs to be re-executed
bnz,pn %icc, 3f ! Check alignment
st %o3, [%o0 + FS_QSIZE] ! f->fs_qsize = qsize;
btst FPRS_DL, %o5 ! Lower FPU clean?
@@ -9631,7 +9633,7 @@
stx %o4, [%o1 + %o3] ! q[qsize++] = fsr_qfront();
stx %fsr, [%o0 + FS_FSR] ! reread fsr
ldx [%o0 + FS_FSR], %o4 ! if fsr & QNE, loop
- btst %o5, %o4
+ btst %o2, %o4
bnz 1b
inc 8, %o3
b Lfp_finish ! set qsize and finish storing fregs
@@ -9757,10 +9759,11 @@
andn %g1, PSTATE_IE, %g2 ! clear PSTATE.IE
wrpr %g2, 0, %pstate
- set intrpending, %o3
+ sethi %hi(CPUINFO_VA+CI_INTRPENDING), %o3
LDPTR [%o2 + IH_PEND], %o5
+ or %o3, %lo(CPUINFO_VA+CI_INTRPENDING), %o3
brnz %o5, 1f
- sll %o1, PTRSHFT+3, %o5 ! Find start of table for this IPL
+ sll %o1, PTRSHFT, %o5 ! Find start of table for this IPL
add %o3, %o5, %o3
2:
LDPTR [%o3], %o5 ! Load list head
Index: sparc64/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/pmap.c,v
retrieving revision 1.210
diff -u -d -r1.210 pmap.c
--- sparc64/pmap.c 28 Feb 2008 11:50:40 -0000 1.210
+++ sparc64/pmap.c 2 Mar 2008 12:50:14 -0000
@@ -1055,6 +1055,7 @@
cpus->ci_cpcb = (struct pcb *)u0va;
proc0paddr = cpus->ci_cpcb;
cpus->ci_idepth = -1;
+ memset(cpus->ci_intrpending, -1, sizeof(cpus->ci_intrpending));
lwp0.l_addr = (struct user*)u0va;
lwp0.l_md.md_tf = (struct trapframe64*)(u0va + USPACE
Home |
Main Index |
Thread Index |
Old Index