mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-20 11:13:58 +08:00
ALSA: pcm: Hide local_irq_disable/enable() and local_irqsave/restore()
The snd_pcm_stream_lock_irq*() functions decouple disabling interrupts from the actual locking process. This does not work as expected if the locking primitives are replaced like on preempt-rt. Provide one function for locking which uses correct locking primitives. Signed-off-by: Anna-Maria Gleixner <anna-maria@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
9ea19e7e76
commit
10aa7cad37
@ -99,6 +99,57 @@ static inline void down_write_nonblock(struct rw_semaphore *lock)
|
|||||||
cond_resched();
|
cond_resched();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PCM_LOCK_DEFAULT 0
|
||||||
|
#define PCM_LOCK_IRQ 1
|
||||||
|
#define PCM_LOCK_IRQSAVE 2
|
||||||
|
|
||||||
|
static unsigned long __snd_pcm_stream_lock_mode(struct snd_pcm_substream *substream,
|
||||||
|
unsigned int mode)
|
||||||
|
{
|
||||||
|
unsigned long flags = 0;
|
||||||
|
if (substream->pcm->nonatomic) {
|
||||||
|
down_read_nested(&snd_pcm_link_rwsem, SINGLE_DEPTH_NESTING);
|
||||||
|
mutex_lock(&substream->self_group.mutex);
|
||||||
|
} else {
|
||||||
|
switch (mode) {
|
||||||
|
case PCM_LOCK_DEFAULT:
|
||||||
|
read_lock(&snd_pcm_link_rwlock);
|
||||||
|
break;
|
||||||
|
case PCM_LOCK_IRQ:
|
||||||
|
read_lock_irq(&snd_pcm_link_rwlock);
|
||||||
|
break;
|
||||||
|
case PCM_LOCK_IRQSAVE:
|
||||||
|
read_lock_irqsave(&snd_pcm_link_rwlock, flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
spin_lock(&substream->self_group.lock);
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __snd_pcm_stream_unlock_mode(struct snd_pcm_substream *substream,
|
||||||
|
unsigned int mode, unsigned long flags)
|
||||||
|
{
|
||||||
|
if (substream->pcm->nonatomic) {
|
||||||
|
mutex_unlock(&substream->self_group.mutex);
|
||||||
|
up_read(&snd_pcm_link_rwsem);
|
||||||
|
} else {
|
||||||
|
spin_unlock(&substream->self_group.lock);
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case PCM_LOCK_DEFAULT:
|
||||||
|
read_unlock(&snd_pcm_link_rwlock);
|
||||||
|
break;
|
||||||
|
case PCM_LOCK_IRQ:
|
||||||
|
read_unlock_irq(&snd_pcm_link_rwlock);
|
||||||
|
break;
|
||||||
|
case PCM_LOCK_IRQSAVE:
|
||||||
|
read_unlock_irqrestore(&snd_pcm_link_rwlock, flags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_pcm_stream_lock - Lock the PCM stream
|
* snd_pcm_stream_lock - Lock the PCM stream
|
||||||
* @substream: PCM substream
|
* @substream: PCM substream
|
||||||
@ -109,13 +160,7 @@ static inline void down_write_nonblock(struct rw_semaphore *lock)
|
|||||||
*/
|
*/
|
||||||
void snd_pcm_stream_lock(struct snd_pcm_substream *substream)
|
void snd_pcm_stream_lock(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
if (substream->pcm->nonatomic) {
|
__snd_pcm_stream_lock_mode(substream, PCM_LOCK_DEFAULT);
|
||||||
down_read_nested(&snd_pcm_link_rwsem, SINGLE_DEPTH_NESTING);
|
|
||||||
mutex_lock(&substream->self_group.mutex);
|
|
||||||
} else {
|
|
||||||
read_lock(&snd_pcm_link_rwlock);
|
|
||||||
spin_lock(&substream->self_group.lock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_pcm_stream_lock);
|
EXPORT_SYMBOL_GPL(snd_pcm_stream_lock);
|
||||||
|
|
||||||
@ -127,13 +172,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_lock);
|
|||||||
*/
|
*/
|
||||||
void snd_pcm_stream_unlock(struct snd_pcm_substream *substream)
|
void snd_pcm_stream_unlock(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
if (substream->pcm->nonatomic) {
|
__snd_pcm_stream_unlock_mode(substream, PCM_LOCK_DEFAULT, 0);
|
||||||
mutex_unlock(&substream->self_group.mutex);
|
|
||||||
up_read(&snd_pcm_link_rwsem);
|
|
||||||
} else {
|
|
||||||
spin_unlock(&substream->self_group.lock);
|
|
||||||
read_unlock(&snd_pcm_link_rwlock);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock);
|
EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock);
|
||||||
|
|
||||||
@ -147,9 +186,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock);
|
|||||||
*/
|
*/
|
||||||
void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream)
|
void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
if (!substream->pcm->nonatomic)
|
__snd_pcm_stream_lock_mode(substream, PCM_LOCK_IRQ);
|
||||||
local_irq_disable();
|
|
||||||
snd_pcm_stream_lock(substream);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq);
|
EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq);
|
||||||
|
|
||||||
@ -161,19 +198,13 @@ EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq);
|
|||||||
*/
|
*/
|
||||||
void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream)
|
void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
snd_pcm_stream_unlock(substream);
|
__snd_pcm_stream_unlock_mode(substream, PCM_LOCK_IRQ, 0);
|
||||||
if (!substream->pcm->nonatomic)
|
|
||||||
local_irq_enable();
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irq);
|
EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irq);
|
||||||
|
|
||||||
unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream)
|
unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
unsigned long flags = 0;
|
return __snd_pcm_stream_lock_mode(substream, PCM_LOCK_IRQSAVE);
|
||||||
if (!substream->pcm->nonatomic)
|
|
||||||
local_irq_save(flags);
|
|
||||||
snd_pcm_stream_lock(substream);
|
|
||||||
return flags;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave);
|
EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave);
|
||||||
|
|
||||||
@ -187,9 +218,7 @@ EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave);
|
|||||||
void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
|
void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
|
||||||
unsigned long flags)
|
unsigned long flags)
|
||||||
{
|
{
|
||||||
snd_pcm_stream_unlock(substream);
|
__snd_pcm_stream_unlock_mode(substream, PCM_LOCK_IRQSAVE, flags);
|
||||||
if (!substream->pcm->nonatomic)
|
|
||||||
local_irq_restore(flags);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore);
|
EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock_irqrestore);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user