On Thu, Jan 04, 2007 at 05:52:08PM +0700, Eugene Grosbein wrote:
> On Thu, Jan 04, 2007 at 12:37:08PM +0200, Kostik Belousov wrote:
> 
> > The problem is revealed by INVARIANTS option, not by WITNESS, and is 
> > definitely the use-after-free.
> > 
> > in src/nvidia_dev.c, nvidia_dev_close(), that is cdevsw.d_close proc,
> > the destroy_dev() is called. Please, apply rev. 1.199 of 
> > sys/kern/kern_conf.c.
> > I expect that crashes shall stop, but non-killable processes (in the 
> > "devdrn")
> > state would accumulate.
> > 
> > Please, confirm.
> 
> I've tried to apply 1.199 to RELENG_6 but failed:
> one of three chunks has been rejected.
> 

Hmm, it needs 1.198 as well. Below is aggregated patch against RELENG_6.

Index: kern_conf.c
===================================================================
RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_conf.c,v
retrieving revision 1.186.2.7
diff -u -r1.186.2.7 kern_conf.c
--- kern_conf.c 30 Oct 2006 15:43:56 -0000      1.186.2.7
+++ kern_conf.c 4 Jan 2007 10:59:33 -0000
@@ -676,16 +676,20 @@
                dev->si_flags &= ~SI_CLONELIST;
        }
 
+       dev->si_refcount++;     /* Avoid race with dev_rel() */
        csw = dev->si_devsw;
        dev->si_devsw = NULL;   /* already NULL for SI_ALIAS */
        while (csw != NULL && csw->d_purge != NULL && dev->si_threadcount) {
-               printf("Purging %lu threads from %s\n",
-                   dev->si_threadcount, devtoname(dev));
                csw->d_purge(dev);
                msleep(csw, &devmtx, PRIBIO, "devprg", hz/10);
+               if (dev->si_threadcount)
+                       printf("Still %lu threads in %s\n",
+                           dev->si_threadcount, devtoname(dev));
+       }
+       while (dev->si_threadcount != 0) {
+               /* Use unique dummy wait ident */
+               msleep(&csw, &devmtx, PRIBIO, "devdrn", hz / 10);
        }
-       if (csw != NULL && csw->d_purge != NULL)
-               printf("All threads purged from %s\n", devtoname(dev));
 
        dev->si_drv1 = 0;
        dev->si_drv2 = 0;
@@ -700,6 +704,7 @@
                        fini_cdevsw(csw);
        }
        dev->si_flags &= ~SI_ALIAS;
+       dev->si_refcount--;     /* Avoid race with dev_rel() */
 
        if (dev->si_refcount > 0) {
                LIST_INSERT_HEAD(&dead_cdevsw.d_devs, dev, si_list);

Attachment: pgpcRQGmWAiDo.pgp
Description: PGP signature

Reply via email to