A signal can end the interruptible wait while a STOP or RELEASE request is
still pending. A later teardown may then submit another RELEASE before the
first request completes.

Keep both waits non-interruptible and use the existing message timeout.
Other control requests remain interruptible. Device reset still cancels the
pending request and wakes the waiter.

Assisted-by: LLM
Signed-off-by: Joonho Lee <[email protected]>

---
diff --git a/sound/virtio/virtio_ctl_msg.c b/sound/virtio/virtio_ctl_msg.c
--- a/sound/virtio/virtio_ctl_msg.c
+++ b/sound/virtio/virtio_ctl_msg.c
@@ -314,7 +314,20 @@
                 */
                virtsnd_ctl_msg_unref(msg);
        } else if (!nowait) {
-               rc = wait_for_completion_interruptible_timeout(&msg->notify, 
js);
+               /*
+                * Teardown must observe completion even with a pending signal.
+                * Otherwise a subsequent open can retry RELEASE while the 
device
+                * is still processing the previous teardown request.
+                */
+               switch (le32_to_cpu(request->code)) {
+               case VIRTIO_SND_R_PCM_STOP:
+               case VIRTIO_SND_R_PCM_RELEASE:
+                       rc = wait_for_completion_timeout(&msg->notify, js);
+                       break;
+               default:
+                       rc = 
wait_for_completion_interruptible_timeout(&msg->notify, js);
+                       break;
+               }
                if (!rc) {
                        dev_err(&vdev->dev,
                                "control message (0x%08x) timeout\n",
diff --git a/sound/virtio/virtio_ctl_msg.h b/sound/virtio/virtio_ctl_msg.h
--- a/sound/virtio/virtio_ctl_msg.h
+++ b/sound/virtio/virtio_ctl_msg.h
@@ -47,6 +47,9 @@
  * The msg_timeout_ms module parameter defines the message completion timeout.
  * If the message is not completed within this time, the function will return 
an
  * error.
+ * PCM STOP and RELEASE wait through pending signals within this timeout.
+ * Other requests remain interruptible. Device reset cancels and wakes either
+ * kind of waiter.
  *
  * Context: Any context that permits to sleep.
  * Return: 0 on success, -errno on failure.

Reply via email to