From owner-svn-src-all@FreeBSD.ORG Tue Feb 8 09:25:33 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 30A521065675; Tue, 8 Feb 2011 09:25:33 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 055F28FC28; Tue, 8 Feb 2011 09:25:33 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p189PWSp040160; Tue, 8 Feb 2011 09:25:32 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p189PW2D040158; Tue, 8 Feb 2011 09:25:32 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201102080925.p189PW2D040158@svn.freebsd.org> From: Konstantin Belousov Date: Tue, 8 Feb 2011 09:25:32 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r218430 - stable/8/sys/kern X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Feb 2011 09:25:33 -0000 Author: kib Date: Tue Feb 8 09:25:32 2011 New Revision: 218430 URL: http://svn.freebsd.org/changeset/base/218430 Log: MFC r218168: Only process as much array elements as we find the sockets during second phase of gc. Take linkage lock and recheck the eligibility of the socket for gc, as well as call fhold() under the linkage lock. Modified: stable/8/sys/kern/uipc_usrreq.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) Modified: stable/8/sys/kern/uipc_usrreq.c ============================================================================== --- stable/8/sys/kern/uipc_usrreq.c Tue Feb 8 08:44:08 2011 (r218429) +++ stable/8/sys/kern/uipc_usrreq.c Tue Feb 8 09:25:32 2011 (r218430) @@ -2045,9 +2045,9 @@ unp_gc(__unused void *arg, int pending) { struct unp_head *heads[] = { &unp_dhead, &unp_shead, NULL }; struct unp_head **head; - struct file **unref; + struct file *f, **unref; struct unpcb *unp; - int i; + int i, total; unp_taskcount++; UNP_LIST_LOCK(); @@ -2085,33 +2085,37 @@ unp_gc(__unused void *arg, int pending) * Iterate looking for sockets which have been specifically marked * as as unreachable and store them locally. */ + UNP_LINK_RLOCK(); UNP_LIST_LOCK(); - for (i = 0, head = heads; *head != NULL; head++) + for (total = 0, head = heads; *head != NULL; head++) LIST_FOREACH(unp, *head, unp_link) - if (unp->unp_gcflag & UNPGC_DEAD) { - unref[i++] = unp->unp_file; - fhold(unp->unp_file); - KASSERT(unp->unp_file != NULL, - ("unp_gc: Invalid unpcb.")); - KASSERT(i <= unp_unreachable, + if ((unp->unp_gcflag & UNPGC_DEAD) != 0) { + f = unp->unp_file; + if (unp->unp_msgcount == 0 || f == NULL || + f->f_count != unp->unp_msgcount) + continue; + unref[total++] = f; + fhold(f); + KASSERT(total <= unp_unreachable, ("unp_gc: incorrect unreachable count.")); } UNP_LIST_UNLOCK(); + UNP_LINK_RUNLOCK(); /* * Now flush all sockets, free'ing rights. This will free the * struct files associated with these sockets but leave each socket * with one remaining ref. */ - for (i = 0; i < unp_unreachable; i++) + for (i = 0; i < total; i++) sorflush(unref[i]->f_data); /* * And finally release the sockets so they can be reclaimed. */ - for (i = 0; i < unp_unreachable; i++) + for (i = 0; i < total; i++) fdrop(unref[i], NULL); - unp_recycled += unp_unreachable; + unp_recycled += total; free(unref, M_TEMP); }