Allocating physical memory using AllocateCommonBuffer

Hello,

I added the following code to the end of EchoDeviceCreate in the echo driver sample:

PDEVICE_OBJECT DeviceObject;
PVOID p;
PHYSICAL_ADDRESS LogicalAddress;
DEVICE_DESCRIPTION deviceDescription;
ULONG NumberOfMapRegisters;
PDMA_ADAPTER DmaAdapterObject;

DeviceObject = WdfDeviceWdmGetPhysicalDevice(device);
RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));
DmaAdapterObject = IoGetDmaAdapter(DeviceObject,&deviceDescription, &NumberOfMapRegisters);
deviceContext->AllocateCommonBuffer =
*DmaAdapterObject->DmaOperations->AllocateCommonBuffer;
p=deviceContext->AllocateCommonBuffer(DmaAdapterObject, 64*1024,&LogicalAddress,FALSE);

When the driver is enabled, p gets a value, so AllocateCommonBuffer is OK.

But when the size of allocated buffer is 128*1024 (and not 64*1024), the return value of AllocateCommonBuffer is 0x0.

Can you tell why ?

Can WDK (or windows) give some hints on the cause to the problem ?

I have to allocate a continuous physical buffer used later by hardware.

Thanks,
Zvika.

> Can WDK (or windows) give some hints on the cause to the problem ?

Yes it can, at least to these who reads the [fine] documentation.

  1. After RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));
    do you initialize some fields of it before calling IoGetDmaAdapter?

  2. the documentation says:
    "After start-up, it is possible that only one-page requests will succeed, if any. "
    So it actually even does not promise that 64K will be allocated.

http://msdn.microsoft.com/en-us/library/ff540575(VS.85).aspx

Regards,
–pa

Dear Pavel,

I did not set any field in deviceDescription.

I need to allocate 128MB of continuous physical memory.

How can I do it ?

Thanks,
Zvika.

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Sunday, May 01, 2011 22:50
Subject: RE:[ntdev] Allocating physical memory using AllocateCommonBuffer

>> Can WDK (or windows) give some hints on the cause to the problem ?
>
> Yes it can, at least to these who reads the [fine] documentation.
>
> 1. After RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));
> do you initialize some fields of it before calling IoGetDmaAdapter?
>
> 2. the documentation says:
> "After start-up, it is possible that only one-page requests will succeed,
> if any. "
> So it actually even does not promise that 64K will be allocated.
>
> http://msdn.microsoft.com/en-us/library/ff540575(VS.85).aspx
>
> Regards,
> --pa
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Dear Pavel,

When I set deviceDescription to:

deviceDescription.Master = TRUE;
deviceDescription.ScatterGather = FALSE;
deviceDescription.Dma32BitAddresses = FALSE;
deviceDescription.Dma64BitAddresses = TRUE;
deviceDescription.InterfaceType = PCIBus;
deviceDescription.MaximumLength = 128*1024*1024; //128MB

AllocateCommonBuffer succeeded to allocate 32MB.

When I tried to allocate 64MB, AllocateCommonBuffer returned NULL.

What is the maximum size of continuous physical memory I can allocate ?

Thanks,
Zvika.

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Sunday, May 01, 2011 22:50
Subject: RE:[ntdev] Allocating physical memory using AllocateCommonBuffer

>> Can WDK (or windows) give some hints on the cause to the problem ?
>
> Yes it can, at least to these who reads the [fine] documentation.
>
> 1. After RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));
> do you initialize some fields of it before calling IoGetDmaAdapter?
>
> 2. the documentation says:
> "After start-up, it is possible that only one-page requests will succeed,
> if any. "
> So it actually even does not promise that 64K will be allocated.
>
> http://msdn.microsoft.com/en-us/library/ff540575(VS.85).aspx
>
> Regards,
> --pa
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

Maybe there isn’t any available 128MB chunk of contiguous physical
memory on this system.
As Pavel already pointed out: “After start-up, it is possible that
only one-page requests will succeed, if any.”

Kris

“Zvi Vered” wrote in message news:xxxxx@ntdev…

> AllocateCommonBuffer succeeded to allocate 32MB.
>
> When I tried to allocate 64MB, AllocateCommonBuffer returned NULL.
>
> What is the maximum size of continuous physical memory I can allocate ?

