diff options
| author | Takashi Iwai <tiwai@suse.de> | 2009-06-13 04:12:59 -0400 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2009-06-13 04:12:59 -0400 |
| commit | 635c265f32d8a3f73402813d6a8dd47f2a363df5 (patch) | |
| tree | f86815481d55d7b844468e4cca92211daea800e2 | |
| parent | a5990dc5b96f537618b0f057c8723a6a0b0cdc74 (diff) | |
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>
| -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) | |||
| 259 | int n_amixer = apcm->substream->runtime->channels, i = 0; | 259 | int n_amixer = apcm->substream->runtime->channels, i = 0; |
| 260 | int device = apcm->substream->pcm->device; | 260 | int device = apcm->substream->pcm->device; |
| 261 | unsigned int pitch; | 261 | unsigned int pitch; |
| 262 | unsigned long flags; | ||
| 263 | 262 | ||
| 264 | if (NULL != apcm->src) { | 263 | if (NULL != apcm->src) { |
| 265 | /* Prepared pcm playback */ | 264 | /* Prepared pcm playback */ |
| @@ -311,10 +310,10 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) | |||
| 311 | src = apcm->src; | 310 | src = apcm->src; |
| 312 | for (i = 0; i < n_amixer; i++) { | 311 | for (i = 0; i < n_amixer; i++) { |
| 313 | amixer = apcm->amixers[i]; | 312 | amixer = apcm->amixers[i]; |
| 314 | spin_lock_irqsave(&atc->atc_lock, flags); | 313 | mutex_lock(&atc->atc_mutex); |
| 315 | amixer->ops->setup(amixer, &src->rsc, | 314 | amixer->ops->setup(amixer, &src->rsc, |
| 316 | INIT_VOL, atc->pcm[i+device*2]); | 315 | INIT_VOL, atc->pcm[i+device*2]); |
| 317 | spin_unlock_irqrestore(&atc->atc_lock, flags); | 316 | mutex_unlock(&atc->atc_mutex); |
| 318 | src = src->ops->next_interleave(src); | 317 | src = src->ops->next_interleave(src); |
| 319 | if (NULL == src) | 318 | if (NULL == src) |
| 320 | src = apcm->src; | 319 | src = apcm->src; |
| @@ -865,7 +864,6 @@ static int | |||
| 865 | spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) | 864 | spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) |
| 866 | { | 865 | { |
| 867 | struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio); | 866 | struct dao *dao = container_of(atc->daios[SPDIFOO], struct dao, daio); |
| 868 | unsigned long flags; | ||
| 869 | unsigned int rate = apcm->substream->runtime->rate; | 867 | unsigned int rate = apcm->substream->runtime->rate; |
| 870 | unsigned int status; | 868 | unsigned int status; |
| 871 | int err; | 869 | int err; |
| @@ -885,7 +883,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) | |||
| 885 | return -ENOENT; | 883 | return -ENOENT; |
| 886 | } | 884 | } |
| 887 | 885 | ||
| 888 | spin_lock_irqsave(&atc->atc_lock, flags); | 886 | mutex_lock(&atc->atc_mutex); |
| 889 | dao->ops->get_spos(dao, &status); | 887 | dao->ops->get_spos(dao, &status); |
| 890 | if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) { | 888 | if (((status >> 24) & IEC958_AES3_CON_FS) != iec958_con_fs) { |
| 891 | status &= ((~IEC958_AES3_CON_FS) << 24); | 889 | status &= ((~IEC958_AES3_CON_FS) << 24); |
| @@ -895,7 +893,7 @@ spdif_passthru_playback_setup(struct ct_atc *atc, struct ct_atc_pcm *apcm) | |||
| 895 | } | 893 | } |
| 896 | if ((rate != atc->pll_rate) && (32000 != rate)) | 894 | if ((rate != atc->pll_rate) && (32000 != rate)) |
| 897 | err = atc_pll_init(atc, rate); | 895 | err = atc_pll_init(atc, rate); |
| 898 | spin_unlock_irqrestore(&atc->atc_lock, flags); | 896 | mutex_unlock(&atc->atc_mutex); |
| 899 | 897 | ||
| 900 | return err; | 898 | return err; |
| 901 | } | 899 | } |
| @@ -908,7 +906,6 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) | |||
| 908 | struct dao *dao; | 906 | struct dao *dao; |
| 909 | int err; | 907 | int err; |
| 910 | int i; | 908 | int i; |
| 911 | unsigned long flags; | ||
| 912 | 909 | ||
| 913 | if (NULL != apcm->src) | 910 | if (NULL != apcm->src) |
| 914 | return 0; | 911 | return 0; |
| @@ -934,13 +931,13 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm) | |||
| 934 | src = apcm->src; | 931 | src = apcm->src; |
| 935 | } | 932 | } |
| 936 | /* Connect to SPDIFOO */ | 933 | /* Connect to SPDIFOO */ |
| 937 | spin_lock_irqsave(&atc->atc_lock, flags); | 934 | mutex_lock(&atc->atc_mutex); |
| 938 | dao = container_of(atc->daios[SPDIFOO], struct dao, daio); | 935 | dao = container_of(atc->daios[SPDIFOO], struct dao, daio); |
| 939 | amixer = apcm->amixers[0]; | 936 | amixer = apcm->amixers[0]; |
| 940 | dao->ops->set_left_input(dao, &amixer->rsc); | 937 | dao->ops->set_left_input(dao, &amixer->rsc); |
| 941 | amixer = apcm->amixers[1]; | 938 | amixer = apcm->amixers[1]; |
| 942 | dao->ops->set_right_input(dao, &amixer->rsc); | 939 | dao->ops->set_right_input(dao, &amixer->rsc); |
| 943 | spin_unlock_irqrestore(&atc->atc_lock, flags); | 940 | mutex_unlock(&atc->atc_mutex); |
| 944 | 941 | ||
| 945 | ct_timer_prepare(apcm->timer); | 942 | ct_timer_prepare(apcm->timer); |
| 946 | 943 | ||
| @@ -1088,7 +1085,6 @@ static int atc_spdif_out_set_status(struct ct_atc *atc, unsigned int status) | |||
| 1088 | 1085 | ||
| 1089 | static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) | 1086 | static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) |
| 1090 | { | 1087 | { |
| 1091 | unsigned long flags; | ||
| 1092 | struct dao_desc da_dsc = {0}; | 1088 | struct dao_desc da_dsc = {0}; |
| 1093 | struct dao *dao; | 1089 | struct dao *dao; |
| 1094 | int err; | 1090 | int err; |
| @@ -1096,7 +1092,7 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) | |||
| 1096 | struct rsc *rscs[2] = {NULL}; | 1092 | struct rsc *rscs[2] = {NULL}; |
| 1097 | unsigned int spos = 0; | 1093 | unsigned int spos = 0; |
| 1098 | 1094 | ||
| 1099 | spin_lock_irqsave(&atc->atc_lock, flags); | 1095 | mutex_lock(&atc->atc_mutex); |
| 1100 | dao = container_of(atc->daios[SPDIFOO], struct dao, daio); | 1096 | dao = container_of(atc->daios[SPDIFOO], struct dao, daio); |
| 1101 | da_dsc.msr = state ? 1 : atc->msr; | 1097 | da_dsc.msr = state ? 1 : atc->msr; |
| 1102 | da_dsc.passthru = state ? 1 : 0; | 1098 | da_dsc.passthru = state ? 1 : 0; |
| @@ -1114,7 +1110,7 @@ static int atc_spdif_out_passthru(struct ct_atc *atc, unsigned char state) | |||
| 1114 | } | 1110 | } |
| 1115 | dao->ops->set_spos(dao, spos); | 1111 | dao->ops->set_spos(dao, spos); |
| 1116 | dao->ops->commit_write(dao); | 1112 | dao->ops->commit_write(dao); |
| 1117 | spin_unlock_irqrestore(&atc->atc_lock, flags); | 1113 | mutex_unlock(&atc->atc_mutex); |
| 1118 | 1114 | ||
| 1119 | return err; | 1115 | return err; |
| 1120 | } | 1116 | } |
| @@ -1572,7 +1568,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, | |||
| 1572 | atc->msr = msr; | 1568 | atc->msr = msr; |
| 1573 | atc->chip_type = chip_type; | 1569 | atc->chip_type = chip_type; |
| 1574 | 1570 | ||
| 1575 | spin_lock_init(&atc->atc_lock); | 1571 | mutex_init(&atc->atc_mutex); |
| 1576 | 1572 | ||
| 1577 | /* Find card model */ | 1573 | /* Find card model */ |
| 1578 | err = atc_identify_card(atc); | 1574 | 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 @@ | |||
| 19 | #define CTATC_H | 19 | #define CTATC_H |
| 20 | 20 | ||
| 21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
| 22 | #include <linux/spinlock_types.h> | 22 | #include <linux/mutex.h> |
| 23 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
| 24 | #include <linux/timer.h> | 24 | #include <linux/timer.h> |
| 25 | #include <sound/core.h> | 25 | #include <sound/core.h> |
| @@ -90,7 +90,7 @@ struct ct_atc { | |||
| 90 | void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm); | 90 | void (*unmap_audio_buffer)(struct ct_atc *atc, struct ct_atc_pcm *apcm); |
| 91 | unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index); | 91 | unsigned long (*get_ptp_phys)(struct ct_atc *atc, int index); |
| 92 | 92 | ||
| 93 | spinlock_t atc_lock; | 93 | struct mutex atc_mutex; |
| 94 | 94 | ||
| 95 | int (*pcm_playback_prepare)(struct ct_atc *atc, | 95 | int (*pcm_playback_prepare)(struct ct_atc *atc, |
| 96 | struct ct_atc_pcm *apcm); | 96 | struct ct_atc_pcm *apcm); |
