BSOD in MmMapLockedPagesSpecifyCache

Hi all,

I want some memory pages to be locked in memory to be a share memory between user and kernel.
When I use MmMapLockedPagesSpecifyCache to lock some user memory space, it will crash sometimes.
Note:OS is win8 32bit
Here are my codes

lowAddress.QuadPart = 0;
highAddress.QuadPart = 0xFFFFFFFFFFFFFFFF;
totalBytes = 1024*1024;

mdl = MmAllocatePagesForMdl(lowAddress,highAddress,lowAddress,totalBytes);

if(!mdl)
return STATUS_INSUFFICIENT_RESOURCES;

__try{
userVAToReturn =
MmMapLockedPagesSpecifyCache(mdl, // MDL
UserMode, // Mode
MmCached, // Caching
NULL, // Address
FALSE, // Bugcheck?
HighPagePriority); // Priority
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
status = GetExceptionCode();
}
if(!userVAToReturn) {
MmFreePagesFromMdl(mdl);
IoFreeMdl(mdl);
return STATUS_INSUFFICIENT_RESOURCES;
}

*UserVa = userVAToReturn;
*PMemMdl = mdl;

return STATUS_SUCCESS;

debug message:

*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

KERNEL_DATA_INPAGE_ERROR (7a)
The requested page of kernel data could not be read in. Typically caused by
a bad block in the paging file or disk controller error. Also see
KERNEL_STACK_INPAGE_ERROR.
If the error status is 0xC000000E, 0xC000009C, 0xC000009D or 0xC0000185,
it means the disk subsystem has experienced a failure.
If the error status is 0xC000009A, then it means the request failed because
a filesystem failed to make forward progress.
Arguments:
Arg1: 00000001, lock type that was held (value 1,2,3, or PTE address)
Arg2: d0000006, error status (normally i/o status code)
Arg3: 843ee580, current process (virtual address for lock type 3, or PTE)
Arg4: c0011000, virtual address that could not be in-paged (or PTE contents if arg1 is a PTE address)

Debugging Details:

TRIAGER: Could not open triage file : c:\program files (x86)\windows kits\8.0\debuggers\x64\triage\modclass.ini, error 2

ERROR_CODE: (NTSTATUS) 0xd0000006 - 0x%p

BUGCHECK_STR: 0x7a_d0000006

DEFAULT_BUCKET_ID: WIN8_DRIVER_FAULT

PROCESS_NAME: RAPT.exe

CURRENT_IRQL: 2

DEVICE_OBJECT: 86043d80

DRIVER_OBJECT: 84f2f370

IMAGE_NAME: OsrSVMStor.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 50053064

FAULTING_MODULE: 82342000 fltmgr

LAST_CONTROL_TRANSFER: from 81ad1b63 to 81aa99d0

