[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