On Mon Jul 6 16:50:15 2026 -0400, Shuangpeng Bai wrote:
> go7007_snd_init() already takes a v4l2_device reference for the ALSA
> side, but go7007_snd_remove() drops it immediately after calling
> snd_card_free_when_closed().
> 
> That is too early when a userspace process still has the capture PCM open.
> The ALSA card and its PCM callbacks remain alive until the last file is
> closed, so the release path can still reach struct go7007 through
> pcm->private_data and call go7007_snd_hw_free() after the V4L2 release path
> has freed the object.
> 
> Move the matching v4l2_device_put() to the ALSA card private_free callback
> so the existing ALSA reference covers the whole deferred card lifetime.
> 
> Closes: 
> https://lore.kernel.org/r/[email protected]
> Fixes: d5d3a7cc127d ("[media] go7007: fix unregister/disconnect handling")
> Cc: [email protected]
> Signed-off-by: Shuangpeng Bai <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/usb/go7007/snd-go7007.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

---

diff --git a/drivers/media/usb/go7007/snd-go7007.c 
b/drivers/media/usb/go7007/snd-go7007.c
index e4b9f37be77b..01d547ad678d 100644
--- a/drivers/media/usb/go7007/snd-go7007.c
+++ b/drivers/media/usb/go7007/snd-go7007.c
@@ -195,6 +195,13 @@ static const struct snd_device_ops go7007_snd_device_ops = 
{
        .dev_free       = go7007_snd_free,
 };
 
+static void go7007_snd_card_free(struct snd_card *card)
+{
+       struct go7007 *go = card->private_data;
+
+       v4l2_device_put(&go->v4l2_dev);
+}
+
 int go7007_snd_init(struct go7007 *go)
 {
        static int dev;
@@ -245,6 +252,8 @@ int go7007_snd_init(struct go7007 *go)
        gosnd->substream = NULL;
        go->snd_context = gosnd;
        v4l2_device_get(&go->v4l2_dev);
+       gosnd->card->private_data = go;
+       gosnd->card->private_free = go7007_snd_card_free;
        ++dev;
 
        return 0;
@@ -263,7 +272,6 @@ int go7007_snd_remove(struct go7007 *go)
 
        snd_card_disconnect(gosnd->card);
        snd_card_free_when_closed(gosnd->card);
-       v4l2_device_put(&go->v4l2_dev);
        return 0;
 }
 EXPORT_SYMBOL(go7007_snd_remove);
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to