* Delete the virtual mapping first before the the mapped range

is freed in MmFreeNonPagedPoolRegion.
* Adujust AllocMapHint only if the reserved block starts at AllocMapHint.
* Changed the bit allocation functions to RtlXxxBitMapYyy.

svn path=/trunk/; revision=3701
This commit is contained in:
Hartmut Birr 2002-11-05 20:41:17 +00:00
parent 3d3d96c5d6
commit 4fcb4176f8

View file

@ -1,4 +1,4 @@
/* $Id: kmap.c,v 1.21 2002/10/01 19:27:22 chorns Exp $
/* $Id: kmap.c,v 1.22 2002/11/05 20:41:17 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -26,9 +26,10 @@
* One bit for each page in the kmalloc region
* If set then the page is used by a kmalloc block
*/
static ULONG AllocMap[ALLOC_MAP_SIZE/32]={0,};
static UCHAR AllocMapBuffer[ROUND_UP(ALLOC_MAP_SIZE, 8) / 8];
static RTL_BITMAP AllocMap;
static KSPIN_LOCK AllocMapLock;
static ULONG AllocMapHint = 1;
static ULONG AllocMapHint = 0;
static PVOID NonPagedPoolBase;
@ -38,15 +39,14 @@ VOID
ExUnmapPage(PVOID Addr)
{
KIRQL oldIrql;
ULONG i = (Addr - NonPagedPoolBase) / PAGE_SIZE;
ULONG Base = (Addr - NonPagedPoolBase) / PAGE_SIZE;
DPRINT("ExUnmapPage(Addr %x)\n",Addr);
DPRINT("i %x\n",i);
MmDeleteVirtualMapping(NULL, (PVOID)Addr, FALSE, NULL, NULL);
KeAcquireSpinLock(&AllocMapLock, &oldIrql);
AllocMap[i / 32] &= (~(1 << (i % 32)));
AllocMapHint = min(AllocMapHint, i);
RtlClearBits(&AllocMap, Base, 1);
AllocMapHint = min(AllocMapHint, Base);
KeReleaseSpinLock(&AllocMapLock, oldIrql);
}
@ -99,35 +99,31 @@ PVOID
ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage)
{
KIRQL oldlvl;
ULONG addr;
ULONG i;
PVOID Addr;
ULONG Base;
NTSTATUS Status;
KeAcquireSpinLock(&AllocMapLock, &oldlvl);
for (i = AllocMapHint; i < ALLOC_MAP_SIZE; i++)
{
if (!(AllocMap[i / 32] & (1 << (i % 32))))
{
DPRINT("i %x\n",i);
AllocMap[i / 32] |= (1 << (i % 32));
AllocMapHint = i + 1;
addr = (ULONG)(NonPagedPoolBase + (i*PAGE_SIZE));
Status = MmCreateVirtualMapping(NULL,
(PVOID)addr,
PAGE_READWRITE | PAGE_SYSTEM,
PhysPage,
FALSE);
if (!NT_SUCCESS(Status))
{
DbgPrint("Unable to create virtual mapping\n");
KeBugCheck(0);
}
KeReleaseSpinLock(&AllocMapLock, oldlvl);
return((PVOID)addr);
}
}
Base = RtlFindClearBitsAndSet(&AllocMap, 1, AllocMapHint);
if (Base != 0xFFFFFFFF)
{
AllocMapHint = Base + 1;
KeReleaseSpinLock(&AllocMapLock, oldlvl);
Addr = NonPagedPoolBase + Base * PAGE_SIZE;
Status = MmCreateVirtualMapping(NULL,
Addr,
PAGE_READWRITE | PAGE_SYSTEM,
PhysPage,
FALSE);
if (!NT_SUCCESS(Status))
{
DbgPrint("Unable to create virtual mapping\n");
KeBugCheck(0);
}
return Addr;
}
KeReleaseSpinLock(&AllocMapLock, oldlvl);
return(NULL);
return NULL;
}
VOID
@ -135,6 +131,8 @@ MmInitKernelMap(PVOID BaseAddress)
{
NonPagedPoolBase = BaseAddress;
KeInitializeSpinLock(&AllocMapLock);
RtlInitializeBitMap(&AllocMap, (PVOID)&AllocMapBuffer, ALLOC_MAP_SIZE);
RtlClearAllBits(&AllocMap);
}
VOID
@ -142,21 +140,19 @@ MiFreeNonPagedPoolRegion(PVOID Addr, ULONG Count, BOOLEAN Free)
{
ULONG i;
ULONG Base = (Addr - NonPagedPoolBase) / PAGE_SIZE;
ULONG Offset;
KIRQL oldlvl;
KeAcquireSpinLock(&AllocMapLock, &oldlvl);
AllocMapHint = min(AllocMapHint, Base);
for (i = 0; i < Count; i++)
{
Offset = Base + i;
AllocMap[Offset / 32] &= (~(1 << (Offset % 32)));
{
MmDeleteVirtualMapping(NULL,
Addr + (i * PAGE_SIZE),
Free,
NULL,
NULL);
}
}
KeAcquireSpinLock(&AllocMapLock, &oldlvl);
RtlClearBits(&AllocMap, Base, Count);
AllocMapHint = min(AllocMapHint, Base);
KeReleaseSpinLock(&AllocMapLock, oldlvl);
}
@ -166,44 +162,21 @@ MiAllocNonPagedPoolRegion(ULONG nr_pages)
* FUNCTION: Allocates a region of pages within the nonpaged pool area
*/
{
unsigned int start = 0;
unsigned int length = 0;
unsigned int i,j;
ULONG Base;
KIRQL oldlvl;
KeAcquireSpinLock(&AllocMapLock, &oldlvl);
for (i=AllocMapHint; i<ALLOC_MAP_SIZE;i++)
{
if (!(AllocMap[i/32] & (1 << (i % 32))))
{
if (length == 0)
{
start=i;
length = 1;
}
else
{
length++;
}
if (length==nr_pages)
{
AllocMapHint = start + length;
for (j=start;j<(start+length);j++)
{
AllocMap[j / 32] |= (1 << (j % 32));
}
DPRINT("returning %x\n",((start*PAGE_SIZE)+NonPagedPoolBase));
KeReleaseSpinLock(&AllocMapLock, oldlvl);
return(((start*PAGE_SIZE)+NonPagedPoolBase));
}
}
else
{
start=0;
length=0;
}
}
DbgPrint("CRITICAL: Out of non-paged pool space\n");
KeBugCheck(0);
return(0);
Base = RtlFindClearBitsAndSet(&AllocMap, nr_pages, AllocMapHint);
if (Base == 0xFFFFFFFF)
{
DbgPrint("CRITICAL: Out of non-paged pool space\n");
KeBugCheck(0);
}
if (AllocMapHint == Base)
{
AllocMapHint += nr_pages;
}
KeReleaseSpinLock(&AllocMapLock, oldlvl);
DPRINT("returning %x\n",NonPagedPoolBase + Base * PAGE_SIZE);
return NonPagedPoolBase + Base * PAGE_SIZE;
}