Skip to content

Commit 89dbb33

Browse files
committed
ALSA: jack: Fix mutex call in snd_jack_report()
snd_jack_report() is supposed to be callable from an IRQ context, too, and it's indeed used in that way from virtsnd driver. The fix for input_dev race in commit 1b6a6fc ("ALSA: jack: Access input_dev under mutex"), however, introduced a mutex lock in snd_jack_report(), and this resulted in a potential sleep-in-atomic. For addressing that problem, this patch changes the relevant code to use the object get/put and removes the mutex usage. That is, snd_jack_report(), it takes input_get_device() and leaves with input_put_device() for assuring the input_dev being assigned. Although the whole mutex could be reduced, we keep it because it can be still a protection for potential races between creation and deletion. Fixes: 1b6a6fc ("ALSA: jack: Access input_dev under mutex") Reported-by: Dan Carpenter <[email protected]> Closes: https://lore.kernel.org/r/[email protected] Tested-by: Amadeusz Sławiński <[email protected]> Cc: <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 5284876 commit 89dbb33

File tree

1 file changed

+7
-8
lines changed

1 file changed

+7
-8
lines changed

sound/core/jack.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ void snd_jack_report(struct snd_jack *jack, int status)
654654
struct snd_jack_kctl *jack_kctl;
655655
unsigned int mask_bits = 0;
656656
#ifdef CONFIG_SND_JACK_INPUT_DEV
657+
struct input_dev *idev;
657658
int i;
658659
#endif
659660

@@ -670,31 +671,29 @@ void snd_jack_report(struct snd_jack *jack, int status)
670671
status & jack_kctl->mask_bits);
671672

672673
#ifdef CONFIG_SND_JACK_INPUT_DEV
673-
mutex_lock(&jack->input_dev_lock);
674-
if (!jack->input_dev) {
675-
mutex_unlock(&jack->input_dev_lock);
674+
idev = input_get_device(jack->input_dev);
675+
if (!idev)
676676
return;
677-
}
678677

679678
for (i = 0; i < ARRAY_SIZE(jack->key); i++) {
680679
int testbit = ((SND_JACK_BTN_0 >> i) & ~mask_bits);
681680

682681
if (jack->type & testbit)
683-
input_report_key(jack->input_dev, jack->key[i],
682+
input_report_key(idev, jack->key[i],
684683
status & testbit);
685684
}
686685

687686
for (i = 0; i < ARRAY_SIZE(jack_switch_types); i++) {
688687
int testbit = ((1 << i) & ~mask_bits);
689688

690689
if (jack->type & testbit)
691-
input_report_switch(jack->input_dev,
690+
input_report_switch(idev,
692691
jack_switch_types[i],
693692
status & testbit);
694693
}
695694

696-
input_sync(jack->input_dev);
697-
mutex_unlock(&jack->input_dev_lock);
695+
input_sync(idev);
696+
input_put_device(idev);
698697
#endif /* CONFIG_SND_JACK_INPUT_DEV */
699698
}
700699
EXPORT_SYMBOL(snd_jack_report);

0 commit comments

Comments
 (0)