DRIVER_IRQL_NOT_LESS_OR_EQUAL from within a work item?

I’m getting a DRIVER_IRQL_NOT_LESS_OR_EQUAL crash indicating I’m accessing pageable code at IRQL(2). However, the call stack is indicating that the work is being done within a workitem I have created. Any ideas why my work item would be running at IRQL(2) instead of PASSIVE?

I should note it’s an NDIS work item created as follows:

NDIS_HANDLE handle_my_wi;
   handle_my_wi= NdisAllocateIoWorkItem(device_context->adapter_handle);

NdisQueueIoWorkItem(handle_my_wi,
         my_work_item_func,
         device_context);

The stack indicates the issue is in a function called by my_work_item_func.

How do you determine the IRQL, and is any routine raising Irql in your
workitem, e.g. acquiring spin locks?

> @Dejan_Maksimovic said: > How do you determine the IRQL, and is any routine raising Irql in your > workitem, e.g. acquiring spin locks? The crash indicates I was at dispatch. And yes I do acquire a spin lock in the calling code. I completely missed that. I’ll have to evaluate if I can remove them safely. Thanks.

Again, how do you determine the IRQL and that this is not just bad memory
access?
The bugcheck has never happened to me when I access pageable memory (even
during testing), simply because it’s easy to avoid.
But it did happen when completely invalid memory is accessed.

I just mean not to presume IRQL is the issue when you see this bugcheck.
“Fixing” the irql only can hide a much worse error.

Regards, Dejan.

You don’t necessarily need to REMOVE the spinlocks, you just need to make sure you’re accessing the paged memory before you acquire one.

@Dejan_Maksimovic said:
Again, how do you determine the IRQL and that this is not just bad memory
access?

I don’t have the crash open at this minute, but the crash specifically indicates what the IRQL level is.

@Tim_Roberts said:
You don’t necessarily need to REMOVE the spinlocks, you just need to make sure you’re accessing the paged memory before you acquire one.

That’s a good point. I have some configuration of the PHYs that takes place over a shared/slower bus. Under certain configurations (too many devices sharing that bus) the time waiting for the bus to be available was exceeding the DPC watchdog timeout. I’m moving all PHY interaction into a passive work item. However, during that work item I’m acquiring a lock that I was previously using to make sure any one device doesn’t attempt multiple access to the shared bus. ex: a user request to change speed/duplex is preempted by an IRQ event that requires PHY changes. There’s many ways I could handle the synchronization. In this case if all interaction with the shared bus is done through a queued work item, I could presumably remove the locks if I can trust the work items are completed before the next work item executes.

I think that Tim’s idea was to see if you could copy the values you need to the stack before acquiring the lock