STACK_TEXT:
9ec0af3c 81ad1b63 00000003 b5296bc8 0000007a nt!RtlpBreakWithStatusInstruction
9ec0af8c 81ad11a4 00000003 81c26138 9ec0b394 nt!KiBugCheckDebugBreak+0x1c
9ec0b368 81aa863a 0000007a 00000001 d0000006 nt!KeBugCheck2+0x594
9ec0b38c 81aa8571 0000007a 00000001 d0000006 nt!KiBugCheck2+0xc6
9ec0b3ac 81b501ea 0000007a 00000001 d0000006 nt!KeBugCheckEx+0x19
9ec0b3e4 81a8758d c0011000 00000000 00000000 nt! ?? ::FNODOBFM::string'+0x25cc3 9ec0b43c 81dbd814 02200000 84400bfc 00000000 nt!MiMapLockedPagesInUserSpaceHelper+0xc6 9ec0b48c 81b50250 84400be0 000022ff 00000001 nt!MiMapLockedPagesInUserSpace+0x28f 9ec0b4f8 9ff78ebc 84400be0 00000001 00000001 nt! ?? ::FNODOBFM::string’+0x25d1e
9ec0b564 9ff73fe5 840a1ff8 840a1ff4 516373d5 OsrSVMStor!CreateAndMapMemory+0xdc
9ec0b750 9ff72b1f 840a1c28 84f34830 874c1f58 OsrSVMStor!OsrUserHandleSrb+0x295
9ec0b77c 9ff72031 874c1f58 84f34830 9ec0b79e OsrSVMStor!OsrVmExecuteScsi+0x1af
9ec0b7a0 822da18d 874c1f58 84f34830 843ea920 OsrSVMStor!OsrHwStartIo+0x61
9ec0b7e0 822d9bed 842a10e0 00000000 9ec0b834 storport!RaidAdapterPostScatterGatherExecute+0x1f4
9ec0b7f0 822f2c53 842a10e0 8464f450 843ea920 storport!RaidAdapterExecuteXrb+0x4d
9ec0b834 822e3615 845cb030 843ea920 9ec0b854 storport!RaUnitStartIo+0x162
9ec0b874 822f3a1f 003ea990 843ea920 00000001 storport!RaidStartIoPacket+0x143
9ec0b89c 822f5c88 845cb0e8 00000000 843ea920 storport!RaidUnitSubmitRequest+0xca
9ec0b8e4 822e1a54 845cb0e8 843ea920 874b66c8 storport!RaUnitScsiIrp+0x206
9ec0b900 81baa07d 845cb030 843ea920 84f34830 storport!RaDriverScsiIrp+0x5d
9ec0b918 82303f68 9dfd6808 00100000 00000000 nt!IofCallDriver+0x3d
9ec0b96c 823041bd 845cb030 9dfd6808 00000001 storport!PortPassThroughSendAsync+0x117
9ec0b9a0 822fe8b8 845cb030 9dfd6808 00000001 storport!PortPassThroughExSendAsync+0x36
9ec0b9cc 822dcb62 842a10e0 845cb0e8 00000001 storport!RaidAdapterPassThrough+0x84
9ec0ba08 822e1b08 842a10e0 9dfd6808 845cb0e8 storport!RaidAdapterDeviceControlIrp+0x1d1
9ec0ba28 81baa07d 842a1028 9dfd6808 842a10e0 storport!RaDriverDeviceControlIrp+0x6a
9ec0ba40 823023fb 9dfd6808 845cb0e8 0004d014 nt!IofCallDriver+0x3d
9ec0ba68 822f54f6 845cb0e8 9dfd6808 9dfd6808 storport!RaUnitScsiPassThroughIoctl+0xe9
9ec0bab0 822e1aff 845cb0e8 9dfd6808 9dfd6974 storport!RaUnitDeviceControlIrp+0x23d
9ec0bad0 81baa07d 845cb030 9dfd6808 0004d014 storport!RaDriverDeviceControlIrp+0x61
9ec0bae8 82d22daa 9dfd6808 00000005 000012c0 nt!IofCallDriver+0x3d
9ec0bc10 82d076a9 84531718 9dfd6808 84343d38 CLASSPNP!ClassDeviceControl+0x13a
9ec0bc54 82d29d0f 84531718 9dfd6808 00000001 disk!DiskDeviceControl+0x105
9ec0bc70 82d2ffc9 84531718 9dfd6808 845317d0 CLASSPNP!ClassDeviceControlDispatch+0x8f
9ec0bc88 81baa07d 84531718 9dfd6808 9dfd6808 CLASSPNP!ClassGlobalDispatch+0x39
9ec0bca0 8837b066 84343d70 9dfd6808 00000050 nt!IofCallDriver+0x3d
9ec0bce4 88373cab 84343c80 9dfd6808 9dfd6974 partmgr!PmIoctlRedirect+0x61
9ec0bd04 883731d8 84343c80 84343d70 8460d778 partmgr!PmFilterDeviceControl+0xfd
9ec0bd38 81baa07d 84343c80 9dfd6808 9dfd6808 partmgr!PmGlobalDispatch+0x1d3
9ec0bd50 88373a0d 8460d6c0 9dfd6808 9dfd6974 nt!IofCallDriver+0x3d
9ec0bd74 883731d8 8460d6c0 9dfd6808 9dfd6990 partmgr!PmLegacyDeviceControl+0xe7
9ec0bda8 81baa07d 8460d6c0 9dfd6808 84608d28 partmgr!PmGlobalDispatch+0x1d3
9ec0bdc0 883bf5ae 9dfd6808 84608c70 845b300e nt!IofCallDriver+0x3d
9ec0bdf4 81baa07d 84608c70 9dfd6808 845b30d8 volmgr!VmDeviceControl+0x280
9ec0be0c 82c210a7 845b3020 9ec0be60 82c211e2 nt!IofCallDriver+0x3d
9ec0be18 82c211e2 845b3020 9dfd6808 8430d230 fvevol!FveFilterSkip+0x31
9ec0be60 81baa07d 845b3020 9dfd6808 9dfd6808 fvevol!FveFilterDeviceControl+0x130
9ec0be78 82cbe3c5 00000000 8430d160 9ec0bec8 nt!IofCallDriver+0x3d
9ec0be88 82cbe501 8430d160 9dfd6808 009b2f5d rdyboost!SmdDispatchPassthrough+0x69
9ec0bec8 81baa07d 8430d160 9dfd6808 9dfd6808 rdyboost!SmdDispatchDeviceControl+0x63
9ec0bee0 82c8243a 9ec0bfe0 845e8610 8434160e nt!IofCallDriver+0x3d
9ec0bf1c 81baa07d 845e8610 9dfd6808 84341600 volsnap!VolSnapDeviceControl+0x6e
9ec0bf34 82639844 97ff6a50 9ec0bf54 81aa8c62 nt!IofCallDriver+0x3d
9ec0bf40 81aa8c62 97ff6b18 ffffffff 81acf267 Ntfs!NtfsStorageDriverCallout+0x14
9ec0bf40 81a3ec8b 97ff6b18 ffffffff 81acf267 nt!KiSwitchKernelStackAndCallout+0x9e
97ff6ae0 81a3eb09 82639830 97ff6b18 00003000 nt!KeExpandKernelStackAndCalloutInternal+0x16b
97ff6afc 8263361e 82639830 97ff6b18 00003000 nt!KeExpandKernelStackAndCalloutEx+0x1e
97ff6b28 826b429a 9dfd6808 00000000 28eed83d Ntfs!NtfsCallStorageDriver+0x2a
97ff6b98 81baa07d 845eb018 9dfd6808 0000010e Ntfs!NtfsFsdDeviceControl+0xcb
97ff6bb0 823430f2 87414420 86043d80 0000010e nt!IofCallDriver+0x3d
97ff6be4 81baa07d 86043d80 9dfd6808 00000100 fltmgr!FltpDispatch+0xed
97ff6bfc 81c68baf 9dfd69e0 9dfd6808 00000050 nt!IofCallDriver+0x3d
97ff6c50 81c68622 86043d80 00000000 81c87601 nt!IopSynchronousServiceTail+0x10a
97ff6cf0 81c6824f 00000001 9dfd6808 00000000 nt!IopXxxControlFile+0x3b7
97ff6d24 81b220bc 000000cc 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
97ff6d24 77b85ee4 000000cc 00000000 00000000 nt!KiFastCallEntry+0x12c
021ff900 77b84f96 77b1d408 000000cc 00000000 ntdll!KiFastSystemCallRet
021ff904 77b1d408 000000cc 00000000 00000000 ntdll!NtDeviceIoControlFile+0xa
021ff95c 7539d798 000000cc 00000000 00000000 verifier!AVrfpNtDeviceIoControlFile+0x10d
021ff9bc 756228c8 000000cc 0004d014 021ffa18 KERNELBASE!DeviceIoControl+0x77
021ff9e8 00401bd6 000000cc 0004d014 021ffa18 KERNEL32!DeviceIoControlImplementation+0x3d0

