No right way to share PCI device memory with user mode?

Hi,
I’ve already asked this on comp.os.ms-windows.programmer.nt.kernlel-mode but
after a total lack of responses I am trying here in a last desperate
attempt.

My question should be simple: what is supposed to be right way
of sharing PCI device memory with an user mode application under W2K? I know
this has been asked lots of times. My search in Google found dozens
(if not hundreds!) of posts about this, but unfortunately not even one
sensible answer. Well, it is possible that I missed that one answer, in
which case I apologize and will be grateful for a reference to it.

Let me give you the information I have so far. The MSDN gives two possible
solutions. Unfortunately both of them seem to have problems: one aserts in
the checked build, the other is rumoured to be too slow.

Solution A (from Q189327 and Q191840):

Use MmMapIoSpace, IoAllocateMdl, MmBuildMdlForNonPagedPool,
MmMapLockedPages(UserMode).

This would have been my preferred solution since it also creates a virtual
address usable outside of the calling process context (the result of
MmMapIoSpace) and uses calls that are well understood and documented.
Unfortunately under the checked build of W2K (SP1), MmMapLockedPages asserts
with something like “ASSERT( Page > MmHighestPhysicalPage )” when the
address is in PCI device memory (as opposed to RAM).
Well, I know that this assertion is not so bad, it can be ignored (or even
better - patch the kernel at runtime not to generate it at all), but we use
W2K checked build for production testing and such behavior is unacceptable.

Solution B (from Q189327 and the MAPMEM sample from the NT 4.0 DDK):

Use ZwOpenSection(“\Device\PhysicalMemory”) and ZwMapViewOfSection. This
code seems a little more scary at first since ZwOpenSection and
ZwMapViewOfSection are not that well documented. However after a little
digging in the Platform SDK all parameters can be deciphered.
The problem here is the reports from several different people claiming that
this solution yields very bad performance when accessing the memory from
user mode.

I personally haven’t still measured the speed difference between Solution A
and B and for me currently Solution B is good enough since for my particular
application speed is not such of an issue (yet?). However I am surprised
that something so important and supposedly simple seems to have no
well-known solution.

-tzvetan


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

The MAPMEM way is slow and no more recommended.
Use MmMapLockedPages, but not for the whole memory of the card, only for the parts.

Max

----- Original Message -----
From: “Tzvetan Mikov”
To: “NT Developers Interest List”
Sent: Thursday, October 25, 2001 3:31 AM
Subject: [ntdev] No right way to share PCI device memory with user mode?

> Hi,
> I’ve already asked this on comp.os.ms-windows.programmer.nt.kernlel-mode but
> after a total lack of responses I am trying here in a last desperate
> attempt.
>
> My question should be simple: what is supposed to be right way
> of sharing PCI device memory with an user mode application under W2K? I know
> this has been asked lots of times. My search in Google found dozens
> (if not hundreds!) of posts about this, but unfortunately not even one
> sensible answer. Well, it is possible that I missed that one answer, in
> which case I apologize and will be grateful for a reference to it.
>
> Let me give you the information I have so far. The MSDN gives two possible
> solutions. Unfortunately both of them seem to have problems: one aserts in
> the checked build, the other is rumoured to be too slow.
>
> Solution A (from Q189327 and Q191840):
> ------------------
> Use MmMapIoSpace, IoAllocateMdl, MmBuildMdlForNonPagedPool,
> MmMapLockedPages(UserMode).
>
> This would have been my preferred solution since it also creates a virtual
> address usable outside of the calling process context (the result of
> MmMapIoSpace) and uses calls that are well understood and documented.
> Unfortunately under the checked build of W2K (SP1), MmMapLockedPages asserts
> with something like “ASSERT( Page > MmHighestPhysicalPage )” when the
> address is in PCI device memory (as opposed to RAM).
> Well, I know that this assertion is not so bad, it can be ignored (or even
> better - patch the kernel at runtime not to generate it at all), but we use
> W2K checked build for production testing and such behavior is unacceptable.
>
> Solution B (from Q189327 and the MAPMEM sample from the NT 4.0 DDK):
> ------------------
> Use ZwOpenSection(“\Device\PhysicalMemory”) and ZwMapViewOfSection. This
> code seems a little more scary at first since ZwOpenSection and
> ZwMapViewOfSection are not that well documented. However after a little
> digging in the Platform SDK all parameters can be deciphered.
> The problem here is the reports from several different people claiming that
> this solution yields very bad performance when accessing the memory from
> user mode.
>
> I personally haven’t still measured the speed difference between Solution A
> and B and for me currently Solution B is good enough since for my particular
> application speed is not such of an issue (yet?). However I am surprised
> that something so important and supposedly simple seems to have no
> well-known solution.
>
> -tzvetan
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
>


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

MmMapLockedPages asserts in the checked build of W2K if the address is
outside of RAM (which it is in this case), so this is an extremely
inconvenient solution, unfortunately. I however am starting to see that it
might be the only (publicly known?) one.

-tzvetan

----- Original Message -----
From: “Maxim S. Shatskih”
To: “NT Developers Interest List”
Sent: Thursday, October 25, 2001 8:23 AM
Subject: [ntdev] Re: No right way to share PCI device memory with user mode?

