[Skiboot] [PATCH V2 5/6] Introduces get and put elog routine and reference count field in elog structure

Mukesh Ojha mukesh02 at linux.vnet.ibm.com
Thu Jun 9 23:54:09 AEST 2016


Introduces a reference count variable in the errorlog structure, which is
to track the number of user of errorlog buffer.

get_elog and put_elog routine to increment/decrement the reference count variable.
errorlog buffer return to the pool on zero count of reference count.

Signed-off-by: Mukesh Ojha <mukesh02 at linux.vnet.ibm.com>

---
Changes in V2:
 - Separates it from patch 3/3 from V1.

 core/errorlog.c         | 31 ++++++++++++++++++++++++++++---
 hw/fsp/fsp-elog-write.c |  1 +
 include/errorlog.h      |  2 ++
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/core/errorlog.c b/core/errorlog.c
index c34251b..8ec603c 100644
--- a/core/errorlog.c
+++ b/core/errorlog.c
@@ -39,9 +39,31 @@ static uint32_t sapphire_elog_id = 0xB0000000;
 /* Pool to allocate elog messages from */
 static struct pool elog_pool;
 static struct lock elog_lock = LOCK_UNLOCKED;
+static struct lock elog_buf_ref_lock = LOCK_UNLOCKED;
 
 static bool elog_available = false;
 
+static 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--;
+	unlock(&elog_buf_ref_lock);
+}
+
+void get_elog(struct errorlog *elog_buf)
+{
+	lock(&elog_buf_ref_lock);
+	elog_buf->ref_count++;
+	unlock(&elog_buf_ref_lock);
+}
+
 static struct errorlog *get_write_buffer(int opal_event_severity)
 {
 	struct errorlog *buf;
@@ -113,12 +135,15 @@ void log_add_section(struct errorlog *buf, uint32_t tag)
 
 void opal_elog_complete(struct errorlog *buf, bool success)
 {
+	put_elog(buf);
 	if (!success)
 		printf("Unable to log error\n");
 
-	lock(&elog_lock);
-	pool_free_object(&elog_pool, buf);
-	unlock(&elog_lock);
+	if (!buf->ref_count) {
+		lock(&elog_lock);
+		pool_free_object(&elog_pool, buf);
+		unlock(&elog_lock);
+	}
 }
 
 void log_commit(struct errorlog *elog)
diff --git a/hw/fsp/fsp-elog-write.c b/hw/fsp/fsp-elog-write.c
index 6e307a4..309617f 100644
--- a/hw/fsp/fsp-elog-write.c
+++ b/hw/fsp/fsp-elog-write.c
@@ -193,6 +193,7 @@ int elog_fsp_commit(struct errorlog *buf)
 {
 	int rc = OPAL_SUCCESS;
 
+	get_elog(buf);
 	/* Error needs to be committed, update the time out value */
 	buf->elog_timeout = get_elog_timeout();
 	if (buf->event_severity == OPAL_ERROR_PANIC) {
diff --git a/include/errorlog.h b/include/errorlog.h
index 3dff2cf..de5fb43 100644
--- a/include/errorlog.h
+++ b/include/errorlog.h
@@ -150,6 +150,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;
@@ -376,6 +377,7 @@ void elog_set_head_state(bool platform_log, enum elog_head_state old_state,
 void opal_commit_elog_in_host(void);
 bool opal_check_elog_pending_write_to_host(void);
 void elog_append_write_to_host(struct errorlog *buf);
+void get_elog(struct errorlog *elog_buf);
 int elog_init(void);
 
 #endif /* __ERRORLOG_H */
-- 
2.1.4



More information about the Skiboot mailing list