Thanks for any reply.

The arguement UserMode can only be used at IRQL <= APC_LEVEL. The output from the crash dump suggests the IRQL is at DISPATCH_LEVEL. You may be holding a spin lock, which is not allowed.

1.StartIo is NOT guaranteed to be called in the context of the requesting process.
2. StartIo is usually called on IRQL>=DISPATCH_LEVEL, except for some special SRBs (PNP, POWER).

Thanks for your quickly reply.
How to solve this problem?
I just want to create a shared memory between specified user application and driver.

xxxxx@gmail.com wrote:

Thanks for your quickly reply.
How to solve this problem?
I just want to create a shared memory between specified user application and driver.

Did you look over that stack dump? You are 13 levels deep here – there
are 12 other drivers between you and the application. It seems very
unlikely that you will be able to establish any kind of a “connection”
to the user application.

What are you really trying to do here? How did you expect to pass the
address of the shared memory back to the user application?


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

WHy do you want shared memory? Are you solving a performance problem?

Yes, I want to create the shared memory for data transfer between user and driver.
For some performance concern, share memory is more suitable for me.
Is there any other way to create share memory can be used to my driver?

OT: Why does every new poster think that shared memory is faster than
anything else? My personal opinion is that they are uneducated and fail to
realize that almost every idea that they may have has already been thought
of and that the standard methods are the culmination of decades of work by
those who may have forgotten as much about the topic at the time they were
born as they know now.