This depends. As always, the later you arrive, the less continuous space is
left.

(see this thread:
http://social.msdn.microsoft.com/Forums/en-US/wdk/thread/af772fc4-aecc-4b73-a28d-02513f924d8f
http://social.msdn.microsoft.com/Forums/en-US/wdk/thread/e8dd2451-645e-4499-944a-aa8fd7230b44
)

My guess is that you can allocate quite a lot very early.
So you can try to grab this amount or more of contiguous RAM in a helper
non-PnP driver that starts early, and release it immediately before
calling AllocateCommonBuffer.

As a more serious long term plan - consider a more suitable operating
system…
which, by the way, won’t mind if your drivers are unsigned :slight_smile:

Regards,
– pa

> My guess is that you can allocate quite a lot very early.

So you can try to grab this amount or more of contiguous RAM in a
helper
non-PnP driver that starts early, and release it immediately before
calling AllocateCommonBuffer.

As a more serious long term plan - consider a more suitable operating
system…
which, by the way, won’t mind if your drivers are unsigned :slight_smile:

I’m as big a Linux fanboi as you’ll find, but I think the bigger problem
here is hardware that needs physically contiguous system memory.

James

“James Harper” wrote in message
news:xxxxx@ntdev…
>> My guess is that you can allocate quite a lot very early.
>> So you can try to grab this amount or more of contiguous RAM in a
> helper
>> non-PnP driver that starts early, and release it immediately before
>> calling AllocateCommonBuffer.
>>
>> As a more serious long term plan - consider a more suitable operating
>> system…
>> which, by the way, won’t mind if your drivers are unsigned
>>
>
> I’m as big a Linux fanboi as you’ll find, but I think the bigger problem
> here is hardware that needs physically contiguous system memory.

My guess is that the OP uses Windows only for prototyping,
the real thing may run on other OS, not nesessarily Linux.

And there the system designer is the king. If he says that half of the RAM
must be
the common DMA buffer, so it will be.They can patch the kernel if needed.
When hardware is a problem, software provides solution :wink:

Neverheless, I am still a big fan of MS…
–pa

Zvi Vered wrote:

When I set deviceDescription to:

deviceDescription.Master = TRUE;
deviceDescription.ScatterGather = FALSE;
deviceDescription.Dma32BitAddresses = FALSE;
deviceDescription.Dma64BitAddresses = TRUE;
deviceDescription.InterfaceType = PCIBus;
deviceDescription.MaximumLength = 128*1024*1024; //128MB

AllocateCommonBuffer succeeded to allocate 32MB.

When I tried to allocate 64MB, AllocateCommonBuffer returned NULL.

What is the maximum size of continuous physical memory I can allocate ?

Others have already told you this, and a few minutes of web searching
would also have shown you the many exchanges about this.

Physical memory gets fragmented very quickly. Immediately after boot,
you can get a pretty good-sized chunk. As time goes on, the size of the
largest contiguous block gets smaller and smaller. After 10 or 15
minutes, the largest block is often less than a dozen megabytes. There
is no good way to “compact” physical memory. The system tries a few
things, but they are not guaranteed.

128MB is not a reasonable request. You need to find another way to
solve your problem.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Dear Pavel,

You are right. When I enabled the driver manually, the allocatation failed.

But when the driver was automatically enabled during boot, the allocation
succeeded.

I’m aware that allocating such continuous space (128MB) in a device driver
is not healthy.

Thank you for your help,

Zvika.

----- Original Message -----
From:
To: “Windows System Software Devs Interest List”
Sent: Sunday, May 01, 2011 22:50
Subject: RE:[ntdev] Allocating physical memory using AllocateCommonBuffer

>> Can WDK (or windows) give some hints on the cause to the problem ?
>
> Yes it can, at least to these who reads the [fine] documentation.
>
> 1. After RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));
> do you initialize some fields of it before calling IoGetDmaAdapter?
>
> 2. the documentation says:
> "After start-up, it is possible that only one-page requests will succeed,
> if any. "
> So it actually even does not promise that 64K will be allocated.
>
> http://msdn.microsoft.com/en-us/library/ff540575(VS.85).aspx
>
> Regards,
> --pa
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer

> I need to allocate 128MB of continuous physical memory.

How can I do it ?

As you was already told, this is impossible in Windows (with guarantees).


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> As a more serious long term plan - consider a more suitable operating

