From owner-svn-src-head@FreeBSD.ORG Wed Feb 4 18:44:29 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 80822106568E; Wed, 4 Feb 2009 18:44:29 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6B44C8FC23; Wed, 4 Feb 2009 18:44:29 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n14IiTuJ088007; Wed, 4 Feb 2009 18:44:29 GMT (envelope-from jhb@svn.freebsd.org) Received: (from jhb@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n14IiTu0088005; Wed, 4 Feb 2009 18:44:29 GMT (envelope-from jhb@svn.freebsd.org) Message-Id: <200902041844.n14IiTu0088005@svn.freebsd.org> From: John Baldwin Date: Wed, 4 Feb 2009 18:44:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r188119 - in head/sys/ia64: ia64 include X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 04 Feb 2009 18:44:32 -0000 Author: jhb Date: Wed Feb 4 18:44:29 2009 New Revision: 188119 URL: http://svn.freebsd.org/changeset/base/188119 Log: Tweak the ia64 machine check handling code to not register new sysctl 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 Modified: head/sys/ia64/ia64/mca.c head/sys/ia64/include/mca.h Modified: head/sys/ia64/ia64/mca.c ============================================================================== --- head/sys/ia64/ia64/mca.c Wed Feb 4 18:20:27 2009 (r188118) +++ head/sys/ia64/ia64/mca.c Wed Feb 4 18:44:29 2009 (r188119) @@ -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; @@ -76,14 +86,32 @@ mca_sysctl_handler(SYSCTL_HANDLER_ARGS) } 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 @@ -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) { @@ -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); @@ -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) @@ -161,6 +180,7 @@ 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 @@ -168,8 +188,6 @@ ia64_mca_save_state(int type) */ result = ia64_sal_entry(SAL_CLEAR_STATE_INFO, type, 0, 0, 0, 0, 0, 0); - - mtx_unlock_spin(&mca_info_block_lock); } } Modified: head/sys/ia64/include/mca.h ============================================================================== --- head/sys/ia64/include/mca.h Wed Feb 4 18:20:27 2009 (r188118) +++ head/sys/ia64/include/mca.h Wed Feb 4 18:44:29 2009 (r188119) @@ -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 */