To the OP: forget that you ever heard of shared memory or its being better
than something else in some circumstances. Unless you are working on an
embedded system, it is an abomination, and even there it is a hack.
Whatever is wrong with your hardware, driver, application, using shared
memory will not solve it.

Note that all of this comes from someone who routinely writes stuff designed
contrary to industry standard best practices and conventional wisdom. The
key is to know what one is doing when going off of the reservation; and
forgive me for being blunt, but if you are asking for help, then you don’t.

wrote in message news:xxxxx@ntdev…

Yes, I want to create the shared memory for data transfer between user and
driver.
For some performance concern, share memory is more suitable for me.
Is there any other way to create share memory can be used to my driver?

> I just want to create a shared memory between specified user application and driver.

From a STORPORT miniport? Try doing this in FindAdapter.

Impossible in StartIo.

What problem do you want to solve?


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

> Yes, I want to create the shared memory for data transfer between user and driver.

The best solution for a StorPort miniport is to create a fake “Processor”-class LUN on it, and send some special requests to it from your “master” app which requires memory sharing.

You can use custom CDBs for these requests.

One of the requests - which you should design yourself - is like “please remember this shared memory”. At this request, the driver has the physical addresses of the memory. The request can be pended nearly forever.

Another request should be “please update the head/tail pointers in this shared memory”.

But a much simpler way is just send “get next request” and “complete next request” special CDBs to the “Processor” LUN. The overall design is called “inverted call” and is very similar to, say, “tun” network adapter in UNIXen.


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

OMG! Not another Shared Memory Hack!!!

This usually marks you as a newbie. Experienced driver writers avoid
these solutions, and in the unlikely situation where they need it, they
are experienced enough that they know how to do it. If you have to ask,
it means you don’t know enough to know that you shouldn’t do this. If you
think you need it, the probability that you are wrong is asymptotically
close to 1.0.

This is the most common Bad Idea we see here. There are a very small
number of situations in which this matters, and the probability you have
one of these is close to 0.0.

Shared memory sounds cool. It isn’t. It adds amazing amounts of
gratuitous complexity to a problem domain that already has massive
intrinsic complexity.

If you are solving a performance problem, where is the data that proves
that (a) you have a performance problem and (b) shared memory will solve
it? This means you have to first build a driver, instrument it, determine
there is a problem cause by memory usage, and determine that shared memory
will solve it. Any other approach falls somewhere between insane and
irresponsible.

Forget you ever heard of shared memory. This is some weird idea left over
from some inappropriate previous experience. Build a plain, ordinary
driver. That’s generally hard enough. Remember that asynchronous
(FILE_FLAG_OVERLAPPED) I/O can cause whatever problem you think you have
to go away.

More comments below in the code

Hi all,

I want some memory pages to be locked in memory to be a share memory
between user and kernel.
When I use MmMapLockedPagesSpecifyCache to lock some user memory space,
it
will crash sometimes.
Note:OS is win8 32bit
Here are my codes

Since you don’t give any context where this code exists, or where it is
called from, it is completely useless to show it

lowAddress.QuadPart = 0;
highAddress.QuadPart = 0xFFFFFFFFFFFFFFFF;
totalBytes = 1024*1024;

Are any of these variables important? If not, why do you show them being
set? If they are, why aren’t their declarations shown, so we know
important facts about them, such as their scope?

mdl =
MmAllocatePagesForMdl(lowAddress,highAddress,lowAddress,totalBytes);

Did you read the documentation? It tells you that calling this at
DISPATCH_LEVEL, which you are doing, incurs a performance penalty.

Did you read the documentation? The part where it says you should use
MmAllocatePagesForMdlEx because it has better performance?