system…
which, by the way, won’t mind if your drivers are unsigned :slight_smile:

Can Linux provide 100% guarantee that 128MB physical can be allocated at any point?


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

No it can’t I’ve seen “pre allocation” drivers in Linux, because of
memory fragmentation.

I’ve used a legacy boot time driver to allocate large blocks of
contiguous memory in Windows for special purpose systems that had
hardware that required it. You have the legacy driver do the
allocation, and then the driver needing the memory issues an IOCTL to
the legacy driver to get the memory. I’ve been able to get 1GB
contiguous memory chunks on Win 7.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev:

> > As a more serious long term plan - consider a more suitable operating
> > system…
> > which, by the way, won’t mind if your drivers are unsigned :slight_smile:
>
> Can Linux provide 100% guarantee that 128MB physical can be allocated at any point?
>
> –
> Maxim S. Shatskih
> Windows DDK MVP
> xxxxx@storagecraft.com
> http://www.storagecraft.com

>

> As a more serious long term plan - consider a more suitable
operating
> system…
> which, by the way, won’t mind if your drivers are unsigned :slight_smile:

Can Linux provide 100% guarantee that 128MB physical can be allocated
at any
point?

Of course, within certain parameters. You have access the complete
kernel code so you can do whatever you want.

It’s a completely different ballgame to Windows. If I write a regular
driver under windows and don’t do anything stupid I can be pretty much
guaranteed that it will run on any future update to current versions of
Windows, and there’s a good chance it will run on any version of windows
released in the next 5 years (eg pretty much the life of any hardware
you buy today). If Microsoft does release a change that breaks my driver
and my company has gone out of business, my hardware becomes useless. If
I write a driver under Linux that is not part of the mainline kernel
there is no guarantee it will run when the next version of the kernel
comes out tomorrow. OTOH, if there were any problems I’d almost
certainly have a fix the day after tomorrow, and if I wasn’t around,
everyone has access to the source so it will probably be fixed by
someone else. Completely different mindset.

Pretty much nothing is impossible under Linux, but there are costs
associated with that flexibility. If making 128MB physically contiguous
memory be available involves a kernel change then the users of my driver
need to know how to patch and recompile a kernel, and that isn’t
acceptable to most end users even if the process is highly streamlined
these days in most distributions.

Linux frustrates me sometimes because the API is somewhat fluid. But if
a change to the API breaks something I can fix it. And if I need to do
something I can tinker with the kernel until it will obey my whim. And
while the documentation is pretty much non-existent, the code is there
so I can see exactly how it works.

Windows frustrates me sometimes because while the documentation is
very good, if there is a point of ambiguity I have to either look
around for example code to figure out what it is doing and hope that the
person who wrote the code knew what they were doing, or post on ntdev. I
can’t look at the source and see what is wrong (unless I want to reverse
engineer it, and who wants to do that?). I spent about two weeks
recently trying to fix a hibernate bug. I’m pretty sure it’s a bug in
the power state interaction between PCI’s DMA adapter, my WDF driver, a
the PDO of my WDF bus driver, and scsiport (the ultimate consumer of the
DMA adapter) but I can’t tell for sure because I can’t look at the
Microsoft code to figure out what is going on, and the people who can
access the code have other things to do than worry about why an 8 year
old OS with deprecated everything doesn’t do what I want, especially
when the problem could likely turn out to be a bug in my code anyway.

James

“Can Linux provide 100% guarantee that 128MB physical can be allocated at any
point?”

In our experience, Windows 2008+ has been more successful for large buffer allocations than Linux. Unlike older versions, it can grab unlocked pages to make a contiguous physical region. Although if one is running x86 flavor, 128 MB is pretty much a matter of luck.

Maxim S. Shatskih wrote:

> As a more serious long term plan - consider a more suitable operating
> system… which, by the way, won’t mind if your drivers are unsigned :slight_smile:
Can Linux provide 100% guarantee that 128MB physical can be allocated at any point?

No. Indeed, we found physical fragmentation to be more of an issue in
Linux than it was in XP. In XP, the operating system will try (for a
while) to shuffle things around to free up a larger block. Linux just
says “no”. Whereas we were always able to find a number of 2MB blocks
in an XP system that had been operating for a while, in Linux we could
not grab anything bigger than 128kB.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.