[HALX86:DMA] Improve limitation of Scatter/Gather memory allocation (#8910)

CORE-20565

Estimate DMA memory needed staying conservative and use this for memory allocation.
This fixes a regression caused by [5418987](https://github.com/reactos/reactos/commit/5418987)
This commit is contained in:
Doug Lyons
2026-05-03 18:46:55 -05:00
committed by GitHub
parent ce53420875
commit 442892d14d

View File

@@ -77,9 +77,6 @@
#define NDEBUG
#include <debug.h>
// FIXME: This value needs to be calculated at runtime
#define MAX_SG_ELEMENTS 0x20
#ifndef _MINIHAL_
static KEVENT HalpDmaLock;
static KSPIN_LOCK HalpDmaAdapterListLock;
@@ -983,6 +980,8 @@ typedef struct _SCATTER_GATHER_CONTEXT {
WAIT_CONTEXT_BLOCK Wcb;
} SCATTER_GATHER_CONTEXT, *PSCATTER_GATHER_CONTEXT;
// FIXME: This value needs to be calculated at runtime
#define MAX_SG_ELEMENTS 0x30
IO_ALLOCATION_ACTION
NTAPI
@@ -997,6 +996,10 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject,
PSCATTER_GATHER_ELEMENT TempElements;
ULONG ElementCount = 0, RemainingLength = AdapterControlContext->Length;
PUCHAR CurrentVa = AdapterControlContext->CurrentVa;
// RemainingLength / PAGE_SIZE + 1 for the remainder of our division
// + 1 for a safety cushion gives a good safe value. Using the
// min function with MAX_SG_ELEMENTS keeps us from getting too large.
ULONG Est_SG_Elements = min(RemainingLength / PAGE_SIZE + 2, MAX_SG_ELEMENTS);
/* Store the map register base for later in HalPutScatterGatherList */
AdapterControlContext->MapRegisterBase = MapRegisterBase;
@@ -1004,7 +1007,7 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject,
// FIXME: HACK Allocate TempElements from pool to minimize stack usage.
// A more efficient algorithm should be found to avoid allocations during S/G I/O operations.
TempElements = ExAllocatePoolUninitialized(NonPagedPool,
sizeof(*TempElements) * MAX_SG_ELEMENTS,
sizeof(*TempElements) * Est_SG_Elements,
TAG_DMA);
if (!TempElements)
{
@@ -1034,6 +1037,9 @@ HalpScatterGatherAdapterControl(IN PDEVICE_OBJECT DeviceObject,
ElementCount++;
}
DPRINT("Est_SG_Elements %d\n", Est_SG_Elements);
DPRINT("ElementCount is %d\n", ElementCount);
if (RemainingLength > 0)
{
DPRINT1("Scatter/gather list construction failed!\n");