Did you read the documentation? Did you read the part where the third
parameter must be an integer multiple of the page size? I suspect they
meant for integers >= 1. So why are you specifying a page size of 0?

Why do you think sharing a really tiny buffer like this (it’s only a
megabyte!) is going to have any impact on performance?

if(!mdl)
return STATUS_INSUFFICIENT_RESOURCES;

__try{
userVAToReturn =
MmMapLockedPagesSpecifyCache(mdl, // MDL
UserMode, // Mode
MmCached, // Caching
NULL, // Address
FALSE, // Bugcheck?
HighPagePriority); // Priority
}

Did you read the documentation? The part where it explains that the user
address is in the context of the running process? Did you know when you
wrote this that it is being called at DISPATCH_LEVEL? Therefore, there
cannot be a known process into which to do this mapping, because
DISPATCH_LEVEL is always an unknown and unknowable context, so UserMode
makes no sense here!

__except(EXCEPTION_EXECUTE_HANDLER)
{
status = GetExceptionCode();
}

And we know for the line below, that on failure tis variable is NULL? We
know this HOW? Oh, that’s right, I look at where it is declared!

if(!userVAToReturn) {
MmFreePagesFromMdl(mdl);
IoFreeMdl(mdl);
return STATUS_INSUFFICIENT_RESOURCES;
}

*UserVa = userVAToReturn;
*PMemMdl = mdl;

These variables are declared and initialized WHERE? Perhaps they
parameters to a function for which this code is the body? How can I find
this out? Oh, yes, I look at the function declaration. And I look at the
call site, and the declarations of the variables whose addresses are
passed in! And, of course, you give the context of the call site, so we
know what IRQL we’re running at? (Never mind; I see by the crash dump we
are at DISPATCH_LEVEL. Did you know this when you wrote the code?)

Overall assessment: there is nothing wong with this code that a complete
redesign that doesn’t use this code can’t fix. Short of that, this code,
and the design as a whole, is unsalvageable.

return STATUS_SUCCESS;

debug message:

*******************************************************************************
*

*
* Bugcheck Analysis

*
*

*
*******************************************************************************

KERNEL_DATA_INPAGE_ERROR (7a)
The requested page of kernel data could not be read in. Typically
caused
by
a bad block in the paging file or disk controller error. Also see
KERNEL_STACK_INPAGE_ERROR.
If the error status is 0xC000000E, 0xC000009C, 0xC000009D or 0xC0000185,
it means the disk subsystem has experienced a failure.
If the error status is 0xC000009A, then it means the request failed
because
a filesystem failed to make forward progress.
Arguments:
Arg1: 00000001, lock type that was held (value 1,2,3, or PTE address)
Arg2: d0000006, error status (normally i/o status code)
Arg3: 843ee580, current process (virtual address for lock type 3, or
PTE)
Arg4: c0011000, virtual address that could not be in-paged (or PTE
contents if arg1 is a PTE address)

Debugging Details:

TRIAGER: Could not open triage file : c:\program files (x86)\windows
kits\8.0\debuggers\x64\triage\modclass.ini, error 2

ERROR_CODE: (NTSTATUS) 0xd0000006 - 0x%p

BUGCHECK_STR: 0x7a_d0000006

DEFAULT_BUCKET_ID: WIN8_DRIVER_FAULT

PROCESS_NAME: RAPT.exe

CURRENT_IRQL: 2

DEVICE_OBJECT: 86043d80

DRIVER_OBJECT: 84f2f370

IMAGE_NAME: OsrSVMStor.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 50053064

FAULTING_MODULE: 82342000 fltmgr

LAST_CONTROL_TRANSFER: from 81ad1b63 to 81aa99d0

