How to discover number of PFNs in the MDL and size of each page ?

Hi,

XP supports 2M and 4K pages. How can I know how many pages were used and
what pages ?

In my case buffers sometime come from user and sometimes are allocated
from nonpaged pool.

PS - I assume that PFN is a number that should be multiplied with page
size to get the physical addrees.

Dmitry Kaptsenel, Intel Software Solutions Group

On Sun, Apr 23, 2006 at 04:25:14PM +0300, Kaptsenel, Dmitry wrote:

Hi,

XP supports 2M and 4K pages. How can I know how many pages were used and
what pages ?

Actually, the P-II and beyond supports 4M and 4K pages.

But what are you talking about? Where are you getting page numbers?
Are you talking about an MDL? The numbers there will all be in units
of 4K, but you should be treating the structure as opaque anyway.

In my case buffers sometime come from user and sometimes are allocated
from nonpaged pool.

PS - I assume that PFN is a number that should be multiplied with page
size to get the physical addrees.

Where are you getting "PFN" from?

>But what are you talking about? Where are you getting page numbers?

Are you talking about an MDL? The numbers there will all be in units
of 4K, but you should be treating the structure as opaque anyway.

[Kaptsenel, Dmitry] MmGetMdlPfnArray() returns the pointer to the PFN
array. I just want to read it and build some structures to be passed to
some external device.

> In my case buffers sometime come from user and sometimes are
allocated
> from nonpaged pool.
>
> PS - I assume that PFN is a number that should be multiplied with
page
> size to get the physical addrees.

Where are you getting “PFN” from?

[Kaptsenel, Dmitry]

>MmGetMdlPfnArray() returns the pointer to the PFN

array. I just want to read it and build some structures to be passed to
some external device.

Not for DMA I hope…What exactly are you trying to do with this
information?

Also, just to clear up a point you made in your original post, whether the
pages have been mapped as large or not doesn’t affect the underlying
physical page size.

Regards,

-scott


Scott Noone
Software Engineer
OSR Open Systems Resources, Inc.
http://www.osronline.com.

“Kaptsenel, Dmitry” wrote in message
news:xxxxx@ntdev…

>But what are you talking about? Where are you getting page numbers?
>Are you talking about an MDL? The numbers there will all be in units
>of 4K, but you should be treating the structure as opaque anyway.

[Kaptsenel, Dmitry] MmGetMdlPfnArray() returns the pointer to the PFN
array. I just want to read it and build some structures to be passed to
some external device.

>> In my case buffers sometime come from user and sometimes are
allocated
>> from nonpaged pool.
>>
>> PS - I assume that PFN is a number that should be multiplied with
page
>> size to get the physical addrees.

>Where are you getting “PFN” from?

[Kaptsenel, Dmitry]

I doubt there’s a supported way to do this. The only time one is
usually worried about physical pages is for DMA, and then you get a
scatter-gather list from the DMA APIs. If you go through DMA mappings
you’ll get address/length tupples and you can program that to your
external device.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Kaptsenel, Dmitry
Sent: Monday, April 24, 2006 6:28 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] How to discover number of PFNs in the MDL and size
of each page ?

But what are you talking about? Where are you getting page numbers?
Are you talking about an MDL? The numbers there will all be in units
of 4K, but you should be treating the structure as opaque anyway.

[Kaptsenel, Dmitry] MmGetMdlPfnArray() returns the pointer to the PFN
array. I just want to read it and build some structures to be passed to
some external device.

> In my case buffers sometime come from user and sometimes are
allocated
> from nonpaged pool.
>
> PS - I assume that PFN is a number that should be multiplied with
page
> size to get the physical addrees.

Where are you getting “PFN” from?

[Kaptsenel, Dmitry]


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

>[Kaptsenel, Dmitry] MmGetMdlPfnArray() returns the pointer to the PFN

array. I just want to read it and build some structures to be passed to
some external device.

