WdfSynchronizationScopeQueue vs. WdfIoQueueDispatchSequential

I am curious about the difference between setting WdfIoQueueDispatchSequential attribute when creating the queue and setting the WdfSynchronizationScopeQueue attribute when creating the device.

Does WdfSynchronizationScopeQueue set the default when a queue is created (for all queues)?

Does WdfIoQueueDispatchSequential do anything if WdfSynchronizationScopeQueue is set for the device?

– jamey

Super common question.

Sequential dispatching provides a single Request from your queue at a time. You don’t get another Request until you complete (or send away with Send-And-Forget, or forward to another Queue) the current Request. So, Sequential dispatching is about the total number of outstanding Requests that can be active at a time.

Sync Scope, be it Sync Scope Queue or Sync Scope Device is about concurrency and locking. Sync Scope Queue simply associates a lock (a spin lock by default) with the Queue. WDF automagically acquires this lock when a Request is presented to your driver, and automagically releases the lock when your driver returns.

So… Sync Scope prevents your EvtIoXxxx callbacks from being active in parallel. It was initially intended to keep devs from worrying about concurrency. It’s basically a big lock model, at the QUeue or at the Device level. So… it’s basically nothing anyone ever wants to use, unless you’re doing some really quick and dirty prorotype.

Does that help? You should come take a class, Jamey :wink:

Peter
OSR
@OSRDrivers

Yes. I kept digging and found this too:

WdfSynchronizationScopeQueue

“… The framework obtains the queue object’s synchronization lock before calling any callback functions that belong to the object. If the driver creates multiple queue objects, their event callback functions might run concurrently on a multiprocessor system. For framework versions 1.9 and later, a driver should set WdfSynchronizationScopeQueue for individual queue objects. To use this scope with earlier versions of the framework, the driver must set WdfSynchronizationScopeQueue for the parent device object and WdfSynchronizationScopeInheritFromParent for the queue object.”

Thanks.

Wow, I just did the math… The last time took the OSR driver class was 23 years ago in Palo Alto. How time flies :slight_smile:

Hi

Inherited a driver. Working on performance, so poured over docs to to understand AutoSerial/SyncScpe (to avoid the big lock). I have following objects

DPC
TIMER
WORK_ITEM < ExecLevelPassive, AutomaticSerial=TRUE, |parent=WDF_QUEUE> separate Q created for every DPC WORK_ITEM just for sync scope purposes.

Parents used above have below set (or defaulted).
WDF_DEVICE< WdfExecutionLevelDispatch and WdfSynchronizationScopeNone>
WDF_QUEUE< WdfExecutionLevelPassive and WdfSynchronizationScopeQueue>

Below were my conclusions

DPC:
Due to IRQL level mismatch is not serialized against TIMER/WORK_ITEM.

TIMER (passive)
? Not serialized vs. WORK_ITEM (since sync_Scope and parents diff)
We create 2 timers.
? Multiple timers NOT serialized against each other as well, because its eventual Synchscope=None

WORK_ITEM
? Not serialized against TIMER (since sync_Scope and parents diff)
? Even if queue_Scope, since each WORK_ITEM is assigned a distinct queue as parent object, multiple WORK_ITEMS not serialized as well against each other as well.
(These manual non_pwr managed queues are just created to limit scope acc. to comments.
They do not have any callbacks defined on them, they do not sink.source any data.)

[Q] Is my understanding above correct? AS first step, I tried to just disable AutoSerial everywhere, things went wary.

Thx.