STACK_TEXT:
9ec0af3c 81ad1b63 00000003 b5296bc8 0000007a
nt!RtlpBreakWithStatusInstruction
9ec0af8c 81ad11a4 00000003 81c26138 9ec0b394
nt!KiBugCheckDebugBreak+0x1c
9ec0b368 81aa863a 0000007a 00000001 d0000006 nt!KeBugCheck2+0x594
9ec0b38c 81aa8571 0000007a 00000001 d0000006 nt!KiBugCheck2+0xc6
9ec0b3ac 81b501ea 0000007a 00000001 d0000006 nt!KeBugCheckEx+0x19
9ec0b3e4 81a8758d c0011000 00000000 00000000 nt! ??
::FNODOBFM::string'+0x25cc3 9ec0b43c 81dbd814 02200000 84400bfc 00000000 nt!MiMapLockedPagesInUserSpaceHelper+0xc6 9ec0b48c 81b50250 84400be0 000022ff 00000001 nt!MiMapLockedPagesInUserSpace+0x28f 9ec0b4f8 9ff78ebc 84400be0 00000001 00000001 nt! ?? ::FNODOBFM::string’+0x25d1e
9ec0b564 9ff73fe5 840a1ff8 840a1ff4 516373d5
OsrSVMStor!CreateAndMapMemory+0xdc
9ec0b750 9ff72b1f 840a1c28 84f34830 874c1f58
OsrSVMStor!OsrUserHandleSrb+0x295
9ec0b77c 9ff72031 874c1f58 84f34830 9ec0b79e
OsrSVMStor!OsrVmExecuteScsi+0x1af
9ec0b7a0 822da18d 874c1f58 84f34830 843ea920
OsrSVMStor!OsrHwStartIo+0x61
9ec0b7e0 822d9bed 842a10e0 00000000 9ec0b834
storport!RaidAdapterPostScatterGatherExecute+0x1f4
9ec0b7f0 822f2c53 842a10e0 8464f450 843ea920
storport!RaidAdapterExecuteXrb+0x4d
9ec0b834 822e3615 845cb030 843ea920 9ec0b854
storport!RaUnitStartIo+0x162
9ec0b874 822f3a1f 003ea990 843ea920 00000001
storport!RaidStartIoPacket+0x143
9ec0b89c 822f5c88 845cb0e8 00000000 843ea920
storport!RaidUnitSubmitRequest+0xca
9ec0b8e4 822e1a54 845cb0e8 843ea920 874b66c8
storport!RaUnitScsiIrp+0x206
9ec0b900 81baa07d 845cb030 843ea920 84f34830
storport!RaDriverScsiIrp+0x5d
9ec0b918 82303f68 9dfd6808 00100000 00000000 nt!IofCallDriver+0x3d
9ec0b96c 823041bd 845cb030 9dfd6808 00000001
storport!PortPassThroughSendAsync+0x117
9ec0b9a0 822fe8b8 845cb030 9dfd6808 00000001
storport!PortPassThroughExSendAsync+0x36
9ec0b9cc 822dcb62 842a10e0 845cb0e8 00000001
storport!RaidAdapterPassThrough+0x84
9ec0ba08 822e1b08 842a10e0 9dfd6808 845cb0e8
storport!RaidAdapterDeviceControlIrp+0x1d1
9ec0ba28 81baa07d 842a1028 9dfd6808 842a10e0
storport!RaDriverDeviceControlIrp+0x6a
9ec0ba40 823023fb 9dfd6808 845cb0e8 0004d014 nt!IofCallDriver+0x3d
9ec0ba68 822f54f6 845cb0e8 9dfd6808 9dfd6808
storport!RaUnitScsiPassThroughIoctl+0xe9
9ec0bab0 822e1aff 845cb0e8 9dfd6808 9dfd6974
storport!RaUnitDeviceControlIrp+0x23d
9ec0bad0 81baa07d 845cb030 9dfd6808 0004d014
storport!RaDriverDeviceControlIrp+0x61
9ec0bae8 82d22daa 9dfd6808 00000005 000012c0 nt!IofCallDriver+0x3d
9ec0bc10 82d076a9 84531718 9dfd6808 84343d38
CLASSPNP!ClassDeviceControl+0x13a
9ec0bc54 82d29d0f 84531718 9dfd6808 00000001
disk!DiskDeviceControl+0x105
9ec0bc70 82d2ffc9 84531718 9dfd6808 845317d0
CLASSPNP!ClassDeviceControlDispatch+0x8f
9ec0bc88 81baa07d 84531718 9dfd6808 9dfd6808
CLASSPNP!ClassGlobalDispatch+0x39
9ec0bca0 8837b066 84343d70 9dfd6808 00000050 nt!IofCallDriver+0x3d
9ec0bce4 88373cab 84343c80 9dfd6808 9dfd6974
partmgr!PmIoctlRedirect+0x61
9ec0bd04 883731d8 84343c80 84343d70 8460d778
partmgr!PmFilterDeviceControl+0xfd
9ec0bd38 81baa07d 84343c80 9dfd6808 9dfd6808
partmgr!PmGlobalDispatch+0x1d3
9ec0bd50 88373a0d 8460d6c0 9dfd6808 9dfd6974 nt!IofCallDriver+0x3d
9ec0bd74 883731d8 8460d6c0 9dfd6808 9dfd6990
partmgr!PmLegacyDeviceControl+0xe7
9ec0bda8 81baa07d 8460d6c0 9dfd6808 84608d28
partmgr!PmGlobalDispatch+0x1d3
9ec0bdc0 883bf5ae 9dfd6808 84608c70 845b300e nt!IofCallDriver+0x3d
9ec0bdf4 81baa07d 84608c70 9dfd6808 845b30d8
volmgr!VmDeviceControl+0x280
9ec0be0c 82c210a7 845b3020 9ec0be60 82c211e2 nt!IofCallDriver+0x3d
9ec0be18 82c211e2 845b3020 9dfd6808 8430d230 fvevol!FveFilterSkip+0x31
9ec0be60 81baa07d 845b3020 9dfd6808 9dfd6808
fvevol!FveFilterDeviceControl+0x130
9ec0be78 82cbe3c5 00000000 8430d160 9ec0bec8 nt!IofCallDriver+0x3d
9ec0be88 82cbe501 8430d160 9dfd6808 009b2f5d
rdyboost!SmdDispatchPassthrough+0x69
9ec0bec8 81baa07d 8430d160 9dfd6808 9dfd6808
rdyboost!SmdDispatchDeviceControl+0x63
9ec0bee0 82c8243a 9ec0bfe0 845e8610 8434160e nt!IofCallDriver+0x3d
9ec0bf1c 81baa07d 845e8610 9dfd6808 84341600
volsnap!VolSnapDeviceControl+0x6e
9ec0bf34 82639844 97ff6a50 9ec0bf54 81aa8c62 nt!IofCallDriver+0x3d
9ec0bf40 81aa8c62 97ff6b18 ffffffff 81acf267
Ntfs!NtfsStorageDriverCallout+0x14
9ec0bf40 81a3ec8b 97ff6b18 ffffffff 81acf267
nt!KiSwitchKernelStackAndCallout+0x9e
97ff6ae0 81a3eb09 82639830 97ff6b18 00003000
nt!KeExpandKernelStackAndCalloutInternal+0x16b
97ff6afc 8263361e 82639830 97ff6b18 00003000
nt!KeExpandKernelStackAndCalloutEx+0x1e
97ff6b28 826b429a 9dfd6808 00000000 28eed83d
Ntfs!NtfsCallStorageDriver+0x2a
97ff6b98 81baa07d 845eb018 9dfd6808 0000010e
Ntfs!NtfsFsdDeviceControl+0xcb
97ff6bb0 823430f2 87414420 86043d80 0000010e nt!IofCallDriver+0x3d
97ff6be4 81baa07d 86043d80 9dfd6808 00000100 fltmgr!FltpDispatch+0xed
97ff6bfc 81c68baf 9dfd69e0 9dfd6808 00000050 nt!IofCallDriver+0x3d
97ff6c50 81c68622 86043d80 00000000 81c87601
nt!IopSynchronousServiceTail+0x10a
97ff6cf0 81c6824f 00000001 9dfd6808 00000000 nt!IopXxxControlFile+0x3b7
97ff6d24 81b220bc 000000cc 00000000 00000000
nt!NtDeviceIoControlFile+0x2a
97ff6d24 77b85ee4 000000cc 00000000 00000000 nt!KiFastCallEntry+0x12c
021ff900 77b84f96 77b1d408 000000cc 00000000 ntdll!KiFastSystemCallRet
021ff904 77b1d408 000000cc 00000000 00000000
ntdll!NtDeviceIoControlFile+0xa
021ff95c 7539d798 000000cc 00000000 00000000
verifier!AVrfpNtDeviceIoControlFile+0x10d
021ff9bc 756228c8 000000cc 0004d014 021ffa18
KERNELBASE!DeviceIoControl+0x77
021ff9e8 00401bd6 000000cc 0004d014 021ffa18
KERNEL32!DeviceIoControlImplementation+0x3d0

