Can I have a KDPC object on the stack? When can I destroy or alter a KDPC?

AMD’s CodeXL driver implements DPCs by declaring a local KDPC variable, initializing it, queueing it, creating an event, and waiting for the deferred routine to post to the event. The data passed to the deferred routine is also in a local variable.

I assume this is safe, because AMD’s product is out there. But it doesn’t follow the documented requirement that it be in a device/controller extension or somewhere allocated from a nonpaged pool.

Is the kernel stack in nonpaged memory, too?

I made the mistake recently of creating my KDPC on the stack, but not waiting for the deferred routine to finish, so that the KDPC would have quickly been overwritten. This resulted in a bugcheck. So I’m putting my KDPC in the device extension.

But that raises the question of reusing the KDPC, and synchronizing usage between threads. Assuming that I’ve handled the issue of access by different threads, I need to know how long a thread that is using the KDPC needs hold onto it, after queueing it.

Even when the device is only being used by one user File, there may be multiple IRPs coming from different user threads at the same time.

On Feb 11, 2018, at 10:00 PM, xxxxx@rolle.name wrote:
>
> AMD’s CodeXL driver implements DPCs by declaring a local KDPC variable, initializing it, queueing it, creating an event, and waiting for the deferred routine to post to the event. The data passed to the deferred routine is also in a local variable.
>
> I assume this is safe, because AMD’s product is out there. But it doesn’t follow the documented requirement that it be in a device/controller extension or somewhere allocated from a nonpaged pool.
>
> Is the kernel stack in nonpaged memory, too?

As long as the thread is running, or in a “kernel mode” wait, the stack is locked into memory. The kernel stack can only be paged out if you do a wait that specifies “user mode”.

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

If the KDPC is on the stack it gets destroyed when the function exits. Trying to access it after wards is a recipe for disaster.

Just wait for the DPC routine to finish.

Just don’t put the DPC object on the stack! Kinda of a dumb practice.

Peter
OSR
@OSRDrivers

Why tell me Peter? I am quite aware of that. Why not tell the OP?

>Why tell me Peter?

I wasn’t speaking directly to you, Mr. Sykes. I was simply adding a “better alternative” to waiting for the DPC routine to finish.

Turns out, ANYbody can read the threads on this forum.

Peter
OSR
@OSRDrivers

Perhaps best not to quote the person you are not replying to. :slight_smile:

>Perhaps best not to quote the person you are not replying to. :slight_smile:

Perhaps best:

  1. Not to be so quick to take offense

  2. Expand your horizons in terms of forum protocol. I was quoting what you said, not specifically replying to you, Mr. Sykes. If I had SPECIFICALLY intended to address you, I would have used your name, or prefixed my reply with an @

I quoted you because I did not think this PARTICULAR piece of advice that you gave was the BEST advice the OP, or somebody else reading the list later on, could receive on this topic. It was “fine” and correct as far as it went… but it was not the fix of the root cause of the OP’s issue… which was for him to not do what he was doing, because what he was doing was not best practice.

On this list, a quote is not a “reply to” a specific person unless that person is named. It is a reply to the THREAD in question.

  1. Not to tell the list owner how to run the list – IIRC, you and I have butted heads before, Mr. Sykes. Please keep in mind that when you post to this list, you are a guest in my house. This is true for anybody who posts here, of course. I trust I do not need to explain this precept further, eh?

Peter
OSR
@OSRDrivers

Perhaps in his situation this is the best way to allocate a KDPC, we don’t know, but there could be a good reason for it, hence my answering his basic question.

Of course we can then go on to ask him what he is trying to do, and suggest a better design, but we hadn’t got to that stage yet.

And I dont think we have butted heads Peter. Dont forget, it is easy to misinterpret a persons sentiment in written text, I was not taking offence, so don’t worry about it. :slight_smile:

From the OP himself…

I have my DPC stored within my device extension, so I don’t have any issue with it getting blown off the stack.

However, I do still have the question, which hasn’t been answered: How soon after KeInsertQueueDpc can I reuse the DPC?

My guess is that the DPC is “owned” by the system, and should remain unchanged, only as long as it is still on the queue; and when the DPC routine starts to run, that means the DPC has been removed from the queue. Indeed, the DPC routine itself should be able queue the DPC again.

On Mar 3, 2018, at 3:39 PM, xxxxx@rolle.name wrote:
>
> However, I do still have the question, which hasn’t been answered: How soon after KeInsertQueueDpc can I reuse the DPC?
>
> My guess is that the DPC is “owned” by the system, and should remain unchanged, only as long as it is still on the queue; and when the DPC routine starts to run, that means the DPC has been removed from the queue. Indeed, the DPC routine itself should be able queue the DPC again.

What do you mean by “reuse”? Once you have initialized a DPC, you can call KeInsertQueueDpc as often as you want. There are only two possible conditions:

1. The DPC is not queued. In that case, the DPC will be queued and KeInsertQueueDPC returns true.
2. The DPC is queued, but is not running. In that case, KeInsertQueueDPC does nothing and returns false.

If the DPC function is running, then the DPC has been dequeued, and condition 1 applies.

If you mean “when can I call KeInitializeDpc again”, the answer is “any time the DPC is not queued”. There is no documented way to find out whether it is currently queued or not, mostly because that state can change at any time. You would need to track that.

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