Revision: 18654
          http://sourceforge.net/p/edk2/code/18654
Author:   lzeng14
Date:     2015-10-23 05:28:38 +0000 (Fri, 23 Oct 2015)
Log Message:
-----------
MdeModulePkg Variable: Enhance variable performance by reading from existed 
memory cache.

Current variable driver already have memory cache to improve performance.
Change the code which read from physical MMIO address to read from memory cache.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Derek Lin <[email protected]>
Reviewed-by: Samer El-Haj-Mahmoud <[email protected]>
Reviewed-by: Star Zeng <[email protected]>

Modified Paths:
--------------
    trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
    trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c

Modified: trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c    
2015-10-23 02:03:20 UTC (rev 18653)
+++ trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/Variable.c    
2015-10-23 05:28:38 UTC (rev 18654)
@@ -17,6 +17,7 @@
   integer overflow. It should also check attribute to avoid authentication 
bypass.
 
 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
@@ -37,6 +38,11 @@
 VARIABLE_STORE_HEADER  *mNvVariableCache      = NULL;
 
 ///
+/// Memory cache of Fv Header.
+///
+EFI_FIRMWARE_VOLUME_HEADER *mNvFvHeaderCache  = NULL;
+
+///
 /// The memory entry used for variable statistics data.
 ///
 VARIABLE_INFO_ENTRY    *gVariableInfo         = NULL;
@@ -333,7 +339,7 @@
     return EFI_INVALID_PARAMETER;
   }
 
