ERROR_NO_SYSTEM_RESOURCES when call DeviceIoControl

Hi, All

When I use DeviceIoControl to send IOCTL_SCSI_MINIPORT IO control to the
adapter, I got a ERROR_NO_SYSTEM_RESOURCES error when the buffer size
larger than 256K bytes.

I checked the memory on the machine, the free system PTE is about 33000000,
and the Free Physical memory is about 1300MB. I think the memory is big
enough.

BTW, the storport miniport driver set MapBuffers to
STOR_MAP_NON_READ_WRITE_BUFFERS.

Best regards,
David Zeng

It suggests to me that there is a limitation in how large a buffer the
adapter might be willing to accept. You seem to think it has something to
do with the amount of physical memory on the machine, or some other
parameter such as the amount of physical memory. You would have to check
for other limitations. Just because some set of values suggest that there
is enough memory does not guarantee anything at all about how it might be
used, what requirements might be imposed by other components. Total free
memory does not equate to total maximum block size that might be
available. Do you know what “address space fragmentation” is? You would
probably need to provide a lot more information about what is actually
being sent down, and verify that all the values make sense.

Given that you have given very little information about what you are
doing, such as what is in the SRB and other places, it is hard to guess
what might be wrong.

joe

Hi, All

When I use DeviceIoControl to send IOCTL_SCSI_MINIPORT IO control to the
adapter, I got a ERROR_NO_SYSTEM_RESOURCES error when the buffer size
larger than 256K bytes.

I checked the memory on the machine, the free system PTE is about 33000000,
and the Free Physical memory is about 1300MB. I think the memory is big
enough.

BTW, the storport miniport driver set MapBuffers to
STOR_MAP_NON_READ_WRITE_BUFFERS.

Best regards,
David Zeng


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

IOCTL_SCSI_GET_CAPABILITIES ?

Thanks for your reminder!

Yes, I set following capabilities in the minipor driver:

MaximumTransferLength = 0x40000; //256KB
AlignmentMask = 0x3; // DWORD aligned

I don’t think the “MaximumTransferLength” make this error happen:

  1. this code works well at some time before, the code never change;
  2. This maximum transfer length tells the upper layer to spit the lager IO;

And following is a snippet of the code:

SRB_IO_CONTROL *pSic = &srbIoctlHdr;
dataLen = 0x80000;
pSic->HeaderLength = sizeof(SRB_IO_CONTROL);
pSic->Length = dataLen - sizeof(SRB_IO_CONTROL); //512KB
pSic->Timeout = 10000;
pSic->ControlCode = IOCTL_XXXXXXXX;

