What kind of lock to protect a resource

Hi everyonne !

I am developping a virtual audio driver and I am wondering how I could
synchronize the access to a home made queue in which I push and pop
audio data.

Here is my workflow:
I push audio data into the queue when IDMAChannel::CopyTo is called and
I schedule a DPC to process the audio data
I pop audio data from the queue when the DPC is executed

I would like to synchronize access to the queue but still wonder which
kind of object (mutex, spin lock) I should use and how to initialize it
(should it be global or a private member of my home made queue).

Thanks in advance for your time, patience and advises.

Best regards.

Matt

Spinlock, in the queue context.

If you will only ever access your queue at IRQL DISPATCH_LEVEL, and you always want to have mutual exclusion (not reader/writer semantics)… use some sort of mutex.

If you will EVER access your data at > IRQL DISPATCH_LEVEL, using a spin lock.

The whole decision process about which primitive to use is described pretty nicely here:

https:</https:>

In terms of WHERE to locate the lock… you want to locate it where it is “visible” only to those routines that access it. In C, “visible” translates to “co-located with” as it’s rather difficult to actually hide variables like this.

Peter
OSR
@OSRDrivers

At what irql will you be acquiring the lock at all call sites? If any are dispatch level you must use a spin lock. Store the lock in the same allocation that holds the queue, don?t make it global

Sent from my Windows 10 phone

From: Matthieu Collettemailto:xxxxx
Sent: Wednesday, May 25, 2016 9:11 AM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: [ntdev] What kind of lock to protect a resource

Hi everyonne !

I am developping a virtual audio driver and I am wondering how I could
synchronize the access to a home made queue in which I push and pop
audio data.

Here is my workflow:
I push audio data into the queue when IDMAChannel::CopyTo is called and
I schedule a DPC to process the audio data
I pop audio data from the queue when the DPC is executed

I would like to synchronize access to the queue but still wonder which
kind of object (mutex, spin lock) I should use and how to initialize it
(should it be global or a private member of my home made queue).

Thanks in advance for your time, patience and advises.

Best regards.

Matt


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx></mailto:xxxxx>

Matthieu Collette wrote:

I am developping a virtual audio driver and I am wondering how I could
synchronize the access to a home made queue in which I push and pop
audio data.

Here is my workflow:
I push audio data into the queue when IDMAChannel::CopyTo is called and
I schedule a DPC to process the audio data
I pop audio data from the queue when the DPC is executed

I would like to synchronize access to the queue but still wonder which
kind of object (mutex, spin lock) I should use and how to initialize it
(should it be global or a private member of my home made queue).

If you have only one reader and only one writer, then you may not need
to synchronize it at all. Remember, synchronization is only necessary
if there is a chance of leaving things in an inconsistent state. If the
writer only updates the “in” pointer, and the reader only updates the
“out” pointer, then there is no chance of an inconsistency, and you
don’t need any locking.

There is lots of good research on “lock-free queues”.


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

You are losing time when trying to implement your own queue or collection management API. You are out of the driver developpement scope. Don’t try to reinvent the wheel, the framework provides both collections and locks.

https://msdn.microsoft.com/en-us/windows/hardware/drivers/wdf/framework-object-collections

If your ISR is involved in the lock acquisition then you should read this:

https://msdn.microsoft.com/en-us/windows/hardware/drivers/wdf/synchronizing-interrupt-code

On 2016-05-25 16:30:59 +0000, xxxxx@osr.com said:

If you will only ever access your queue at IRQL DISPATCH_LEVEL, and you
always want to have mutual exclusion (not reader/writer semantics)…
use some sort of mutex.

If you will EVER access your data at > IRQL DISPATCH_LEVEL, using a spin lock.

The whole decision process about which primitive to use is described
pretty nicely here:

https:</https:>

In terms of WHERE to locate the lock… you want to locate it where it
is “visible” only to those routines that access it. In C, “visible”
translates to “co-located with” as it’s rather difficult to actually
hide variables like this.

Peter
OSR
@OSRDrivers

Hi !

Thanks for the link, I will have a look at it.

IDMAChannel::CopyTo can be called at any IRQL
The DPC will be executed at DISPATCH_LEVEL

Hi!

