add support for interrupt counting on sparc64. This copies part of the
code from i386. The code has a slight bogon that interrupts are counted twice. Once on the ithread dispatch and once on the dispatch for the vector vmstat -i and systat -vm now contains interrupt counts. Reviewed by: jake
This commit is contained in:
parent
57499a32b1
commit
e93581dc7a
@ -68,6 +68,17 @@
|
||||
bne,pn %icc, 9b ; \
|
||||
mov r3, r2
|
||||
|
||||
/*
|
||||
* Atomically increment an u_long in memory.
|
||||
*/
|
||||
#define ATOMIC_INC_ULONG(r1, r2, r3) \
|
||||
ldx [r1], r2 ; \
|
||||
9: add r2, 1, r3 ; \
|
||||
casxa [r1] ASI_N, r2, r3 ; \
|
||||
cmp r2, r3 ; \
|
||||
bne,pn %icc, 9b ; \
|
||||
mov r3, r2
|
||||
|
||||
/*
|
||||
* Atomically clear a number of bits of an integer in memory.
|
||||
*/
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#define PIL_MAX (1 << 4)
|
||||
#define IV_MAX (1 << 11)
|
||||
#define IV_NAMLEN 1024
|
||||
|
||||
#define IR_FREE (PIL_MAX * 2)
|
||||
|
||||
|
@ -364,7 +364,7 @@ ENTRY(rsf_fatal)
|
||||
sir
|
||||
END(rsf_fatal)
|
||||
|
||||
.comm intrnames, IV_MAX * 8
|
||||
.comm intrnames, IV_NAMLEN
|
||||
.comm eintrnames, 0
|
||||
|
||||
.comm intrcnt, IV_MAX * 8
|
||||
@ -2316,6 +2316,17 @@ ENTRY(tl0_intr)
|
||||
stx %i6, [%sp + SPOFF + CCFSZ + TF_O6]
|
||||
stx %i7, [%sp + SPOFF + CCFSZ + TF_O7]
|
||||
|
||||
/* %l3 contains PIL */
|
||||
SET(intrcnt, %l1, %l2)
|
||||
prefetcha [%l2] ASI_N, 1
|
||||
SET(pil_countp, %l1, %l0)
|
||||
sllx %l3, 1, %l1
|
||||
lduh [%l0 + %l1], %l0
|
||||
sllx %l0, 3, %l0
|
||||
add %l0, %l2, %l0
|
||||
|
||||
ATOMIC_INC_ULONG(%l0, %l1, %l2)
|
||||
|
||||
call critical_enter
|
||||
nop
|
||||
|
||||
@ -2820,6 +2831,17 @@ ENTRY(tl1_intr)
|
||||
mov %l5, PCPU_REG
|
||||
wrpr %g0, PSTATE_KERNEL, %pstate
|
||||
|
||||
/* %l3 contains PIL */
|
||||
SET(intrcnt, %l5, %l4)
|
||||
prefetcha [%l4] ASI_N, 1
|
||||
SET(pil_countp, %l5, %l6)
|
||||
sllx %l7, 1, %l5
|
||||
lduh [%l5 + %l6], %l5
|
||||
sllx %l5, 3, %l5
|
||||
add %l5, %l4, %l4
|
||||
|
||||
ATOMIC_INC_ULONG(%l4, %l5, %l6)
|
||||
|
||||
call critical_enter
|
||||
nop
|
||||
|
||||
|
@ -218,6 +218,7 @@ ASSYM(IV_FUNC, offsetof(struct intr_vector, iv_func));
|
||||
ASSYM(IV_ARG, offsetof(struct intr_vector, iv_arg));
|
||||
ASSYM(IV_PRI, offsetof(struct intr_vector, iv_pri));
|
||||
|
||||
ASSYM(IV_NAMLEN, IV_NAMLEN);
|
||||
ASSYM(IV_MAX, IV_MAX);
|
||||
|
||||
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
|
||||
|
@ -169,7 +169,18 @@ ENTRY(intr_fast)
|
||||
|
||||
3: ldx [%l0 + IR_FUNC], %o0
|
||||
ldx [%l0 + IR_ARG], %o1
|
||||
ldx [%l0 + IR_VEC], %o2
|
||||
lduw [%l0 + IR_VEC], %o2
|
||||
|
||||
/* load intrcnt[intr_countp[%o2]] into %l4 */
|
||||
SET(intrcnt, %l7, %l2) /* %l5 = intrcnt */
|
||||
prefetcha [%l2] ASI_N, 1
|
||||
SET(intr_countp, %l7, %l3) /* %l6 = intr_countp */
|
||||
sllx %o2, 1, %l4 /* %l4 = vec << 1 */
|
||||
lduh [%l4 + %l3], %l5 /* %l6 = intr_countp[%o2] */
|
||||
sllx %l5, 3, %l6 /* %l6 = intr_countp[%o2] << 3 */
|
||||
add %l6, %l2, %l7 /* %l4 = intrcnt[intr_countp[%o2]] */
|
||||
|
||||
ATOMIC_INC_ULONG(%l7, %l5, %l2)
|
||||
|
||||
ldx [PCPU(IRFREE)], %l1
|
||||
stx %l1, [%l0 + IR_NEXT]
|
||||
|
@ -82,16 +82,88 @@
|
||||
CTASSERT((1 << IV_SHIFT) == sizeof(struct intr_vector));
|
||||
|
||||
ih_func_t *intr_handlers[PIL_MAX];
|
||||
u_int16_t pil_countp[PIL_MAX];
|
||||
|
||||
struct intr_vector intr_vectors[IV_MAX];
|
||||
|
||||
u_long intr_stray_count[IV_MAX];
|
||||
u_int16_t intr_countp[IV_MAX];
|
||||
|
||||
char *pil_names[] = {
|
||||
"stray",
|
||||
"low", /* PIL_LOW */
|
||||
"ithrd", /* PIL_ITHREAD */
|
||||
"rndzvs", /* PIL_RENDEZVOUS */
|
||||
"ast", /* PIL_AST */
|
||||
"stop", /* PIL_STOP */
|
||||
"stray", "stray", "stray", "stray", "stray", "stray", "stray",
|
||||
"fast", /* PIL_FAST */
|
||||
"tick", /* PIL_TICK */
|
||||
};
|
||||
|
||||
/* protect the intr_vectors table */
|
||||
static struct mtx intr_table_lock;
|
||||
|
||||
static void intr_stray_level(struct trapframe *tf);
|
||||
static void intr_stray_vector(void *cookie);
|
||||
|
||||
/*
|
||||
* not MPSAFE
|
||||
*/
|
||||
static void
|
||||
update_intrname(int vec, const char *name, int ispil)
|
||||
{
|
||||
char buf[32];
|
||||
char *cp;
|
||||
int off, name_index;
|
||||
|
||||
if (intrnames[0] == '\0') {
|
||||
/* for bitbucket */
|
||||
if (bootverbose)
|
||||
printf("initalizing intr_countp\n");
|
||||
off = sprintf(intrnames, "???") + 1;
|
||||
|
||||
off += sprintf(intrnames + off, "stray") + 1;
|
||||
for (name_index = 0; name_index < IV_MAX; name_index++)
|
||||
intr_countp[name_index] = 1;
|
||||
|
||||
off += sprintf(intrnames + off, "pil") + 1;
|
||||
for (name_index = 0; name_index < PIL_MAX; name_index++)
|
||||
pil_countp[name_index] = 2;
|
||||
}
|
||||
|
||||
if (name == NULL)
|
||||
name = "???";
|
||||
|
||||
if (snprintf(buf, sizeof(buf), "%s %s%d", name, ispil ? "pil" : "vec",
|
||||
vec) >= sizeof(buf))
|
||||
goto use_bitbucket;
|
||||
|
||||
/*
|
||||
* Search for `buf' in `intrnames'. In the usual case when it is
|
||||
* not found, append it to the end if there is enough space (the \0
|
||||
* terminator for the previous string, if any, becomes a separator).
|
||||
*/
|
||||
for (cp = intrnames, name_index = 0; cp != eintrnames &&
|
||||
name_index < IV_MAX; cp += strlen(cp) + 1, name_index++) {
|
||||
if (*cp == '\0') {
|
||||
if (strlen(buf) >= eintrnames - cp)
|
||||
break;
|
||||
strcpy(cp, buf);
|
||||
goto found;
|
||||
}
|
||||
if (strcmp(cp, buf) == 0)
|
||||
goto found;
|
||||
}
|
||||
|
||||
use_bitbucket:
|
||||
name_index = 0;
|
||||
found:
|
||||
if (!ispil)
|
||||
intr_countp[vec] = name_index;
|
||||
else
|
||||
pil_countp[vec] = name_index;
|
||||
}
|
||||
|
||||
void
|
||||
intr_setup(int pri, ih_func_t *ihf, int vec, iv_func_t *ivf, void *iva)
|
||||
{
|
||||
@ -104,6 +176,7 @@ intr_setup(int pri, ih_func_t *ihf, int vec, iv_func_t *ivf, void *iva)
|
||||
intr_vectors[vec].iv_pri = pri;
|
||||
intr_vectors[vec].iv_vec = vec;
|
||||
}
|
||||
update_intrname(pri, pil_names[pri], 1);
|
||||
intr_handlers[pri] = ihf;
|
||||
intr_restore(ps);
|
||||
}
|
||||
@ -222,7 +295,9 @@ inthand_add(const char *name, int vec, void (*handler)(void *), void *arg,
|
||||
intr_setup(PIL_FAST, intr_fast, vec, handler, arg);
|
||||
|
||||
intr_stray_count[vec] = 0;
|
||||
/* XXX: name is not yet used. */
|
||||
|
||||
update_intrname(vec, name, 0);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user