I have to disagree with the assertion:
“I am concerned this practice is a relic of a bygone time when memory was
very expensive and computers did not have much of it at all”
This is the sort of thinking that has gotten us to where we are today; and
industry saturated with overly complex bloat-ware.
We have a driver that is somewhat complex and has a code size of about 50K.
The driver is used very little during day-to-day operations, but is required
occasionally to perform some task that may be in operation from several
minutes to several hours. In this driver, we mark all of the subroutines
used by the top level functions as pagable. When the IOCTLS are sent to the
driver asking the filters to engage, we lock these functions in memory. When
we are done, we unlock them so that they can be paged.
I am not sure what the performance penalty is on the rare IOCTLs that lock
and unlock the paged code, but it only took us a day or two to go through
the driver and set it all up to be pagable as I have described.
Please, let’s not get lazy about memory and resource constraints. We should
all strive to write the best possible code we can in the most resource
conservative way possible. It is a professional responsibility.
Jamey
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Mark Roddy
Sent: Thursday, October 07, 2004 4:25 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Pageable Code Assert (Probably a basic question)
Unless you have some overwhelming reason to mark you code pageable I would
suggest never doing this. As far as I am concerned this practice is a relic
of a bygone time when memory was very expensive and computers did not have
much of it at all.
Pageable data is a different story.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Mats PETERSSON
Sent: Thursday, October 07, 2004 7:07 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] Pageable Code Assert (Probably a basic question)
xxxxx@lists.osr.com wrote on 10/07/2004 11:47:25 AM:
> Hi Mats,
> Thanks for this very informative reply, I understand what
the purpose
> of the macro is now but I still don’t know why the ASSERT
fires after
> a few seconds. What is wrong with the way the routine is
being called
> when this happens?
> The macro (in wdm.h) is:
> if(KeGetCurrentIrql() > APC_LEVEL)
> {
> KdPrint(( “EX : Pageable code called at IRQL %d\n”.
> KeGetCurrentIrql() ));
> ASSERT(FALSE);
> }
> APC_LEVEL is 1, DISPATCH_LEVEL is 2 so this will fire whenever the
> routine is called *AT* Dispatch level. Is it being called
at the wrong
> level for some reason?
Simple answer: Yes, it’s called at DISPATCH or higher level,
which is not allowed for pageable code.
As to “What is wrogn with the wway the routine is being
called”, you’ve got to have a look at the stack for the call
when it asserts. In most cases it would become obvious from
your own code why it’s happening, but it could of course be
more complicated (for instance, it’s not called by your own
driver, because it’s called through some function pointer or
similar mechanism).
You need to EITHER make sure that the code isn’t called from
DISPATCH level, or that the code is not pageable (i.e. it’s
not in code_seg(PAGE)).
The right choice of those depends on what your code is
actually doing, and I’m not sure from the context you’re
giving what IRQL it’s expected to be called at. One
possibility is that you have a leacky lock situation…
Simplified code:
somefunction(…)
{
KeAcquireSpinLock(…);
if (something)
return;
KeReleaseSpinLock(…);
}
someotherfunction(…)
{
…
somefunction(…);
DispatchControl(…);
}
The above code should release the spinlock when leaving the
function. This type of function is usually best designed so
that you set a variable with the return value, rather than
just returning. I’ve seen several cases (in my own and others
code) where there is a return in the middle that causes some
lock or other operation to be left “dangling” when some
special case happens.
Or you’re DispatchControl is called by an interrupt? That
would cause IRQL to be > 1 for sure…
> I am running DV.
Ok, so maybe it’s not paging out code in the driver. I
thought it did. Or maybe you haven’t got all the settings
turned on… You should enable all options EXCEPT the Low
resource simulation (unless you think your driver is almost
ready to ship, in which case a LRS is a good final test for
reliability).
I hope this helps. If not, I’m not sure I can offer much more
help, as I’ve only run into this problem once, and that was
caused by an interrupt calling a paged function (and it did a
BSOD, but the stack-trace was quite easy to follow and fix
was a one-line removal, so not too difficult to find or fix).
–
Mats
> Thanks
> Alasdair (still confused)
>
> > Hi Alasdair.
> >
> > Paged code is fine, but in this case, the macro is checking that
> > you’re not calling the code in IRQL >= DISPATCH. The
reason for this
> > is that should the code happen to be paged out, there’s
no way the
> > OS can page it back in, as it’s running at an IRQL that
prevents it
> > from running the page-in code, and thus, you’d
blue-screen when this
> > happens.
> > Obviously, your test-machine probably has enough memory and is
> > excercising your driver enough to not cause it to be
paged out, but
> > that doesn’t mean that it’s not a problem in a different
situation
> > in a different system.
> >
> > I’m pretty sure that you’d get a bug-check if you used Driver
> > Verifier on your driver, as it has a mechanism that
“pages out” all
> > pages that are pageable, just to avoid you getting to debug the
> > problem when you’ve got a customer who has a tighter memory
> > requirement than your test-system…
[I put “pages out” in
\> \> quotes, because what DV really does is just to mark the page “not
\> \> present”, whilst the page is actually still in memory,
it’s just not
\> \> available to code until the swapper process is available, and
\> \> anything that accesses this page from high IRQL will
automatically
\> \> cause a BSOD!].
> >
> > –
> > Mats
> > xxxxx@lists.osr.com wrote on 10/07/2004 11:22:50 AM:
> >
> > > Hi (again),
> > > Thanks for all the help so far from this novice.
> > >
> > > I have encountered another problem which I am sure is
very basic.
> > > I have based my filter driver on the skeleton code produced by
> > > Walt Oney’s driver wizard. The DispatchControl routine
begins like this:
> > >
> > > #pragma PAGEDCODE
> > > NTSTATUS DispatchControl(…
> > > {
> > > PAGED_CODE();
> > > …
> > >
> > > When the driver is running and passing Irps down to the
> > lower driver,
> > > after a few seconds the ASSERT in this PAGED_CODE() macro
> > fires with
> > > the message:
> > > “EX: Pageable code called at IRQL 2”.
> > > I assume that this has happened because after a few
seconds this
> > > routine has been “paged” out of memory, but surely that is what
> > > the PAGEDCODE pragma is saying may happen. The PAGEDCODE pragma
> > looks like
> > > this:
> > > code_seg(“PAGE”)
> > > When I press “g” to continue the driver resumes until the
> > next ASSERT.
> > > There is no bugcheck. What do I do here? Comment out
the macro? I
> > > guess it is there for a
> > reason.
> > > Thanks
> > > Alasdair (confused)
> > >
> >
> > > NOTICE AND DISCLAIMER:
> > > This email (including attachments) is confidential. If
you have
> > > received this email in error please notify the sender
> > immediately and
> > > delete this email from your system without copying or
> > disseminating it
> > > or placing any reliance upon its contents. We cannot
> > accept liability
> > > for any breaches of confidence arising through use of
email. Any
> > > opinions expressed in this email (including attachments)
> > are those of
> > > the author and do not necessarily reflect our opinions. We
> > will not
> > > accept responsibility for any commitments made by our employees
> > > outside the scope of our business. We do not warrant the
> > accuracy or
> > > completeness of such
> > information.
> > > —
> > > Questions? First check the Kernel Driver FAQ at http://www.
> > > osronline.com/article.cfm?id=256
> > >
> > > You are currently subscribed to ntdev as: unknown lmsubst tag
> > > argument:
> > ‘’
> > > To unsubscribe send a blank email to
> > xxxxx@lists.osr.com
> > > ForwardSourceID:NT00004CF6
> >
> >
> >
> > —
> > Questions? First check the Kernel Driver FAQ at
> > http://www.osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as:
> > xxxxx@t-mobile.co.uk To unsubscribe send a
blank email to
> > xxxxx@lists.osr.com
> >
>
> NOTICE AND DISCLAIMER:
> This email (including attachments) is confidential. If you have
> received this email in error please notify the sender
immediately and
> delete this email from your system without copying or
disseminating it
> or placing any reliance upon its contents. We cannot
accept liability
> for any breaches of confidence arising through use of email. Any
> opinions expressed in this email (including attachments)
are those of
> the author and do not necessarily reflect our opinions. We
will not
> accept responsibility for any commitments made by our employees
> outside the scope of our business. We do not warrant the
accuracy or
> completeness of such
information.
> —
> Questions? First check the Kernel Driver FAQ at http://www.
> osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: unknown lmsubst
tag argument:
‘’
> To unsubscribe send a blank email to xxxxx@lists.osr.com
> ForwardSourceID:NT00004D02
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as:
xxxxx@hollistech.com To unsubscribe send a blank email to
xxxxx@lists.osr.com
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@storagecraft.com
To unsubscribe send a blank email to xxxxx@lists.osr.com
__________ NOD32 1.860 (20040903) Information __________
This message was checked by NOD32 antivirus system.
http://www.nod32.com