linux/sound/usb
Takashi Iwai 47ab154593 ALSA: usb-audio: Avoid nested autoresume calls
After the recent fix of runtime PM for USB-audio driver, we got a
lockdep warning like:

  =============================================
  [ INFO: possible recursive locking detected ]
  4.2.0-rc8+ #61 Not tainted
  ---------------------------------------------
  pulseaudio/980 is trying to acquire lock:
   (&chip->shutdown_rwsem){.+.+.+}, at: [<ffffffffa0355dac>] snd_usb_autoresume+0x1d/0x52 [snd_usb_audio]
  but task is already holding lock:
   (&chip->shutdown_rwsem){.+.+.+}, at: [<ffffffffa0355dac>] snd_usb_autoresume+0x1d/0x52 [snd_usb_audio]

This comes from snd_usb_autoresume() invoking down_read() and it's
used in a nested way.  Although it's basically safe, per se (as these
are read locks), it's better to reduce such spurious warnings.

The read lock is needed to guarantee the execution of "shutdown"
(cleanup at disconnection) task after all concurrent tasks are
finished.  This can be implemented in another better way.

Also, the current check of chip->in_pm isn't good enough for
protecting the racy execution of multiple auto-resumes.

This patch rewrites the logic of snd_usb_autoresume() & co; namely,
- The recursive call of autopm is avoided by the new refcount,
  chip->active.  The chip->in_pm flag is removed accordingly.
- Instead of rwsem, another refcount, chip->usage_count, is introduced
  for tracking the period to delay the shutdown procedure.  At
  the last clear of this refcount, wake_up() to the shutdown waiter is
  called.
- The shutdown flag is replaced with shutdown atomic count; this is
  for reducing the lock.
- Two new helpers are introduced to simplify the management of these
  refcounts; snd_usb_lock_shutdown() increases the usage_count, checks
  the shutdown state, and does autoresume.  snd_usb_unlock_shutdown()
  does the opposite.  Most of mixer and other codes just need this,
  and simply returns an error if it receives an error from lock.

Fixes: 9003ebb13f ('ALSA: usb-audio: Fix runtime PM unbalance')
Reported-and-tested-by: Alexnader Kuleshov <kuleshovmail@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2015-08-26 15:38:25 +02:00
..
6fire ALSA: 6fire: Convert byte_rev_table uses to bitrev8 2014-11-14 08:01:53 +01:00
bcd2000 ALSA: bcd2000: Make local data static 2015-05-26 13:00:01 +02:00
caiaq ALSA: snd-usb-caiaq: fix stream count check 2015-01-05 08:56:19 +01:00
hiface ALSA: usb: Convert to snd_card_new() with a device pointer 2014-02-12 11:18:00 +01:00
line6 ALSA: line6: Fix -EBUSY error during active monitoring 2015-07-14 15:19:37 +02:00
misc ALSA: pcm: Add snd_pcm_stop_xrun() helper 2014-11-09 18:20:40 +01:00
usx2y ALSA: usx2y: Move UAPI definition into include/uapi/sound/usb_stream.h 2015-01-28 17:33:49 +01:00
card.c ALSA: usb-audio: Avoid nested autoresume calls 2015-08-26 15:38:25 +02:00
card.h ALSA: usb: update trigger timestamp on first non-zero URB submitted 2015-02-09 16:02:43 +01:00
clock.c ALSA: usb-audio: Don't attempt to get Lifecam HD-5000 sample rate 2015-02-17 07:20:04 +01:00
clock.h ALSA: usb-audio: UAC2: do clock validity check earlier 2013-04-04 08:30:59 +02:00
debug.h ALSA: usb-audio: make hwc_debug a noop in case HW_CONST_DEBUG is not set 2011-05-18 11:44:35 +02:00
endpoint.c ALSA: usb-audio: Avoid nested autoresume calls 2015-08-26 15:38:25 +02:00
endpoint.h ALSA: usb-audio: Pass direct struct pointer instead of list_head 2014-11-04 15:09:10 +01:00
format.c ALSA: usb-audio: Fix audio output on Roland SC-D70 sound module 2015-04-21 07:59:10 +02:00
format.h ALSA: usb-audio: store protocol version in struct audioformat 2013-06-27 21:59:47 +02:00
helper.c ALSA: usb-audio: support wireless devices in snd_usb_parse_datainterval 2013-10-07 12:52:21 +02:00
helper.h ALSA: usb-audio: increase control transfer timeout 2011-09-27 09:21:48 +02:00
Kconfig ALSA: move line6 usb driver into sound/usb 2015-01-12 22:29:57 +01:00
Makefile ALSA: line6: Split to each driver 2015-01-20 08:14:17 +01:00
midi.c ALSA: usb-audio: Use setup_timer() and mod_timer() 2015-01-19 11:43:50 +01:00
midi.h ALSA: usb-audio: Whitespace cleanups for sound/usb/midi.* 2014-08-05 20:08:00 +02:00
mixer_maps.c ALSA: usb-audio: add dB range mapping for some devices 2015-07-29 09:28:02 +02:00
mixer_quirks.c ALSA: usb-audio: Avoid nested autoresume calls 2015-08-26 15:38:25 +02:00
mixer_quirks.h ALSA: usb-mixer: factor out quirks 2010-03-12 12:20:26 +01:00
mixer_scarlett.c ALSA: usb-audio: Fix Scarlett 6i6 initialization typo 2014-12-18 08:39:17 +01:00
mixer_scarlett.h ALSA: usb-audio: Scarlett mixer interface for 6i6, 18i6, 18i8 and 18i20 2014-11-13 07:32:39 +01:00
mixer.c ALSA: usb-audio: Avoid nested autoresume calls 2015-08-26 15:38:25 +02:00
mixer.h ALSA: usb-audio: Fix parameter block size for UAC2 control requests 2015-08-14 16:26:50 +02:00
pcm.c ALSA: usb-audio: Avoid nested autoresume calls 2015-08-26 15:38:25 +02:00
pcm.h ALSA: usb: refine delay information with USB frame counter 2011-09-12 10:30:20 +02:00
power.h ALSA: usbaudio: implement USB autosuspend 2011-03-11 14:59:29 +01:00
proc.c ALSA: usb-audio: Avoid nested autoresume calls 2015-08-26 15:38:25 +02:00
proc.h ALSA: usb-audio: refactor code 2010-03-05 08:17:14 +01:00
quirks-table.h ALSA: usb-audio: Add MIDI support for Steinberg MI2/MI4 2015-07-01 17:29:40 +02:00
quirks.c ALSA: usb: Add native DSD support for Gustard DAC-X20U 2015-08-21 10:27:35 +02:00
quirks.h ALSA: usb-audio: Don't attempt to get Lifecam HD-5000 sample rate 2015-02-17 07:20:04 +01:00
stream.c ALSA: usb-audio: Use standard printk helpers 2014-02-26 16:45:34 +01:00
stream.h ALSA: snd-usb: re-order code 2011-09-14 17:07:02 +02:00
usbaudio.h ALSA: usb-audio: Avoid nested autoresume calls 2015-08-26 15:38:25 +02:00