On 15/01/20(Wed) 20:26, Vadim Zhukov wrote:
> I have a diff or two for that, will send when I'll come home.

After discussing the issue with Peter Stuge, we figured out that
the free should happen *after* calling config_detach() for the child
device (video(4)).

When video(4) is detached it will call:

        vdevgone()->videoclose()->uvideo_close()

this last function will sleep until all I/O are finished or cancelled as
part of usbd_pipe_close(9).

Diff below should fix the issue.

Index: dev/video.c
===================================================================
RCS file: /cvs/src/sys/dev/video.c,v
retrieving revision 1.42
diff -u -p -r1.42 video.c
--- dev/video.c 6 Oct 2019 17:13:10 -0000       1.42
+++ dev/video.c 15 Jan 2020 19:11:20 -0000
@@ -463,9 +463,6 @@ videodetach(struct device *self, int fla
        struct video_softc *sc = (struct video_softc *)self;
        int maj, mn;
 
-       if (sc->sc_fbuffer != NULL)
-               free(sc->sc_fbuffer, M_DEVBUF, sc->sc_fbufferlen);
-
        /* locate the major number */
        for (maj = 0; maj < nchrdev; maj++)
                if (cdevsw[maj].d_open == videoopen)
@@ -474,6 +471,8 @@ videodetach(struct device *self, int fla
        /* Nuke the vnodes for any open instances (calls close). */
        mn = self->dv_unit;
        vdevgone(maj, mn, mn, VCHR);
+
+       free(sc->sc_fbuffer, M_DEVBUF, sc->sc_fbufferlen);
 
        return (0);
 }
Index: dev/usb/uvideo.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uvideo.c,v
retrieving revision 1.205
diff -u -p -r1.205 uvideo.c
--- dev/usb/uvideo.c    14 Oct 2019 09:20:48 -0000      1.205
+++ dev/usb/uvideo.c    15 Jan 2020 19:09:48 -0000
@@ -644,10 +644,10 @@ uvideo_detach(struct device *self, int f
        /* Wait for outstanding requests to complete */
        usbd_delay_ms(sc->sc_udev, UVIDEO_NFRAMES_MAX);
 
-       uvideo_vs_free_frame(sc);
-
        if (sc->sc_videodev != NULL)
                rv = config_detach(sc->sc_videodev, flags);
+
+       uvideo_vs_free_frame(sc);
 
        return (rv);
 }

Reply via email to