rc = DeviceIoControl(fdIoa,
IOCTL_SCSI_MINIPORT, // operation to
perform
pSic, dataLen, // input buffer
pSic, dataLen, // output buffer
(LPDWORD)&bytesReturned, // # bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
The return code is 1450(*ERROR_NO_SYSTEM_RESOURCES*).
And when this error occurred, the miniport driver didn’t get the IOCTL. So
maybe the Storport failed the request before sending it the miniport driver.

On Thu, Oct 17, 2013 at 12:58 PM, wrote:

> IOCTL_SCSI_GET_CAPABILITIES ?
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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 your reminder!

Yes, I set following capabilities in the minipor driver:

MaximumTransferLength = 0x40000; //256KB
AlignmentMask = 0x3; // DWORD aligned

I don’t think the “MaximumTransferLength” make this error happen:

  1. this code works well at some time before, the code never change;
  2. This maximum transfer length tells the upper layer to spit the lager
    IO;

And following is a snippet of the code:

SRB_IO_CONTROL *pSic = &srbIoctlHdr;

You have not indicated where srbIoctlHdr is allocated. It cannot be
static or global, so it must be on the stack, and if it is on the stack,
is it guaranteed to exist during the entire processing of the SRB? If
not, then by the time the SRB is examined, it can be complete garbage.

For that matter, why do you feel compelled to create a pointer variable,
if stack allocation is safe? You could easily have done this by simply
writing

srbIoctlHdr.HeaderLength = sizeof(SRB_IO_CONTROL);
srbIoctlHdr.Length = dataLen - sizeof(SRB_IO_CONTROL);

etc. and you don’t need to introduce a pointless pointer (pun intended)
whose sole purpose seems to be to allow you to write -> instead of ., at
least that’s the only reason I can see that it makes sense. Is, perhaps,
the “.” key on your keyboard broken?

dataLen = 0x80000;
pSic->HeaderLength = sizeof(SRB_IO_CONTROL);
pSic->Length = dataLen - sizeof(SRB_IO_CONTROL); //512KB
pSic->Timeout = 10000;
pSic->ControlCode = IOCTL_XXXXXXXX;

rc = DeviceIoControl(fdIoa,
IOCTL_SCSI_MINIPORT, // operation to
perform
pSic, dataLen, // input buffer
pSic, dataLen, // output buffer
(LPDWORD)&bytesReturned, // # bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
The return code is 1450(*ERROR_NO_SYSTEM_RESOURCES*).
And when this error occurred, the miniport driver didn’t get the IOCTL. So
maybe the Storport failed the request before sending it the miniport
driver.

On Thu, Oct 17, 2013 at 12:58 PM, wrote:
>
>> IOCTL_SCSI_GET_CAPABILITIES ?
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>>
>> OSR is HIRING!! See http://www.osr.com/careers
>>
>> 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
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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

>Yes, I set following capabilities in the minipor driver:

MaximumTransferLength = 0x40000; //256KB
AlignmentMask = 0x3; // DWORD aligned

I don’t think the “MaximumTransferLength” make this error happen:

  1. this code works well at some time before, the code never change;
  2. This maximum transfer length tells the upper layer to spit the lager IO;

No, this is exactly why it happens. And “it worked before” never means the code was correct before. That’s basics of software engineering.

  1. There is no upper layer to IOCTL_SCSI_MINIPORT. Only ReadFile and WriteFile (when handled by a class driver classpnp.sys+disk.sys) are split. IOCTL requests go directly. There is no generic way to split a buffer for a generic CDB.

I am not sure whether Storport check the buffer size for IOCTL_SCSI_MINIPORT
using MaximumTransferLength.
Anyone can confirm this?

If so, that means the user level application can’t pass a buffer larger
than MaximumTransferLength using IOCTL?

On Thu, Oct 17, 2013 at 10:57 PM, wrote:

>
> >Yes, I set following capabilities in the minipor driver:
>
> >MaximumTransferLength = 0x40000; //256KB
> >AlignmentMask = 0x3; // DWORD aligned
>
> >I don’t think the “MaximumTransferLength” make this error happen:
> >1) this code works well at some time before, the code never change;
> >2) This maximum transfer length tells the upper layer to spit the lager
> IO;
>
> No, this is exactly why it happens. And “it worked before” never means the
> code was correct before. That’s basics of software engineering.
>
> 2) There is no upper layer to IOCTL_SCSI_MINIPORT. Only ReadFile and
> WriteFile (when handled by a class driver classpnp.sys+disk.sys) are split.
> IOCTL requests go directly. There is no generic way to split a buffer for a
> generic CDB.
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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

If the miniport reports that it only supports transfers up to 256K, storport and the miniport has all the rights to reject bigger transfers. If in some cases the IO will succeed doesn’t mean it will always succeed. A responsible programmer will not try to challenge that limit.

Actually, the 256K transfer limitation is for the block read/write command
to the disk connected to this controller. The controller itself can accept
a larger transfer size.
So, is there any other place I can specify the max transfer size for the
disk, other than set the MaximumTransferLength?

On Fri, Oct 18, 2013 at 11:57 AM, wrote:

> If the miniport reports that it only supports transfers up to 256K,
> storport and the miniport has all the rights to reject bigger transfers. If
> in some cases the IO will succeed doesn’t mean it will always succeed. A
> responsible programmer will not try to challenge that limit.
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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

Do you mean a disk cannot accept bigger commands?

STORPORT doesn’t make distinction between different commands. It doesn’t try to interpret CDBs and command codes. If it limits transfer size, it does that for all commands.