On 2016-05-25 16:32:42 +0000, Doron Holan said:

At what irql will you be acquiring the lock at all call sites? If any
are dispatch level you must use a spin lock. Store the lock in the same
allocation that holds the queue, don’t make it global
I push data to the queue when I am called from IDMAChannel::CopyTo
which can be called at ANY IRQL.
I pop from a DPC, at DISPATCH_LEVEL.

 
Sent from my Windows 10 phone
 
From: Matthieu Collette
Sent: Wednesday, May 25, 2016 9:11 AM
To: Windows System Software Devs Interest List
Subject: [ntdev] What kind of lock to protect a resource
 
Hi everyonne !

I am developping a virtual audio driver and I am wondering how I could
synchronize the access to a home made queue in which I push and pop
audio data.

Here is my workflow:
I push audio data into the queue when IDMAChannel::CopyTo is called and
I schedule a DPC to process the audio data
I pop audio data from the queue when the DPC is executed

I would like to synchronize access to the queue but still wonder which
kind of object (mutex, spin lock) I should use and how to initialize it
(should it be global or a private member of my home made queue).

Thanks in advance for your time, patience and advises.

Best regards.

Matt


NTDEV is sponsored by OSR

Visit the list online at: http:
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:</http:></http:></http:>

On 2016-05-25 16:48:27 +0000, Tim Roberts said:

Matthieu Collette wrote:
> I am developping a virtual audio driver and I am wondering how I could
> synchronize the access to a home made queue in which I push and pop
> audio data.
>
> Here is my workflow:
> I push audio data into the queue when IDMAChannel::CopyTo is called and
> I schedule a DPC to process the audio data
> I pop audio data from the queue when the DPC is executed
>
> I would like to synchronize access to the queue but still wonder which
> kind of object (mutex, spin lock) I should use and how to initialize it
> (should it be global or a private member of my home made queue).

If you have only one reader and only one writer, then you may not need
to synchronize it at all. Remember, synchronization is only necessary
if there is a chance of leaving things in an inconsistent state. If the
writer only updates the “in” pointer, and the reader only updates the
“out” pointer, then there is no chance of an inconsistency, and you
don’t need any locking.

There is lots of good research on “lock-free queues”.

Hi Tim !

I have a writer (any thread) and a reader (the one that executes de
DPC) but as I don’t wan’t to overwrite data that that has not been read
yet, the “push” operation requires an access to the read position, so I
need a synchroization mechanism.

I also should have mentioned that IDMAChannel::CopyTo can be called at
any IRQL but the DPC is only called at DISPATCH_LEVEL.

You did get this IRQL (any IRQL) from the documentation, didn’t you ?

This just tells you that the DMA buffer can be accessesed at any IRQL because it is resident. Thas has nothing to do with synchronization.

But the question should be: what is the highest IRQL at which lock acquisition is performed within your code ?

This is important because, to avoid deadlocks, all lock acquisitions must be consequently performed at this highest IRQL.

So, if your ISR is acquiring the lock and if your ISR runs at device IRQL (DIRQL) than every single lock operation will be performed at DIRQL and you have no other choice than a spinlock. Any access being exclusive in that case. This is also the case if this highest IRQL is DISPATCH_LEVEL.

Matthieu Collette wrote:

Hi!

On 2016-05-25 16:32:42 +0000, Doron Holan said:

> At what irql will you be acquiring the lock at all call sites? If any
> are dispatch level you must use a spin lock. Store the lock in the same
> allocation that holds the queue, don’t make it global
I push data to the queue when I am called from IDMAChannel::CopyTo
which can be called at ANY IRQL.

In a hardware device, that’s true – you are usually called from an
ISR. In a virtual driver, it’s not. You will be called from the Audio
Engine service when new data arrives. Possibly PASSIVE_LEVEL, but more
likely DISPATCH_LEVEL. Certainly nothing more than that.


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

Matthieu Collette wrote:

I have a writer (any thread) and a reader (the one that executes de
DPC) but as I don’t wan’t to overwrite data that that has not been read
yet, the “push” operation requires an access to the read position, so I
need a synchroization mechanism.