Why not use ->GetScatterGatherList instead?

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Kaptsenel, Dmitry wrote:

>But what are you talking about? Where are you getting page numbers?
>Are you talking about an MDL? The numbers there will all be in units
>of 4K, but you should be treating the structure as opaque anyway.
>
>

[Kaptsenel, Dmitry] MmGetMdlPfnArray() returns the pointer to the PFN
array. I just want to read it and build some structures to be passed to
some external device.

Ah, I see. Those numbers are always in units of 4k, even if it resides
in a 4M page. Otherwise, the values would not be unique.


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

Scott Noone wrote:

Also, just to clear up a point you made in your original post, whether the
pages have been mapped as large or not doesn’t affect the underlying
physical page size.

I think we are saying the same thing, but I’d like to clarify this a bit
for those who read the archives.

One virtual address maps to one physical address, but a single physical
address can be mapped to many different virtual addresses. It is quite
common for an I/O buffer to have three mappings: a user mapping, the
kernel’s 1-to-1 mapping, and a kernel driver’s own mapping.

It is the virtual address that determines the page table entry, which in
turn specifies 4M or 4k pages. Some of the virtual addresses might be
configured to use 4M pages, while some might be configured to use 4k
pages. Last time I looked, the 1-to-1 mapping used 4M pages, so that
typical I/O buffer I mentioned above would be such a case.

Since a page fault happens based on a virtual address, in a sense the
physical page size can vary as well. It is up to the system to figure
out whether it has to page in 4k or 4M bytes. However, unless I am
mistaken, XP uses 4M pages only for non-paged memory, so this isn’t a
problem in practice.

Regardless of that, the page number entries in an MDL are in 4k units.


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

I looked at GetScatterGatherList() but it is not doing the job I need.

My device should get some table that describes the physical structure of
the user message. User message is built of set of buffers. After the
device receives this it will use it later according to it’s own internal
algorithms. So I need to build some 2-level indirection tables (very
like x86 page tables structure in a theory) where the top level table
points (physically) to the list of Page Frame Numbers + size of the
intermediate tables that contain PFN numbers of user pages.
So I wanted to lock user buffers using MmProbeAndLockPages() and then
reuse the same MDL as my intermediate table. So all what I need to do
after this is to create one more level that will describe the physical
structure of the PFN list inside MDL (assuming that MDL itself is always
allocated in non-paged area). If user will pass more that single virtual
buffer this will result just in using more than one MDL for intermediate
level tables.


Dmitry Kaptsenel, Intel Software Solutions Group

>I looked at GetScatterGatherList() but it is not doing the job I need.

My device should get some table that describes the physical structure of
the user message.

Is your device DMA-ing to these pages? If so, then you need to call
GetScatterGatherList to translate the physical addresses described by the
MDL into a list of bus logical addresses suitable for DMA.
http://www.microsoft.com/whdc/driver/kernel/dma.mspx contains good
description of all of this.

If what you’re saying is that the Windows DMA abstraction does not suit your
needs then you’re off in undocumented/unsupported/not gonna work on all
systems territory.

Regards,

-scott


Scott Noone
Software Engineer
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Kaptsenel, Dmitry” wrote in message
news:xxxxx@ntdev…

I looked at GetScatterGatherList() but it is not doing the job I need.

My device should get some table that describes the physical structure of
the user message. User message is built of set of buffers. After the
device receives this it will use it later according to it’s own internal
algorithms. So I need to build some 2-level indirection tables (very
like x86 page tables structure in a theory) where the top level table
points (physically) to the list of Page Frame Numbers + size of the
intermediate tables that contain PFN numbers of user pages.
So I wanted to lock user buffers using MmProbeAndLockPages() and then
reuse the same MDL as my intermediate table. So all what I need to do
after this is to create one more level that will describe the physical
structure of the PFN list inside MDL (assuming that MDL itself is always
allocated in non-paged area). If user will pass more that single virtual
buffer this will result just in using more than one MDL for intermediate
level tables.