Thanks for any reply.


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

Any suggestions if I want to send a buffer(20MegaBytes, alloc in user
application) from the user application to the storport miniport drier using
IOCTL_SCSI_MINIPORT?

On Thu, Jul 19, 2012 at 5:02 AM, Maxim S. Shatskih
wrote:

> > Yes, I want to create the shared memory for data transfer between user
> and driver.
>
> The best solution for a StorPort miniport is to create a fake
> “Processor”-class LUN on it, and send some special requests to it from your
> “master” app which requires memory sharing.
>
> You can use custom CDBs for these requests.
>
> One of the requests - which you should design yourself - is like “please
> remember this shared memory”. At this request, the driver has the physical
> addresses of the memory. The request can be pended nearly forever.
>
> Another request should be “please update the head/tail pointers in this
> shared memory”.
>
> But a much simpler way is just send “get next request” and “complete next
> request” special CDBs to the “Processor” LUN. The overall design is called
> “inverted call” and is very similar to, say, “tun” network adapter in
> UNIXen.
>
> –
> Maxim S. Shatskih
> Windows DDK MVP
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
> —
> 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
>



Best regards,
David Zeng

Thanks for all reply.

Ok, from now on, I will avoid using shared memory as much as possible.
And I have another way to solve this problem, but still meet some problem.
My idea is to use SCSI PASS THROUGH DIRECT to pass device io control to SCSI_MINIPORT DRIVER and let it pending until I have done other read/write requests, my problem is that I can’t get other read/write requests until my control request has been done.
I think this problem is caused by that queue action of my io control is not appropriate, so that there’s no other requests come in my driver before quitting my io control.

