summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>2007-08-15 03:34:39 +0000
committeryshang1 <yshang1@6f19259b-4bc3-4df7-8a09-765794883524>2007-08-15 03:34:39 +0000
commite99dbdf28e7356d2a933f816f3fa877c2f49a7e4 (patch)
treeb009f360b85605e0ca29fbe01a08aa975f612b5f
parent20049698b2b0989db98cde5b77bd695cc7783905 (diff)
downloadedk2-e99dbdf28e7356d2a933f816f3fa877c2f49a7e4.zip
edk2-e99dbdf28e7356d2a933f816f3fa877c2f49a7e4.tar.gz
edk2-e99dbdf28e7356d2a933f816f3fa877c2f49a7e4.tar.bz2
1) Fix bug in StatusCodeDxe about the nested DataHub->Log in callback.
2) Close a small window which may result in the data collision of records. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2/IntelFrameworkModulePkg@3641 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c59
1 files changed, 57 insertions, 2 deletions
diff --git a/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c b/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c
index 70f41e9..c14dfc8 100644
--- a/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c
+++ b/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c
@@ -22,6 +22,8 @@ LIST_ENTRY mRecordsFifo = INITIALIZE_LIST_HEAD_VARIABLE
STATIC
LIST_ENTRY mRecordsBuffer = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsBuffer);
STATIC
+UINT32 mLogDataHubStatus = 0;
+STATIC
EFI_EVENT mLogDataHubEvent;
//
// Cache data hub protocol.
@@ -59,6 +61,9 @@ AcquireRecordBuffer (
Record = _CR (Node, DATAHUB_STATUSCODE_RECORD, Node);
} else {
if (CurrentTpl > TPL_NOTIFY) {
+ //
+ // Memory management should work at <=TPL_NOTIFY
+ //
gBS->RestoreTPL (CurrentTpl);
return NULL;
}
@@ -108,10 +113,9 @@ RetrieveRecord (
if (!IsListEmpty (&mRecordsFifo)) {
Node = GetFirstNode (&mRecordsFifo);
Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, DATAHUB_STATUS_CODE_SIGNATURE);
+ ASSERT (NULL != Record);
RemoveEntryList (&Record->Node);
- InsertTailList (&mRecordsBuffer, &Record->Node);
- Record->Signature = 0;
RecordData = (DATA_HUB_STATUS_CODE_DATA_RECORD *) Record->Data;
}
@@ -120,6 +124,34 @@ RetrieveRecord (
return RecordData;
}
+/**
+ Release Records to FIFO.
+
+ @param RecordData Point to the record buffer allocated
+ from AcquireRecordBuffer.
+
+**/
+STATIC
+VOID
+ReleaseRecord (
+ DATA_HUB_STATUS_CODE_DATA_RECORD *RecordData
+ )
+{
+ DATAHUB_STATUSCODE_RECORD *Record;
+ EFI_TPL CurrentTpl;
+
+ Record = CR (RecordData, DATAHUB_STATUSCODE_RECORD, Data[0], DATAHUB_STATUS_CODE_SIGNATURE);
+ ASSERT (NULL != Record);
+
+ CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+ InsertTailList (&mRecordsBuffer, &Record->Node);
+ Record->Signature = 0;
+
+ gBS->RestoreTPL (CurrentTpl);
+}
+
+
/**
Report status code into DataHub.
@@ -166,6 +198,15 @@ DataHubStatusCodeReportWorker (
CHAR8 *Format;
UINTN CharCount;
+
+ //
+ // Use atom operation to avoid the reentant of report.
+ // If current status is not zero, then the function is reentrancy.
+ //
+ if (1 == InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 0)) {
+ return EFI_DEVICE_ERROR;
+ }
+
//
// See whether in runtime phase or not.
//
@@ -246,6 +287,14 @@ LogDataHubEventCallBack (
UINT64 DataRecordClass;
//
+ // Use atom operation to avoid the reentant of report.
+ // If current status is not zero, then the function is reentrancy.
+ //
+ if (1 == InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 1)) {
+ return;
+ }
+
+ //
// Log DataRecord in Data Hub.
// Journal records fifo to find all record entry.
//
@@ -288,7 +337,13 @@ LogDataHubEventCallBack (
Size
);
+ ReleaseRecord (Record);
}
+
+ //
+ // Restore the nest status of report
+ //
+ InterlockedCompareExchange32 (&mLogDataHubStatus, 1, 0);
}