[pulseaudio-commits] [Git][pulseaudio/pulseaudio][master] alsa: make the unsuspend more robust

Tanu Kaskinen gitlab at gitlab.freedesktop.org
Fri Jul 10 03:41:07 UTC 2020



Tanu Kaskinen pushed to branch master at PulseAudio / pulseaudio


Commits:
ede8cbb1 by Hui Wang at 2020-07-09T16:43:17+08:00
alsa: make the unsuspend more robust

We met a weird situation on a couple of Lenovo machines and at least
on one Dell machine. First we open the gnome-sound-setting, then
suspend and resume the system, after the system resume back, the audio
devices change to dummy, the audio doesn't work anymore. And pacmd
list-cards shows no available sound card.

Through debugging I found after resume, the alsa receives POLLERR
events and it will call unsuspend to recover the pcm, but at that
moment, the device nodes in /dev/snd/ is not accessible, so the
snd_pcm_open() fails and the pulseaudio unload the module-alsa-card.

Here I add retry and pa_msleep if snd_pcm_open fails, I tested it on
all machines which have this problem, pa_msleep(25) is ok for most of
them, there is only one machine which needs to call pa_msleep(25)
twice, so for safety reason, I set the max retry times to 4.

Signed-off-by: Hui Wang <hui.wang at canonical.com>

- - - - -


2 changed files:

- src/modules/alsa/alsa-sink.c
- src/modules/alsa/alsa-source.c


Changes:

=====================================
src/modules/alsa/alsa-sink.c
=====================================
@@ -1152,7 +1152,7 @@ static void update_size(struct userdata *u, pa_sample_spec *ss) {
 /* Called from IO context */
 static int unsuspend(struct userdata *u, bool recovering) {
     pa_sample_spec ss;
-    int err;
+    int err, i;
     bool b, d;
     snd_pcm_uframes_t period_frames, buffer_frames;
     snd_pcm_uframes_t tsched_frames = 0;
@@ -1172,13 +1172,26 @@ static int unsuspend(struct userdata *u, bool recovering) {
         pa_snprintf(device_name, len, "%s,AES0=6", u->device_name);
     }
 
-    if ((err = snd_pcm_open(&u->pcm_handle, device_name ? device_name : u->device_name, SND_PCM_STREAM_PLAYBACK,
-                            SND_PCM_NONBLOCK|
-                            SND_PCM_NO_AUTO_RESAMPLE|
-                            SND_PCM_NO_AUTO_CHANNELS|
-                            SND_PCM_NO_AUTO_FORMAT)) < 0) {
-        pa_log("Error opening PCM device %s: %s", u->device_name, pa_alsa_strerror(err));
-        goto fail;
+    /*
+     * On some machines, during the system suspend and resume, the thread_func could receive
+     * POLLERR events before the dev nodes in /dev/snd/ are accessible, and thread_func calls
+     * the unsuspend() to try to recover the PCM, this will make the snd_pcm_open() fail, here
+     * we add msleep and retry to make sure those nodes are accessible.
+     */
+    for (i = 0; i < 4; i++) {
+	if ((err = snd_pcm_open(&u->pcm_handle, device_name ? device_name : u->device_name, SND_PCM_STREAM_PLAYBACK,
+				SND_PCM_NONBLOCK|
+				SND_PCM_NO_AUTO_RESAMPLE|
+				SND_PCM_NO_AUTO_CHANNELS|
+				SND_PCM_NO_AUTO_FORMAT)) < 0 && recovering)
+	    pa_msleep(25);
+	else
+	    break;
+    }
+
+    if (err < 0) {
+	pa_log("Error opening PCM device %s: %s", u->device_name, pa_alsa_strerror(err));
+	goto fail;
     }
 
     if (pa_frame_size(&u->sink->sample_spec) != u->frame_size) {


=====================================
src/modules/alsa/alsa-source.c
=====================================
@@ -1033,7 +1033,7 @@ static void update_size(struct userdata *u, pa_sample_spec *ss) {
 /* Called from IO context */
 static int unsuspend(struct userdata *u, bool recovering) {
     pa_sample_spec ss;
-    int err;
+    int err, i;
     bool b, d;
     snd_pcm_uframes_t period_frames, buffer_frames;
     snd_pcm_uframes_t tsched_frames = 0;
@@ -1044,12 +1044,25 @@ static int unsuspend(struct userdata *u, bool recovering) {
 
     pa_log_info("Trying resume...");
 
-    if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE,
-                            SND_PCM_NONBLOCK|
-                            SND_PCM_NO_AUTO_RESAMPLE|
-                            SND_PCM_NO_AUTO_CHANNELS|
-                            SND_PCM_NO_AUTO_FORMAT)) < 0) {
-        pa_log("Error opening PCM device %s: %s", u->device_name, pa_alsa_strerror(err));
+    /*
+     * On some machines, during the system suspend and resume, the thread_func could receive
+     * POLLERR events before the dev nodes in /dev/snd/ are accessible, and thread_func calls
+     * the unsuspend() to try to recover the PCM, this will make the snd_pcm_open() fail, here
+     * we add msleep and retry to make sure those nodes are accessible.
+     */
+    for (i = 0; i < 4; i++) {
+	if ((err = snd_pcm_open(&u->pcm_handle, u->device_name, SND_PCM_STREAM_CAPTURE,
+				SND_PCM_NONBLOCK|
+				SND_PCM_NO_AUTO_RESAMPLE|
+				SND_PCM_NO_AUTO_CHANNELS|
+				SND_PCM_NO_AUTO_FORMAT)) < 0 && recovering)
+	    pa_msleep(25);
+	else
+	    break;
+    }
+
+    if (err < 0) {
+	pa_log("Error opening PCM device %s: %s", u->device_name, pa_alsa_strerror(err));
         goto fail;
     }
 



View it on GitLab: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/commit/ede8cbb131f7493f14f5717aefd5b4e0603a05d1

-- 
View it on GitLab: https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/commit/ede8cbb131f7493f14f5717aefd5b4e0603a05d1
You're receiving this email because of your account on gitlab.freedesktop.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/pulseaudio-commits/attachments/20200710/ec03b6d5/attachment-0001.htm>


More information about the pulseaudio-commits mailing list