-  for (PtrBlockMapEntry = FwVolHeader->BlockMap; PtrBlockMapEntry->NumBlocks 
!= 0; PtrBlockMapEntry++) {
+  for (PtrBlockMapEntry = mNvFvHeaderCache->BlockMap; 
PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {
     for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; 
BlockIndex2++) {
       //
       // Check to see if the Variable Writes are spanning through multiple
@@ -2209,7 +2215,8 @@
     VariableStoreHeader  = (VARIABLE_STORE_HEADER *) ((UINTN) 
mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase);
     Variable = &NvVariable;
     Variable->StartPtr = GetStartPointer (VariableStoreHeader);
-    Variable->EndPtr   = GetEndPointer (VariableStoreHeader);
+    Variable->EndPtr   = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + 
((UINTN)CacheVariable->EndPtr - (UINTN)CacheVariable->StartPtr));
+
     Variable->CurrPtr  = (VARIABLE_HEADER *)((UINTN)Variable->StartPtr + 
((UINTN)CacheVariable->CurrPtr - (UINTN)CacheVariable->StartPtr));
     if (CacheVariable->InDeletedTransitionPtr != NULL) {
       Variable->InDeletedTransitionPtr = (VARIABLE_HEADER 
*)((UINTN)Variable->StartPtr + ((UINTN)CacheVariable->InDeletedTransitionPtr - 
(UINTN)CacheVariable->StartPtr));
@@ -2247,7 +2254,7 @@
       //
       // Only variable that have NV attributes can be updated/deleted in 
Runtime.
       //
-      if ((Variable->CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
+      if ((CacheVariable->CurrPtr->Attributes & EFI_VARIABLE_NON_VOLATILE) == 
0) {
         Status = EFI_INVALID_PARAMETER;
         goto Done;
       }
@@ -2255,7 +2262,7 @@
       //
       // Only variable that have RT attributes can be updated/deleted in 
Runtime.
       //
-      if ((Variable->CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) == 0) {
+      if ((CacheVariable->CurrPtr->Attributes & EFI_VARIABLE_RUNTIME_ACCESS) 
== 0) {
         Status = EFI_INVALID_PARAMETER;
         goto Done;
       }
@@ -2273,7 +2280,7 @@
         // Both ADDED and IN_DELETED_TRANSITION variable are present,
         // set IN_DELETED_TRANSITION one to DELETED state first.
         //
-        State = Variable->InDeletedTransitionPtr->State;
+        State = CacheVariable->InDeletedTransitionPtr->State;
         State &= VAR_DELETED;
         Status = UpdateVariableStore (
                    &mVariableModuleGlobal->VariableGlobal,
@@ -2294,7 +2301,7 @@
         }
       }
 
-      State = Variable->CurrPtr->State;
+      State = CacheVariable->CurrPtr->State;
       State &= VAR_DELETED;
 
       Status = UpdateVariableStore (
@@ -2319,8 +2326,8 @@
     // If the variable is marked valid, and the same data has been passed in,
     // then return to the caller immediately.
     //
-    if (DataSizeOfVariable (Variable->CurrPtr) == DataSize &&
-        (CompareMem (Data, GetVariableDataPtr (Variable->CurrPtr), DataSize) 
== 0) &&
+    if (DataSizeOfVariable (CacheVariable->CurrPtr) == DataSize &&
+        (CompareMem (Data, GetVariableDataPtr (CacheVariable->CurrPtr), 
DataSize) == 0) &&
         ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) &&
         (TimeStamp == NULL)) {
       //
@@ -2329,8 +2336,8 @@
       UpdateVariableInfo (VariableName, VendorGuid, Variable->Volatile, FALSE, 
TRUE, FALSE, FALSE);
       Status = EFI_SUCCESS;
       goto Done;
-    } else if ((Variable->CurrPtr->State == VAR_ADDED) ||
-               (Variable->CurrPtr->State == (VAR_ADDED & 
VAR_IN_DELETED_TRANSITION))) {
+    } else if ((CacheVariable->CurrPtr->State == VAR_ADDED) ||
+               (CacheVariable->CurrPtr->State == (VAR_ADDED & 
VAR_IN_DELETED_TRANSITION))) {
 
       //
       // EFI_VARIABLE_APPEND_WRITE attribute only effects for existing 
variable.
@@ -2340,9 +2347,9 @@
         // NOTE: From 0 to DataOffset of NextVariable is reserved for Variable 
Header and Name.
         // From DataOffset of NextVariable is to save the existing variable 
data.
         //
-        DataOffset = GetVariableDataOffset (Variable->CurrPtr);
+        DataOffset = GetVariableDataOffset (CacheVariable->CurrPtr);
         BufferForMerge = (UINT8 *) ((UINTN) NextVariable + DataOffset);
-        CopyMem (BufferForMerge, (UINT8 *) ((UINTN) Variable->CurrPtr + 
DataOffset), DataSizeOfVariable (Variable->CurrPtr));
+        CopyMem (BufferForMerge, (UINT8 *) ((UINTN) CacheVariable->CurrPtr + 
DataOffset), DataSizeOfVariable (CacheVariable->CurrPtr));
 
         //
         // Set Max Common/Auth Variable Data Size as default MaxDataSize.
@@ -2361,15 +2368,15 @@
           MaxDataSize = PcdGet32 (PcdMaxHardwareErrorVariableSize) - 
DataOffset;
         }
 
-        if (DataSizeOfVariable (Variable->CurrPtr) + DataSize > MaxDataSize) {
+        if (DataSizeOfVariable (CacheVariable->CurrPtr) + DataSize > 
MaxDataSize) {
           //
           // Existing data size + new data size exceed maximum variable size 
limitation.
           //
           Status = EFI_INVALID_PARAMETER;
           goto Done;
         }
-        CopyMem ((UINT8*) ((UINTN) BufferForMerge + DataSizeOfVariable 
(Variable->CurrPtr)), Data, DataSize);
-        MergedBufSize = DataSizeOfVariable (Variable->CurrPtr) + DataSize;
+        CopyMem ((UINT8*) ((UINTN) BufferForMerge + DataSizeOfVariable 
(CacheVariable->CurrPtr)), Data, DataSize);
+        MergedBufSize = DataSizeOfVariable (CacheVariable->CurrPtr) + DataSize;
 
         //
         // BufferForMerge(from DataOffset of NextVariable) has included the 
merged existing and new data.
@@ -2382,7 +2389,7 @@
       //
       // Mark the old variable as in delete transition.
       //
-      State = Variable->CurrPtr->State;
+      State = CacheVariable->CurrPtr->State;
       State &= VAR_IN_DELETED_TRANSITION;
 
       Status = UpdateVariableStore (
@@ -2456,7 +2463,7 @@
         // with the variable, we need associate the new timestamp with the 
updated value.
         //
         if (Variable->CurrPtr != NULL) {
-          if (VariableCompareTimeStampInternal 
(&(((AUTHENTICATED_VARIABLE_HEADER *) Variable->CurrPtr)->TimeStamp), 
TimeStamp)) {
+          if (VariableCompareTimeStampInternal 
(&(((AUTHENTICATED_VARIABLE_HEADER *) CacheVariable->CurrPtr)->TimeStamp), 
TimeStamp)) {
             CopyMem (&AuthVariable->TimeStamp, TimeStamp, sizeof (EFI_TIME));
           }
         }
@@ -2712,7 +2719,7 @@
       // Both ADDED and IN_DELETED_TRANSITION old variable are present,
       // set IN_DELETED_TRANSITION one to DELETED state first.
       //
-      State = Variable->InDeletedTransitionPtr->State;
+      State = CacheVariable->InDeletedTransitionPtr->State;
       State &= VAR_DELETED;
       Status = UpdateVariableStore (
                  &mVariableModuleGlobal->VariableGlobal,
@@ -3679,10 +3686,13 @@
   VariableStoreBase = (EFI_PHYSICAL_ADDRESS) ((UINTN) FvHeader + 
FvHeader->HeaderLength);
   VariableStoreLength = (UINT64) (NvStorageSize - FvHeader->HeaderLength);
 
+  mNvFvHeaderCache = FvHeader;
   mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = 
VariableStoreBase;
   mNvVariableCache = (VARIABLE_STORE_HEADER *) (UINTN) VariableStoreBase;
   if (GetVariableStoreStatus (mNvVariableCache) != EfiValid) {
     FreePool (NvStorageData);
+    mNvFvHeaderCache = NULL;
+    mNvVariableCache = NULL;
     DEBUG((EFI_D_ERROR, "Variable Store header is corrupted\n"));
     return EFI_VOLUME_CORRUPTED;
   }
@@ -3858,7 +3868,6 @@
   )
 {
   EFI_STATUS                      Status;
-  VARIABLE_STORE_HEADER           *VariableStoreHeader;
   UINTN                           Index;
   UINT8                           Data;
   EFI_PHYSICAL_ADDRESS            VariableStoreBase;
@@ -3871,18 +3880,17 @@
   if (NvStorageBase == 0) {
     NvStorageBase = (EFI_PHYSICAL_ADDRESS) PcdGet32 
(PcdFlashNvStorageVariableBase);
   }
-  VariableStoreBase = NvStorageBase + (((EFI_FIRMWARE_VOLUME_HEADER 
*)(UINTN)(NvStorageBase))->HeaderLength);
+  VariableStoreBase = NvStorageBase + (mNvFvHeaderCache->HeaderLength);
 
   //
   // Let NonVolatileVariableBase point to flash variable store base directly 
after FTW ready.
   //
   mVariableModuleGlobal->VariableGlobal.NonVolatileVariableBase = 
VariableStoreBase;
-  VariableStoreHeader = (VARIABLE_STORE_HEADER *)(UINTN)VariableStoreBase;
 
   //
   // Check if the free area is really free.
   //
-  for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < 
VariableStoreHeader->Size; Index++) {
+  for (Index = mVariableModuleGlobal->NonVolatileLastVariableOffset; Index < 
mNvVariableCache->Size; Index++) {
     Data = ((UINT8 *) mNvVariableCache)[Index];
     if (Data != 0xff) {
       //

Modified: trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c
===================================================================
--- trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c 
2015-10-23 02:03:20 UTC (rev 18653)
+++ trunk/edk2/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c 
2015-10-23 05:28:38 UTC (rev 18654)
@@ -4,6 +4,7 @@
 
 Copyright (C) 2013, Red Hat, Inc.
 Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
@@ -16,18 +17,19 @@
 
 #include "Variable.h"
 
-extern VARIABLE_STORE_HEADER   *mNvVariableCache;
-extern VARIABLE_INFO_ENTRY     *gVariableInfo;
-EFI_HANDLE                     mHandle                    = NULL;
-EFI_EVENT                      mVirtualAddressChangeEvent = NULL;
-EFI_EVENT                      mFtwRegistration           = NULL;
-extern BOOLEAN                 mEndOfDxe;
-VOID                           ***mVarCheckAddressPointer = NULL;
-UINTN                          mVarCheckAddressPointerCount = 0;
-EDKII_VARIABLE_LOCK_PROTOCOL   mVariableLock              = { 
VariableLockRequestToLock };
-EDKII_VAR_CHECK_PROTOCOL       mVarCheck                  = { 
VarCheckRegisterSetVariableCheckHandler,
-                                                              
VarCheckVariablePropertySet,
-                                                              
VarCheckVariablePropertyGet };
+extern VARIABLE_STORE_HEADER        *mNvVariableCache;
+extern EFI_FIRMWARE_VOLUME_HEADER   *mNvFvHeaderCache;
+extern VARIABLE_INFO_ENTRY          *gVariableInfo;
+EFI_HANDLE                          mHandle                    = NULL;
+EFI_EVENT                           mVirtualAddressChangeEvent = NULL;
+EFI_EVENT                           mFtwRegistration           = NULL;
+extern BOOLEAN                      mEndOfDxe;
+VOID                                ***mVarCheckAddressPointer = NULL;
+UINTN                               mVarCheckAddressPointerCount = 0;
+EDKII_VARIABLE_LOCK_PROTOCOL        mVariableLock              = { 
VariableLockRequestToLock };
+EDKII_VAR_CHECK_PROTOCOL            mVarCheck                  = { 
VarCheckRegisterSetVariableCheckHandler,
+                                                                    
VarCheckVariablePropertySet,
+                                                                    
VarCheckVariablePropertyGet };
 
 /**
   Return TRUE if ExitBootServices () has been called.
@@ -243,6 +245,7 @@
   EfiConvertPointer (0x0, (VOID **) 
&mVariableModuleGlobal->VariableGlobal.HobVariableBase);
   EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal);
   EfiConvertPointer (0x0, (VOID **) &mNvVariableCache);
+  EfiConvertPointer (0x0, (VOID **) &mNvFvHeaderCache);
 
   if (mAuthContextOut.AddressPointer != NULL) {
     for (Index = 0; Index < mAuthContextOut.AddressPointerCount; Index++) {


------------------------------------------------------------------------------
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to