Not necessarily… All you care about is the instantaneous value of the
read position. When the reader updates the read position, it is an
atomic operation. Thus, the writer is always going to get either the
“old” value or the “new” value. There is no in between, so there is no
opportunity for things to be in an inconsistent state.


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

On 2016-05-26 16:39:26 +0000, Tim Roberts said:

Matthieu Collette wrote:
> Hi!
>
> On 2016-05-25 16:32:42 +0000, Doron Holan said:
>
>> At what irql will you be acquiring the lock at all call sites? If any
>> are dispatch level you must use a spin lock. Store the lock in the same
>> allocation that holds the queue, don’t make it global
> I push data to the queue when I am called from IDMAChannel::CopyTo
> which can be called at ANY IRQL.

In a hardware device, that’s true – you are usually called from an
ISR. In a virtual driver, it’s not. You will be called from the Audio
Engine service when new data arrives. Possibly PASSIVE_LEVEL, but more
likely DISPATCH_LEVEL. Certainly nothing more than that.

Hi Tim !

I all tests I ran, I have never been called at a IRQL > DISPATCH_LEVEL
so you are certainly true.
I am just wondering why the documentation mention that
IDMAChannel::CopyTo may be called at any IRQL.

Thanks !

> I am just wondering why the documentation mention that IDMAChannel::CopyTo may

be called at any IRQL.

Simply because you may get called in context of either ISR or DPC routine. Although the former scenario may not, for the (hopefully) obvious reasons, occur if the target device is virtual, it may (and most likely will) occur if the target device is a physical one - in this case you will get called at DIRQL. Is it so hard to get???

Anton Bassov

Because the question is " What kind of lock to protect a resource ?", I would suggest you read this document:

https://msdn.microsoft.com/en-us/library/windows/hardware/dn613957(v=vs.85).aspx

On 2016-05-27 08:55:59 +0000, xxxxx@hotmail.com said:

>
> I am just wondering why the documentation mention that IDMAChannel::CopyTo may
> be called at any IRQL.

Simply because you may get called in context of either ISR or DPC
routine. Although the former scenario may not, for the (hopefully)
obvious reasons, occur if the target device is virtual, it may (and
most likely will) occur if the target device is a physical one - in
this case you will get called at DIRQL. Is it so hard to get???

Anton Bassov

Thank you very much for your answer.

I am new to to kernel driver and what I need is to understand things
one step at a time.

PS : asking me if it is hard to get such the way you did seems a bit rude …

Matthieu Collette wrote:

I am new to to kernel driver and what I need is to understand things
one step at a time.

PS : asking me if it is hard to get such the way you did seems a bit rude …

Please allow me to offer you some mailing list advice.

Every forum, newsgroup, and mailing has its own personality, evolved
over many years. When you start to participate in a new forum, you MUST
take some time to learn the personality of the group before making
editorial comments. God knows I have failed to follow this advice many
times, and I’ve paid the price. Some forums are welcoming and nurturing
to newcomers. Some forums are not. This particular one is not. Most
of us are grizzled long-timers, who have accrued our knowledge over the
decades, and are looking for a high-level technical exchange. Some of
the long-timers get annoyed by questions and tutorial sessions that seem
obvious to them, and they respond in kind.

That doesn’t mean we prohibit newbie questions. It does mean we can be
a bit harsh to newbies, especially if a key point is not absorbed. The
best option for you is to suck it up, ignore the cracks, and plow
forward. Most of us are not going to side with a newbie against a
valued contributor. Illegitimi non carborundum.


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

> I am new to to kernel driver and what I need is to understand things one step at a time.

We’ve been through this on another thread - the only thing that I can say here is “get yourself a bit of overall understanding of how the OSes work and what makes them tick, of what basic operations device drivers have to do under any OS, and then, when you get familiar with these concepts, take OSR class on Windows drivers”. I would say this is the best approach possible - as I can see from your original question, you are yet to understand the difference between spinlocks and dispatcher-level synch constructs…

PS : asking me if it is hard to get such the way you did seems a bit rude …

Well, I have never had a reputation of being particularly nice person, have I. I know in this particular case my (relatively)harsh reaction was uncalled for ( I have to apologise for that), but, in general, whenever I encounter someone obtuse I get really, really irritated with the imbeciles and their overall idiocy, and just cannot force myself to be nice…

Anton Bassov