How can I set the queue action to my SCSI PASS THROUGH DIRECT control?

Thanks again.

Apparently, this is a commonly-used design pattern in Linux. So, people with some Linux architectuer knowledge and without a lot of Windows architectural knowledge naturally tend to think of this as a good architecture.

Peter
OSR

> [quote]

Why does every new poster think that shared memory is faster than anything
else?
[/quote]

Apparently, this is a commonly-used design pattern in Linux. So, people
with some Linux architectuer knowledge and without a lot of Windows
architectural knowledge naturally tend to think of this as a good
architecture.

Peter
OSR

It is also a common pattern in certain RTOS systems. Most of these do not
use any form of memory mapping, so there is always exactly one address,
which is the physical address of the buffer. So what I see is that they
try to either force the single-address model or build some convoluted
scheme to handle mapped memory. These same RTOS systems often use “event
objects” for the kernel to signal a process (each process is
single-threaded) that something interesting has happened. So they keep
trying to force Windows to work like the obsolete model they learning in.

The “event objects” often have the effect that they are extremely
efficient. So an “event” is always efficient, in their reasoning. Most
of these RTOS systems do not have preemptive priority schedulers, so there
is no question that once you “signal” the event, the process will be
running in single-digit microseconds in the worst case. So all “events”
in all operating systems must be the most efficient way to do
kernel-to-process notifications.

I once ran a graduate seminar in real-time systems, and the students had
to choose a particular system and show how it met or failed to meet a set
of criteria that had been established in the Operating Systems course. So
they had do compare locking strategies, what “scheduler” meant, how
priority inversion was avoided (or not), and so on. Most systems were
quite similar (and were head-to-head competitors), and all were
substantially different from the Windows model (or most other
general-purpose operating systems).
joe


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

> My idea is to use SCSI PASS THROUGH DIRECT to pass device io control to SCSI_MINIPORT

DRIVER and let it pending until I have done other read/write requests, my problem is that I can’t get
other read/write requests until my control request has been done.

You need a special separate control LUN for this.

Note that physical RAID controllers (from cheapest Promise to expensive LSI MegaRAID aka Dell PERC) use this approach to provide a target for RAID management requests.


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

> Apparently, this is a commonly-used design pattern in Linux.

Can you tell us the examples of the Linux drivers doing such things?

I think Linus personally warned once against using this way.

Linux and FreeBSD are great users of inverted calls - terminal stack, “tun” etc.

Probably you mean another thing - mapping device registers to user space. This is yes, more or less common in Linux.


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