]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/NvmExpressDxe: Memory leak fix in async code flow
authorSuman Prakash <suman.p@samsung.com>
Mon, 20 Mar 2017 08:34:55 +0000 (16:34 +0800)
committerHao Wu <hao.a.wu@intel.com>
Tue, 21 Mar 2017 02:01:44 +0000 (10:01 +0800)
For async commands, the buffer allocated for Prp list is
not getting freed, which will cause memory leak for async
read write command. For example testing async command flow
with custom application to send multiple read write commands
were resulting in decrease of available memory page in memmap,
which eventually resulted in system hang. Hence freeing
AsyncRequest->MapData, AsyncRequest->MapMeta, AsyncRequest->MapPrpList and
AsyncRequest->PrpListHost when async command is completed.

Cc: Feng Tian <feng.tian@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Suman Prakash <suman.p@samsung.com.com>
Reviewed-by: Hao Wu <hao.a.wu@intel.com>
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.c
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpress.h
MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressPassthru.c

index 39f49bd77459a2869cff13090f9c4e61c96a824e..de5c2a05eae1b4d5e00a24d733414f94ca3e46b5 100644 (file)
@@ -548,6 +548,7 @@ ProcessAsyncTaskList (
   QueueId    = 2;\r
   Cq         = Private->CqBuffer[QueueId] + Private->CqHdbl[QueueId].Cqh;\r
   HasNewItem = FALSE;\r
+  PciIo      = Private->PciIo;\r
 \r
   //\r
   // Submit asynchronous subtasks to the NVMe Submission Queue\r
@@ -644,6 +645,26 @@ ProcessAsyncTaskList (
           sizeof(EFI_NVM_EXPRESS_COMPLETION)\r
           );\r
 \r
+        //\r
+        // Free the resources allocated before cmd submission\r
+        //\r
+        if (AsyncRequest->MapData != NULL) {\r
+          PciIo->Unmap (PciIo, AsyncRequest->MapData);\r
+        }\r
+        if (AsyncRequest->MapMeta != NULL) {\r
+          PciIo->Unmap (PciIo, AsyncRequest->MapMeta);\r
+        }\r
+        if (AsyncRequest->MapPrpList != NULL) {\r
+          PciIo->Unmap (PciIo, AsyncRequest->MapPrpList);\r
+        }\r
+        if (AsyncRequest->PrpListHost != NULL) {\r
+          PciIo->FreeBuffer (\r
+                   PciIo,\r
+                   AsyncRequest->PrpListNo,\r
+                   AsyncRequest->PrpListHost\r
+                   );\r
+        }\r
+\r
         RemoveEntryList (Link);\r
         gBS->SignalEvent (AsyncRequest->CallerEvent);\r
         FreePool (AsyncRequest);\r
@@ -666,7 +687,6 @@ ProcessAsyncTaskList (
   }\r
 \r
   if (HasNewItem) {\r
-    PciIo = Private->PciIo;\r
     Data  = ReadUnaligned32 ((UINT32*)&Private->CqHdbl[QueueId]);\r
     PciIo->Mem.Write (\r
                  PciIo,\r
index 6a1c2575a3bd436cb55d76244b21efd7eafac75a..fa4a34ab53cb4b9a4dd378fa9ecc8aee7b9afb71 100644 (file)
@@ -292,6 +292,11 @@ typedef struct {
 \r
   EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet;\r
   UINT16                                   CommandId;\r
+  VOID                                     *MapPrpList;\r
+  UINTN                                    PrpListNo;\r
+  VOID                                     *PrpListHost;\r
+  VOID                                     *MapData;\r
+  VOID                                     *MapMeta;\r
   EFI_EVENT                                CallerEvent;\r
 } NVME_PASS_THRU_ASYNC_REQ;\r
 \r
index 2c300099455b49bc222cc63ba16f51bb465b691d..ef3d772cc28b1ebe640b066ee24da505fc5f4144 100644 (file)
@@ -627,6 +627,11 @@ NvmExpressPassThru (
     AsyncRequest->Packet        = Packet;\r
     AsyncRequest->CommandId     = Sq->Cid;\r
     AsyncRequest->CallerEvent   = Event;\r
+    AsyncRequest->MapData       = MapData;\r
+    AsyncRequest->MapMeta       = MapMeta;\r
+    AsyncRequest->MapPrpList    = MapPrpList;\r
+    AsyncRequest->PrpListNo     = PrpListNo;\r
+    AsyncRequest->PrpListHost   = PrpListHost;\r
 \r
     OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
     InsertTailList (&Private->AsyncPassThruQueue, &AsyncRequest->Link);\r