From patchwork Wed Apr 6 11:47:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mukesh Ojha X-Patchwork-Id: 606954 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qg3rq4Cjyz9s5l for ; Wed, 6 Apr 2016 21:48:27 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3qg3rq3TSJzDqGy for ; Wed, 6 Apr 2016 21:48:27 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from e36.co.us.ibm.com (e36.co.us.ibm.com [32.97.110.154]) (using TLSv1.2 with cipher CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3qg3rW6MkGzDqFP for ; Wed, 6 Apr 2016 21:48:11 +1000 (AEST) Received: from localhost by e36.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 6 Apr 2016 05:48:08 -0600 Received: from d03dlp02.boulder.ibm.com (9.17.202.178) by e36.co.us.ibm.com (192.168.1.136) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 6 Apr 2016 05:48:03 -0600 X-IBM-Helo: d03dlp02.boulder.ibm.com X-IBM-MailFrom: mukesh02@linux.vnet.ibm.com X-IBM-RcptTo: skiboot@lists.ozlabs.org Received: from b03cxnp08027.gho.boulder.ibm.com (b03cxnp08027.gho.boulder.ibm.com [9.17.130.19]) by d03dlp02.boulder.ibm.com (Postfix) with ESMTP id 3D0873E40030 for ; Wed, 6 Apr 2016 05:48:02 -0600 (MDT) Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by b03cxnp08027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u36Bm2mI35717274 for ; Wed, 6 Apr 2016 04:48:02 -0700 Received: from d03av02.boulder.ibm.com (localhost [127.0.0.1]) by d03av02.boulder.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u36Bm1lL016945 for ; Wed, 6 Apr 2016 05:48:02 -0600 Received: from mukesh-ThinkPad-T420.in.ibm.com (mukesh-thinkpad-t420.in.ibm.com [9.124.35.244]) by d03av02.boulder.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u36Bln8w015898; Wed, 6 Apr 2016 05:48:00 -0600 From: Mukesh Ojha To: skiboot@lists.ozlabs.org Date: Wed, 6 Apr 2016 17:17:46 +0530 Message-Id: <1459943266-6268-4-git-send-email-mukesh02@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1459943266-6268-1-git-send-email-mukesh02@linux.vnet.ibm.com> References: <1459943266-6268-1-git-send-email-mukesh02@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16040611-0021-0000-0000-00002F9A7390 Subject: [Skiboot] [PATCH 3/3] opal/errorlog : Enables errorlog write to host on BMC systems X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Adds the support of errorlog write to host by using the generic interface of errorlog read/write framework. OPAL sents the errorlog messages to both BMC and host kernel by passing the errorlog buffers. Properly returning of buffers to the pool by introducing ref_count variable in the errorlog structure, which is manipulated in 'get_elog' and 'put_elog' function. Makes put_elog a wrapper of opal_elog_complete (static) and exported function. Call to 'opal_elog_complete' made on ref_count of zero. 'opal_elog_init' initialises the memory and the callbacks require for errorlog write to host framework. Signed-off-by: Mukesh Ojha --- core/elog-host.c | 4 ++-- core/errorlog.c | 46 +++++++++++++++++++++++++++++++++++----------- hw/fsp/fsp-elog-write.c | 9 +++++---- hw/ipmi/ipmi-sel.c | 25 ++++++++++++++++++------- include/errorlog.h | 7 +++---- platforms/astbmc/common.c | 4 ++-- 6 files changed, 65 insertions(+), 30 deletions(-) diff --git a/core/elog-host.c b/core/elog-host.c index c6ec51a..b104447 100644 --- a/core/elog-host.c +++ b/core/elog-host.c @@ -180,7 +180,7 @@ static int opal_elog_ack(uint64_t ack_id) if (record->plid != ack_id) continue; list_del(&record->link); - opal_elog_complete(record, true); + put_elog(record); unlock(&elog_write_to_host_lock); return rc; } @@ -197,7 +197,7 @@ static int opal_elog_ack(uint64_t ack_id) if (record->plid != ack_id) continue; list_del(&record->link); - opal_elog_complete(record, true); + put_elog(record); unlock(&elog_write_to_host_lock); return rc; } diff --git a/core/errorlog.c b/core/errorlog.c index 7afd16c..af2853b 100644 --- a/core/errorlog.c +++ b/core/errorlog.c @@ -42,6 +42,40 @@ static struct pool elog_pool; static struct lock elog_lock = LOCK_UNLOCKED; static bool elog_available = false; +static struct lock elog_buf_ref_lock = LOCK_UNLOCKED; + +static void opal_elog_complete(struct errorlog *buf) +{ + lock(&elog_lock); + pool_free_object(&elog_pool, buf); + unlock(&elog_lock); +} + +void get_elog(struct errorlog *elog_buf) +{ + lock(&elog_buf_ref_lock); + elog_buf->ref_count++; + unlock(&elog_buf_ref_lock); +} + +void put_elog(struct errorlog *elog_buf) +{ + lock(&elog_buf_ref_lock); + if (!elog_buf->ref_count) { + prerror( + "put_elog has been called multiple times on reference" + " count zero\n" + ); + unlock(&elog_buf_ref_lock); + return; + } + + elog_buf->ref_count--; + if (!elog_buf->ref_count) + opal_elog_complete(elog_buf); + + unlock(&elog_buf_ref_lock); +} static struct errorlog *get_write_buffer(int opal_event_severity) { @@ -112,16 +146,6 @@ void log_add_section(struct errorlog *buf, uint32_t tag) buf->user_section_count++; } -void opal_elog_complete(struct errorlog *buf, bool success) -{ - if (!success) - printf("Unable to log error\n"); - - lock(&elog_lock); - pool_free_object(&elog_pool, buf); - unlock(&elog_lock); -} - void log_commit(struct errorlog *elog) { int rc; @@ -135,7 +159,7 @@ void log_commit(struct errorlog *elog) prerror("ELOG: Platform commit error %d\n", rc); return; } - opal_elog_complete(elog, false); + opal_elog_complete(elog); } void log_append_data(struct errorlog *buf, unsigned char *data, uint16_t size) diff --git a/hw/fsp/fsp-elog-write.c b/hw/fsp/fsp-elog-write.c index ee293f1..dced70d 100644 --- a/hw/fsp/fsp-elog-write.c +++ b/hw/fsp/fsp-elog-write.c @@ -66,7 +66,7 @@ static void remove_elog_head_entry(void) if (head->plid == elog_plid_fsp_commit) { entry = list_pop(&elog_write_to_fsp_pending, struct errorlog, link); - opal_elog_complete(entry, elog_write_retries < MAX_RETRIES); + put_elog(entry); /* Reset the counter */ elog_plid_fsp_commit = -1; } @@ -161,7 +161,7 @@ static int opal_push_logs_sync_to_fsp(struct errorlog *buf) prerror("ELOG: PLID: 0x%x Failed to create message for WRITE " "to FSP\n", buf->plid); unlock(&elog_panic_write_lock); - opal_elog_complete(buf, false); + put_elog(buf); return OPAL_INTERNAL_ERROR; } @@ -175,9 +175,9 @@ static int opal_push_logs_sync_to_fsp(struct errorlog *buf) unlock(&elog_panic_write_lock); if (rc != OPAL_SUCCESS) - opal_elog_complete(buf, false); + put_elog(buf); else - opal_elog_complete(buf, true); + put_elog(buf); return rc; } @@ -193,6 +193,7 @@ int elog_fsp_commit(struct errorlog *buf) /* Error needs to be committed, update the time out value */ buf->elog_timeout = get_elog_timeout(); + get_elog(buf); if (buf->event_severity == OPAL_ERROR_PANIC) { rc = opal_push_logs_sync_to_fsp(buf); return rc; diff --git a/hw/ipmi/ipmi-sel.c b/hw/ipmi/ipmi-sel.c index 6bc386a..0950218 100644 --- a/hw/ipmi/ipmi-sel.c +++ b/hw/ipmi/ipmi-sel.c @@ -262,7 +262,7 @@ static void ipmi_elog_error(struct ipmi_msg *msg) /* Retry due to SEL erase */ ipmi_queue_msg(msg); else { - opal_elog_complete(msg->user_data, false); + put_elog(msg->user_data); ipmi_sel_free_msg(msg); } } @@ -345,7 +345,7 @@ static void ipmi_elog_poll(struct ipmi_msg *msg) * get here, but just in case we do we cancel * sending the message. */ prerror("Invalid reservation id"); - opal_elog_complete(elog_buf, false); + put_elog(elog_buf); ipmi_sel_free_msg(msg); return; } @@ -371,7 +371,7 @@ static void ipmi_elog_poll(struct ipmi_msg *msg) /* Log SEL event and free ipmi message */ ipmi_log_sel_event(msg, elog_buf->event_severity, record_id); - opal_elog_complete(elog_buf, true); + put_elog(elog_buf); return; } @@ -415,24 +415,34 @@ int ipmi_elog_commit(struct errorlog *elog_buf) { struct ipmi_msg *msg; + get_elog(elog_buf); /* Only log events that needs attention */ if (elog_buf->event_severity < OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_REBOOT || elog_buf->elog_origin != ORG_SAPPHIRE) { prlog(PR_INFO, "dropping non severe PEL event\n"); - opal_elog_complete(elog_buf, true); + put_elog(elog_buf); return 0; } + /* We take get_elog two times to make sure errorlog will be sent to + * both BMC and the host irrespective of either of them is complete + * or not, buffer will be return to the pool during the call of + * put_elog(). + */ + get_elog(elog_buf); + /* We pass a large request size in to mkmsg so that we have a * large enough allocation to reuse the message to pass the - * PEL data via a series of partial add commands. */ + * PEL data via a series of partial add commands. + */ msg = ipmi_sel_alloc_msg(elog_buf); if (!msg) { - opal_elog_complete(elog_buf, false); + put_elog(elog_buf); + elog_append_write_to_host(elog_buf); return OPAL_RESOURCE; } - msg->error = ipmi_elog_error; + msg->error = ipmi_elog_error; msg->req_size = 0; if (elog_buf->event_severity == OPAL_ERROR_PANIC) @@ -440,6 +450,7 @@ int ipmi_elog_commit(struct errorlog *elog_buf) else ipmi_queue_msg(msg); + elog_append_write_to_host(elog_buf); return 0; } diff --git a/include/errorlog.h b/include/errorlog.h index d58eb5e..d7c25c2 100644 --- a/include/errorlog.h +++ b/include/errorlog.h @@ -137,6 +137,7 @@ struct __attribute__((__packed__)) errorlog { uint32_t plid; uint32_t log_size; uint64_t elog_timeout; + uint32_t ref_count; char user_data_dump[OPAL_LOG_MAX_DUMP]; struct list_node link; @@ -349,10 +350,8 @@ void log_append_msg(struct errorlog *buf, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); void log_commit(struct errorlog *elog); -/* Called by the backend after an error has been logged by the - * backend. If the error could not be logged successfully success is - * set to false. */ -void opal_elog_complete(struct errorlog *elog, bool success); +void get_elog(struct errorlog *elog_buf); +void put_elog(struct errorlog *elog_buf); void opal_elog_init(void); void opal_commit_elog_in_host(void); diff --git a/platforms/astbmc/common.c b/platforms/astbmc/common.c index 1ed7d42..4dd5401 100644 --- a/platforms/astbmc/common.c +++ b/platforms/astbmc/common.c @@ -115,8 +115,8 @@ void astbmc_init(void) /* Register the BT interface with the IPMI layer */ bt_init(); - /* Initialize elog */ - elog_init(); + /*Initialize the errorlog framework*/ + opal_elog_init(); ipmi_sel_init(); ipmi_wdt_init(); ipmi_rtc_init();