Skip to content

Commit

Permalink
Tweak the ia64 machine check handling code to not register new sysctl…
Browse files Browse the repository at this point in the history
… nodes

while holding a spin mutex.  Instead, it now shoves the machine check
records onto a queue that is later drained to add sysctl nodes for each
record.  While a routine to drain the queue is present, it is not currently
called.

Reviewed by:	marcel
  • Loading branch information
bsdjhb committed Feb 4, 2009
1 parent 38f4b2a commit 91ab06b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 26 deletions.
70 changes: 44 additions & 26 deletions sys/ia64/ia64/mca.c
Expand Up @@ -42,6 +42,16 @@

MALLOC_DEFINE(M_MCA, "MCA", "Machine Check Architecture");

struct mca_info {
STAILQ_ENTRY(mca_info) mi_link;
char mi_name[32];
size_t mi_recsz;
char mi_record[0];
};

static STAILQ_HEAD(, mca_info) mca_records =
STAILQ_HEAD_INITIALIZER(mca_records);

int64_t mca_info_size[SAL_INFO_TYPES];
vm_offset_t mca_info_block;
struct mtx mca_info_block_lock;
Expand Down Expand Up @@ -75,15 +85,33 @@ mca_sysctl_handler(SYSCTL_HANDLER_ARGS)
return (error);
}

void
ia64_mca_populate(void)
{
struct mca_info *rec;

mtx_lock_spin(&mca_info_block_lock);
while (!STAILQ_EMPTY(&mca_records)) {
rec = STAILQ_FIRST(&mca_records);
STAILQ_REMOVE_HEAD(&mca_records, mi_link);
mtx_unlock_spin(&mca_info_block_lock);
(void)SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca),
OID_AUTO, rec->mi_name, CTLTYPE_OPAQUE | CTLFLAG_RD,
rec->mi_record, rec->mi_recsz, mca_sysctl_handler, "S,MCA",
"Error record");
mtx_lock_spin(&mca_info_block_lock);
}
mtx_unlock_spin(&mca_info_block_lock);
}

void
ia64_mca_save_state(int type)
{
struct ia64_sal_result result;
struct mca_record_header *hdr;
struct sysctl_oid *oidp;
char *name, *state;
struct mca_info *rec;
uint64_t seqnr;
size_t recsz, totsz;
size_t recsz;

/*
* Don't try to get the state if we couldn't get the size of
Expand All @@ -95,9 +123,8 @@ ia64_mca_save_state(int type)
if (mca_info_block == 0)
return;

mtx_lock_spin(&mca_info_block_lock);
while (1) {
mtx_lock_spin(&mca_info_block_lock);

result = ia64_sal_entry(SAL_GET_STATE_INFO, type, 0,
mca_info_block, 0, 0, 0, 0);
if (result.sal_status < 0) {
Expand All @@ -111,11 +138,13 @@ ia64_mca_save_state(int type)

mtx_unlock_spin(&mca_info_block_lock);

totsz = sizeof(struct sysctl_oid) + recsz + 32;
oidp = malloc(totsz, M_MCA, M_NOWAIT|M_ZERO);
state = (char*)(oidp + 1);
name = state + recsz;
sprintf(name, "%lld", (long long)seqnr);
rec = malloc(sizeof(struct mca_info) + recsz, M_MCA,
M_NOWAIT | M_ZERO);
if (rec == NULL)
/* XXX: Not sure what to do. */
return;

sprintf(rec->mi_name, "%lld", (long long)seqnr);

mtx_lock_spin(&mca_info_block_lock);

Expand All @@ -133,24 +162,14 @@ ia64_mca_save_state(int type)
mca_info_block, 0, 0, 0, 0);
if (seqnr != hdr->rh_seqnr) {
mtx_unlock_spin(&mca_info_block_lock);
free(oidp, M_MCA);
free(rec, M_MCA);
mtx_lock_spin(&mca_info_block_lock);
continue;
}
}

bcopy((char*)mca_info_block, state, recsz);

oidp->oid_parent = &sysctl__hw_mca_children;
oidp->oid_number = OID_AUTO;
oidp->oid_kind = CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_DYN;
oidp->oid_arg1 = state;
oidp->oid_arg2 = recsz;
oidp->oid_name = name;
oidp->oid_handler = mca_sysctl_handler;
oidp->oid_fmt = "S,MCA";
oidp->oid_descr = "Error record";

sysctl_register_oid(oidp);
rec->mi_recsz = recsz;
bcopy((char*)mca_info_block, rec->mi_record, recsz);

if (mca_count > 0) {
if (seqnr < mca_first)
Expand All @@ -161,15 +180,14 @@ ia64_mca_save_state(int type)
mca_first = mca_last = seqnr;

mca_count++;
STAILQ_INSERT_TAIL(&mca_records, rec, mi_link);

/*
* Clear the state so that we get any other records when
* they exist.
*/
result = ia64_sal_entry(SAL_CLEAR_STATE_INFO, type, 0, 0, 0,
0, 0, 0);

mtx_unlock_spin(&mca_info_block_lock);
}
}

Expand Down
1 change: 1 addition & 0 deletions sys/ia64/include/mca.h
Expand Up @@ -239,6 +239,7 @@ struct mca_pcidev_reg {
#ifdef _KERNEL

void ia64_mca_init(void);
void ia64_mca_populate(void);
void ia64_mca_save_state(int);

#endif /* _KERNEL */
Expand Down

0 comments on commit 91ab06b

Please sign in to comment.