Dmitry Kaptsenel, Intel Software Solutions Group

>I looked at GetScatterGatherList() but it is not doing the job I need.

My device should get some table that describes the physical structure of
the user message. User message is built of set of buffers. After the

GetScatterGatherList is doing exactly what you need. It returns you the list of
(PhysAddr, Len) pairs which your hardware can interpret.

It is the same as analyzing the MDL itself, but can apply additional semantics
if the PCI bridges do some address translation. The physaddrs returned by the
GetScatterGatherList are really bus-side addresses, which your hardware can use
for DMA.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Unfortunately you don’t know you can safely perform DMA to a PFN you get
from the MDL. You only know DMA is safe to logical addresses that you
get out of the DMA DDI (GetScatterGatherList for one).

Typically you would allocate some Common Buffer up front and then
sub-allocate from that in order to create your physical address tables.
The logical addresses in the top level table are in common buffer. The
logical addresses in the second level table come from the scatter gather
list.

So take your request. Suballocate the common buffer you need in order
to create the tables. Then go through the DMA DDI to map the
user-buffer for DMA.

-p

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Kaptsenel, Dmitry
Sent: Monday, April 24, 2006 11:55 PM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] How to discover number of PFNs in the MDL and size
of each page ?

I looked at GetScatterGatherList() but it is not doing the job I need.

My device should get some table that describes the physical structure of
the user message. User message is built of set of buffers. After the
device receives this it will use it later according to it’s own internal
algorithms. So I need to build some 2-level indirection tables (very
like x86 page tables structure in a theory) where the top level table
points (physically) to the list of Page Frame Numbers + size of the
intermediate tables that contain PFN numbers of user pages.
So I wanted to lock user buffers using MmProbeAndLockPages() and then
reuse the same MDL as my intermediate table. So all what I need to do
after this is to create one more level that will describe the physical
structure of the PFN list inside MDL (assuming that MDL itself is always
allocated in non-paged area). If user will pass more that single virtual
buffer this will result just in using more than one MDL for intermediate
level tables.


Dmitry Kaptsenel, Intel Software Solutions Group


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

I looked once more at the GetScatterGatherList() …

Actually my device is sitting on the same Local APIC bus as a normal
processor - it is a dedicated processor that runs some real time OS. It
is like one of the processors on the SMP machine is stolen from the OS.
I need to pass it a physical addresses that it will add to it’s own page
tables and will be able to access the main memory.

I do not have any DMA adapter. All communication is done by putting some
data into the predefined physical page and sending IPI. So, … I got
your point. The PFN list in MDL structure is not documented and I need
either build on undocumented feature or build the PFN list myself using
MmGetPhysicalAddress().

Many thanks,


Dmitry Kaptsenel, Intel Software Solutions Group

>your point. The PFN list in MDL structure is not documented and I need

either build on undocumented feature or build the PFN list myself using
MmGetPhysicalAddress().

If there are no ways of instantiating an adapter object for your device - then
try using MmGetMdlPfnArray, it will return the physical page numbers. I don’t
know though how to convert them to physical addresses on a machine with
discontiguous memory
. On a usual machine, just multiply by 4096.

Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com

Does Windows use large pages for user mode apps at all?
( If not, then the MDLs in question can not refer to large pages, and the problem is dismissed.)

–PA

Both CreateFileMapping and VirtualAlloc have large page options (I’ve never
actually used them but I’m assuming they work). Really doesn’t matter
though, as has been discussed the MDL (as it currently exists) will still
describe the data buffer in PAGE_SIZE pieces.

-scott


Scott Noone
Software Engineer
OSR Open Systems Resources, Inc.
http://www.osronline.com

“Pavel A.” wrote in message news:xxxxx@ntdev…
> Does Windows use large pages for user mode apps at all?
> ( If not, then the MDLs in question can not refer to large pages, and the
> problem is dismissed.)
>
> --PA
>
>
>