> The MAPMEM way is slow and no more recommended.
> Use MmMapLockedPages, but not for the whole memory of the card, only for
the parts.
>
> Max
>
> ----- Original Message -----
> From: “Tzvetan Mikov”
> To: “NT Developers Interest List”
> Sent: Thursday, October 25, 2001 3:31 AM
> Subject: [ntdev] No right way to share PCI device memory with user mode?
>
>
> > Hi,
> > I’ve already asked this on comp.os.ms-windows.programmer.nt.kernlel-mode
but
> > after a total lack of responses I am trying here in a last desperate
> > attempt.
> >
> > My question should be simple: what is supposed to be right way
> > of sharing PCI device memory with an user mode application under W2K? I
know
> > this has been asked lots of times. My search in Google found dozens
> > (if not hundreds!) of posts about this, but unfortunately not even one
> > sensible answer. Well, it is possible that I missed that one answer, in
> > which case I apologize and will be grateful for a reference to it.
> >
> > Let me give you the information I have so far. The MSDN gives two
possible
> > solutions. Unfortunately both of them seem to have problems: one aserts
in
> > the checked build, the other is rumoured to be too slow.
> >
> > Solution A (from Q189327 and Q191840):
> > ------------------
> > Use MmMapIoSpace, IoAllocateMdl, MmBuildMdlForNonPagedPool,
> > MmMapLockedPages(UserMode).
> >
> > This would have been my preferred solution since it also creates a
virtual
> > address usable outside of the calling process context (the result of
> > MmMapIoSpace) and uses calls that are well understood and documented.
> > Unfortunately under the checked build of W2K (SP1), MmMapLockedPages
asserts
> > with something like “ASSERT( Page > MmHighestPhysicalPage )” when the
> > address is in PCI device memory (as opposed to RAM).
> > Well, I know that this assertion is not so bad, it can be ignored (or
even
> > better - patch the kernel at runtime not to generate it at all), but we
use
> > W2K checked build for production testing and such behavior is
unacceptable.
> >
> > Solution B (from Q189327 and the MAPMEM sample from the NT 4.0 DDK):
> > ------------------
> > Use ZwOpenSection(“\Device\PhysicalMemory”) and ZwMapViewOfSection. This
> > code seems a little more scary at first since ZwOpenSection and
> > ZwMapViewOfSection are not that well documented. However after a little
> > digging in the Platform SDK all parameters can be deciphered.
> > The problem here is the reports from several different people claiming
that
> > this solution yields very bad performance when accessing the memory from
> > user mode.
> >
> > I personally haven’t still measured the speed difference between
Solution A
> > and B and for me currently Solution B is good enough since for my
particular
> > application speed is not such of an issue (yet?). However I am surprised
> > that something so important and supposedly simple seems to have no
> > well-known solution.
> >
> > -tzvetan
> >
> >
> > —
> > You are currently subscribed to ntdev as: xxxxx@storagecraft.com
> > To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com
> >
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@jupiter.com
> To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

> > > Absolutely. DDraw lets user mode application access the display surfaces

> > directly (look at IDirectDrawSurface7::Lock for example).
>
>Are you sure it does not do any double buffering?

DirectDraw definitely let’s an app read/write the primary display frame
buffer (the memory being used to refresh the current display), although

The what is the display driver’s support to do this?
Surely the display driver must have some “DDraw handler” which will call some OS’s functions to map the video memory to the user
process.

Is it VideoPortMapMemory? Maybe it is a good idea to disassemble it to know how DDraw’s mapping works?

Max


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com

It exposes the video buffer directly to user space. The only thing
unusual is that the buffer uses the later pNx86 write-combined stuff.
Video apps (i.e. games) are free to abuse the video ram anyway they see
fit.

I never said “NT doesn’t do that” I said I don’t believe it is a great
idea. Arguably video performance is important enough for some uses that
this one example is justified. In addition, as others have pointed out,
the AGP bus is essentially isolated so at least in theory an application
is not chomping the general purpose PCI bus bandwidth.

I’m not too big on the ‘appealing to what NT does as a HIGHER AUTHORITY
argument’ anyhow. It is just another operating system. Not a bad one,
but certainly not a perfect one.

The problem is that if one uses the video ram example as justification
one ends up with user mode driver solutions for general purpose IO, and
other than for prototyping, this is just not a good design direction,
Jungo and other examples not-withstanding.

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Maxim
S. Shatskih
Sent: Sunday, October 28, 2001 4:30 PM
To: NT Developers Interest List
Subject: [ntdev] RE: No right way to share PCI device memory
with user mode?

> > > Absolutely. DDraw lets user mode application access the display
> > > surfaces directly (look at IDirectDrawSurface7::Lock
for example).
> >
> >Are you sure it does not do any double buffering?
>
> DirectDraw definitely let’s an app read/write the primary display
> frame buffer (the memory being used to refresh the current
display),
> although

The what is the display driver’s support to do this?
Surely the display driver must have some “DDraw handler”
which will call some OS’s functions to map the video memory
to the user process.

Is it VideoPortMapMemory? Maybe it is a good idea to
disassemble it to know how DDraw’s mapping works?

Max


You are currently subscribed to ntdev as:
xxxxx@hollistech.com To unsubscribe send a blank email to
leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com