Index: sys/file.h =================================================================== RCS file: /usr/home/ncvs/src/sys/sys/file.h,v retrieving revision 1.73 diff -u -r1.73 file.h --- sys/file.h 5 Jan 2007 19:59:46 -0000 1.73 +++ sys/file.h 6 Aug 2007 02:07:59 -0000 @@ -128,7 +128,6 @@ short f_gcflag; /* used by thread doing fd garbage collection */ #define FMARK 0x1 /* mark during gc() */ #define FDEFER 0x2 /* defer for next gc pass */ -#define FWAIT 0x4 /* gc is scanning message buffers */ int f_msgcount; /* (f) references from message queue */ /* DTYPE_VNODE specific fields */ Index: kern/kern_descrip.c =================================================================== RCS file: /usr/home/ncvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.312 diff -u -r1.312 kern_descrip.c --- kern/kern_descrip.c 3 Jul 2007 21:26:06 -0000 1.312 +++ kern/kern_descrip.c 6 Aug 2007 02:07:59 -0000 @@ -2159,17 +2159,6 @@ FILE_UNLOCK(fp); return (0); } - - /* - * We might have just dropped the last reference to a file - * object that is for a UNIX domain socket whose message - * buffers are being examined in unp_gc(). If that is the - * case, FWAIT will be set in f_gcflag and we need to wait for - * unp_gc() to finish its scan. - */ - while (fp->f_gcflag & FWAIT) - msleep(&fp->f_gcflag, fp->f_mtxp, 0, "fpdrop", 0); - /* We have the last ref so we can proceed without the file lock. */ FILE_UNLOCK(fp); if (fp->f_count < 0) Index: kern/uipc_usrreq.c =================================================================== RCS file: /usr/home/ncvs/src/sys/kern/uipc_usrreq.c,v retrieving revision 1.206 diff -u -r1.206 uipc_usrreq.c --- kern/uipc_usrreq.c 26 Jul 2007 16:58:09 -0000 1.206 +++ kern/uipc_usrreq.c 6 Aug 2007 02:07:59 -0000 @@ -104,7 +104,7 @@ static unp_gen_t unp_gencnt; static u_int unp_count; /* Count of local sockets. */ static ino_t unp_ino; /* Prototype for fake inode numbers. */ -static int unp_rights; /* File descriptors in flight. */ +static volatile int unp_rights; /* File descriptors in flight. */ static struct unp_head unp_shead; /* List of local stream sockets. */ static struct unp_head unp_dhead; /* List of local datagram sockets. */ @@ -147,7 +147,8 @@ &unpdg_sendspace, 0, ""); SYSCTL_ULONG(_net_local_dgram, OID_AUTO, recvspace, CTLFLAG_RW, &unpdg_recvspace, 0, ""); -SYSCTL_INT(_net_local, OID_AUTO, inflight, CTLFLAG_RD, &unp_rights, 0, ""); +SYSCTL_INT(_net_local, OID_AUTO, inflight, CTLFLAG_RD, + __DEVOLATILE(int *, &unp_rights), 0, ""); /*- * Locking and synchronization: @@ -1603,7 +1604,7 @@ FILE_LOCK(fp); fp->f_msgcount--; FILE_UNLOCK(fp); - unp_rights--; + atomic_subtract_int(&unp_rights, 1); *fdp++ = f; } FILEDESC_XUNLOCK(td->td_proc->p_fd); @@ -1769,7 +1770,7 @@ fp->f_count++; fp->f_msgcount++; FILE_UNLOCK(fp); - unp_rights++; + atomic_add_int(&unp_rights, 1); } FILEDESC_SUNLOCK(fdescp); break; @@ -1904,10 +1905,10 @@ * consideration. Clear the flag now if so. */ if (fp->f_count == 0) { + FILE_UNLOCK(fp); if (fp->f_gcflag & FDEFER) unp_defer--; fp->f_gcflag &= ~(FMARK|FDEFER); - FILE_UNLOCK(fp); continue; } /* @@ -1959,11 +1960,10 @@ } /* - * Tell any other threads that do a subsequent - * fdrop() that we are scanning the message - * buffers. + * Grab a reference so the descriptor can't go away + * while we're scanning. */ - fp->f_gcflag |= FWAIT; + fhold_locked(fp); FILE_UNLOCK(fp); /* @@ -1978,12 +1978,9 @@ SOCKBUF_UNLOCK(&so->so_rcv); /* - * Wake up any threads waiting in fdrop(). + * Let go of our reference. */ - FILE_LOCK(fp); - fp->f_gcflag &= ~FWAIT; - wakeup(&fp->f_gcflag); - FILE_UNLOCK(fp); + fdrop(fp, NULL); } } while (unp_defer); sx_sunlock(&filelist_lock); @@ -2070,19 +2067,12 @@ */ for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) { struct file *tfp = *fpp; - FILE_LOCK(tfp); - if (tfp->f_type == DTYPE_SOCKET && - tfp->f_data != NULL) { - FILE_UNLOCK(tfp); + if (tfp->f_type == DTYPE_SOCKET && tfp->f_data != NULL) sorflush(tfp->f_data); - } else { - FILE_UNLOCK(tfp); - } } - for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) { + for (i = nunref, fpp = extra_ref; --i >= 0; ++fpp) closef(*fpp, (struct thread *) NULL); - unp_recycled++; - } + unp_recycled += nunref; free(extra_ref, M_TEMP); } @@ -2159,12 +2149,10 @@ unp_discard(struct file *fp) { - UNP_GLOBAL_WLOCK(); FILE_LOCK(fp); fp->f_msgcount--; - unp_rights--; FILE_UNLOCK(fp); - UNP_GLOBAL_WUNLOCK(); + atomic_subtract_int(&unp_rights, 1); (void) closef(fp, (struct thread *)NULL); }