I have used buffer sizes as large as 32MB through IOCTL_SCSI_MINIPORT with no problems. Note MaximumTransferLength alone is a meaningless value. You must also factor in the setting of NumberOfPhysicalBreaks.

>I have used buffer sizes as large as 32MB through IOCTL_SCSI_MINIPORT with no
problems. Note MaximumTransferLength alone is a meaningless value.

This doesn’t mean anything. Your particular scenario was not exercising all possible configurations. Some HBA may require bounce buffers sometimes, some HBA cares about number of pages, some HBA miniport will simply check the transfer size against the advertised limit.

You should not try to run around what the HBA tells you. Because there is a reason.

> Your particular scenario was not exercising all possible configurations.

And how would you know that? In my case 32MB is perfectly legal and works perfectly because it is within the described limits of the host adapters I targeted. I can think of no “possible configurations” that would be a problem.

You should not try to run around what the HBA tells you.

Exactly. Which is why I recommend checking max breaks. It would explain why it works some of the time. The times it works could be when enough pages are contiguous and the times it fails could be when there is too much fragmentation.

>Which is why I recommend checking max breaks.

An user mode application has no means of checking how many physical breaks is in a buffer.

I would presume that is the role of higher-level drivers than the one
requiring the limited physical breaks.
joe

>Which is why I recommend checking max breaks.

An user mode application has no means of checking how many physical breaks
is in a buffer.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

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

> An user mode application has no means of checking how many physical breaks

is in a buffer.

Nor should it. Please see spti in the WDK on how to compute what it calls TrueMaximumTransfer. Any buffer that does not exceed this length is guaranteed to work. Buffers larger than this length may not work (hence my assertion MaximumTransferLength alone is a meaningless value). It’s a pretty straightforward algorithm and source code is provided.

>BTW, the storport miniport driver set MapBuffers to STOR_MAP_NON_READ_WRITE_BUFFERS.

Storport ignores this, anyway.

> An user mode application has no means of checking how many physical breaks
> is in a buffer.

Nor should it. Please see spti in the WDK on how to compute what it calls
TrueMaximumTransfer.

Note this in spti.c:

// take the minimum of the two

> Note this in spti.c: // take the minimum of the two

It is an essential part of the algorithm, do not omit it. If you need more information, see the msdn topic “Storage Class Driver’s SplitTransferRequest Routine”.

Yes, the Class Driver will use MaximumTransferLength and
MaximumPhysicalPages to determine how to spit the large IOs.
That will affect the IOCTL_SCSI_PASS_THROUGH.
But now i want to know whether these two parameters affect the
IOCTL_SCSI_MINIPORT.
It seems that I must set the MaximumTransferLength to 256K for my hardware.
And How I can pass buffers larger than 2M to the miniport driver using
IOCTL_SCSI_MINIPORT?

On Tue, Oct 22, 2013 at 8:29 AM, wrote:

> > Note this in spti.c: // take the minimum of the two
>
> It is an essential part of the algorithm, do not omit it. If you need more
> information, see the msdn topic “Storage Class Driver’s
> SplitTransferRequest Routine”.
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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

> Yes, the Class Driver will use MaximumTransferLength and

MaximumPhysicalPages to determine how to spit the large IOs.
That will affect the IOCTL_SCSI_PASS_THROUGH.
But now i want to know whether these two parameters affect the
IOCTL_SCSI_MINIPORT.
It seems that I must set the MaximumTransferLength to 256K for my
hardware.
And How I can pass buffers larger than 2M to the miniport driver using
IOCTL_SCSI_MINIPORT?

In pieces?

The question now becomes how to determine how big the pieces are.
joe

On Tue, Oct 22, 2013 at 8:29 AM, wrote:
>
>> > Note this in spti.c: // take the minimum of the two
>>
>> It is an essential part of the algorithm, do not omit it. If you need
>> more
>> information, see the msdn topic “Storage Class Driver’s
>> SplitTransferRequest Routine”.
>>
>>
>> —
>> NTDEV is sponsored by OSR
>>
>> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>>
>> OSR is HIRING!! See http://www.osr.com/careers
>>
>> 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
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev
>
> OSR is HIRING!! See http://www.osr.com/careers
>
> 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