diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-06-13 10:12:59 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-06-13 10:12:59 +0200 |
commit | 635c265f32d8a3f73402813d6a8dd47f2a363df5 (patch) | |
tree | f86815481d55d7b844468e4cca92211daea800e2 /sound/pci/ctxfi | |
parent | ALSA: ctxfi - Clear PCM resources at hw_params and hw_free (diff) | |
download | linux-635c265f32d8a3f73402813d6a8dd47f2a363df5.tar.xz linux-635c265f32d8a3f73402813d6a8dd47f2a363df5.zip |
ALSA: ctxfi - Replace atc lock to mutex
The spinlock in atc can cause a sleep in lock:
Kernel failure message 1:
BUG: sleeping function called from invalid context at mm/slub.c:1599
in_atomic(): 0, irqs_disabled(): 1, pid: 2537, name: gstreamer-prope
Pid: 2537, comm: gstreamer-prope Tainted: P
2.6.29.4-167.fc11.x86_64 #1
Call Trace:
[<ffffffff8103ff0f>] __might_sleep+0x10b/0x110
[<ffffffff810cd734>] __kmalloc+0x73/0x130
[<ffffffffa0b4b142>] ? daio_rsc_init+0xaa/0x125 [snd_ctxfi]
[<ffffffffa0b4b212>] dao_rsc_init+0x55/0x1c0 [snd_ctxfi]
[<ffffffffa0b4b3d2>] dao_rsc_reinit+0x55/0x5d [snd_ctxfi]
[<ffffffff813abd6c>] ? _spin_lock_irqsave+0x32/0x3b
[<ffffffffa0b454fe>] atc_spdif_out_passthru+0x92/0x136 [snd_ctxfi]
...
Since the lock path is no critical path, it can be gracefully
replaced with a mutex.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/ctxfi')
-rw-r--r-- | sound/pci/ctxfi/ctatc.c | 22 | ||||
-rw-r--r-- | sound/pci/ctxfi/ctatc.h | 4 |
2 files changed, 11 insertions, 15 deletions
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 80fb2baed7a7..b0adc8094009 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -259,7 +259,6 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) int n_amixer = apcm->substream->runtime->channels, i = 0; int device = apcm->substream->pcm->device; unsigned int pitch; - unsigned long flags; if (NULL != apcm->src) { /* Prepared pcm playback */ @@ -311,10 +310,10 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) src = apcm->src; for (i = 0; i < n_amixer; i++) { amixer = apcm->amixers[i]; - spin_lock_irqsave(&atc->atc_lock, flags); + mutex_lock(&atc->atc_mutex); amixer->ops->setup(amixer, &src->rsc, INIT_VOL, atc->pcm[i+device*2]); - spin_unlock_irqrestore(&atc->atc_lock, flags); + mutex_unlock(&atc->atc_mutex); src = src->ops->next_interleave(src); if (NULL == src) src = apcm->src; @@ -865,7 +864,6 @@ static int spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) { struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio); - unsigned long flags; unsigned int rate = apcm->substream->runtime->rate; unsigned int status; int err; @@ -885,7 +883,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) return -ENOENT; } - spin_lock_irqsave(&atc->atc_lock, flags); + mutex_lock(&atc->atc_mutex); dao->ops->get_spos(dao, &status); if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) { status &= ((~IEC958_AES3_CON_FS) << 24); @@ -895,7 +893,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) } if ((rate != atc->pll_rate) && (32000 != rate)) err = atc_pll_init(atc, rate); - spin_unlock_irqrestore(&atc->atc_lock, flags); + mutex_unlock(&atc->atc_mutex); return err; } @@ -908,7 +906,6 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) struct dao *dao; int err; int i; - unsigned long flags; if (NULL != apcm->src) return 0; @@ -934,13 +931,13 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) src = apcm->src; } /* Connect to SPDIFOO */ - spin_lock_irqsave(&atc->atc_lock, flags); + mutex_lock(&atc->atc_mutex); dao = container_of(atc->daios[SPDIFOO], struct dao, daio); amixer = apcm->amixers[0]; dao->ops->set_left_input(dao, &amixer->rsc); amixer = apcm->amixers[1]; dao->ops->set_right_input(dao, &amixer->rsc); - spin_unlock_irqrestore(&atc->atc_lock, flags); + mutex_unlock(&atc->atc_mutex); ct_timer_prepare(apcm->timer); @@ -1088,7 +1085,6 @@ static int atc_spdif_out_set_status(struct ct_atc *atc, unsigned int status) static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) { - unsigned long flags; struct dao_desc da_dsc = {0}; struct dao *dao; int err; @@ -1096,7 +1092,7 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) struct rsc *rscs[2] = {NULL}; unsigned int spos = 0; - spin_lock_irqsave(&atc->atc_lock, flags); + mutex_lock(&atc->atc_mutex); dao = container_of(atc->daios[SPDIFOO], struct dao, daio); da_dsc.msr = state ? 1 : atc->msr; da_dsc.passthru = state ? 1 : 0; @@ -1114,7 +1110,7 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) } dao->ops->set_spos(dao, spos); dao->ops->commit_write(dao); - spin_unlock_irqrestore(&atc->atc_lock, flags); + mutex_unlock(&atc->atc_mutex); return err; } @@ -1572,7 +1568,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, atc->msr = msr; atc->chip_type = chip_type; - spin_lock_init(&atc->atc_lock); + mutex_init(&atc->atc_mutex); /* Find card model */ err = atc_identify_card(atc); diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h index a03347232e84..9fe620ea5f3f 100644 --- a/sound/pci/ctxfi/ctatc.h +++ b/sound/pci/ctxfi/ctatc.h @@ -19,7 +19,7 @@ #define CTATC_H #include <linux/types.h> -#include <linux/spinlock_types.h> +#include <linux/mutex.h> #include <linux/pci.h> #include <linux/timer.h> #include <sound/core.h> @@ -90,7 +90,7 @@ struct ct_atc { void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm); unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index); - spinlock_t atc_lock; + struct mutex atc_mutex; int (*pcm_playback_prepare)(struct ct_atc *atc, struct ct_atc_pcm *apcm); |