Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 17 Jun 2009 20:56:03 +0000 (UTC)
From:      Brooks Davis <brooks@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r194398 - projects/ngroups/sys/kern
Message-ID:  <200906172056.n5HKu3XA087973@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: brooks
Date: Wed Jun 17 20:56:03 2009
New Revision: 194398
URL: http://svn.freebsd.org/changeset/base/194398

Log:
  Use crsetgroups() in crcopy().
  
  When a user has more than a page worth of groups, switch from power of
  two allocation to allocating the number of pages actually required.  It
  seems more likely that a process will need a non-power-of-two number of
  pages than that they will use many thousands of groups and add them one
  at a time (in which case there would be no difference in number of
  allocations until they use more than 3072 groups and the context switch
  overhead would likely swamp the extra allocations).

Modified:
  projects/ngroups/sys/kern/kern_prot.c

Modified: projects/ngroups/sys/kern/kern_prot.c
==============================================================================
--- projects/ngroups/sys/kern/kern_prot.c	Wed Jun 17 20:30:51 2009	(r194397)
+++ projects/ngroups/sys/kern/kern_prot.c	Wed Jun 17 20:56:03 2009	(r194398)
@@ -1856,9 +1856,7 @@ crcopy(struct ucred *dest, struct ucred 
 	bcopy(&src->cr_startcopy, &dest->cr_startcopy,
 	    (unsigned)((caddr_t)&src->cr_endcopy -
 		(caddr_t)&src->cr_startcopy));
-	crextend(dest, src->cr_agroups);
-	memcpy(dest->cr_groups, src->cr_groups,
-	    src->cr_ngroups * sizeof(gid_t));
+	crsetgroups(dest, src->cr_ngroups, src->cr_groups);
 	uihold(dest->cr_uidinfo);
 	uihold(dest->cr_ruidinfo);
 	prison_hold(dest->cr_prison);
@@ -1959,17 +1957,23 @@ crextend(struct ucred *cr, int n)
 
 	/*
 	 * We extend by 2 each time since we're using a power of two
-	 * allocator.
-	 * XXX: it probably makes more sense to right-size the
-	 * allocation if we need more than a page.
+	 * allocator until we need enough groups to fill a page.
+	 * Once we're allocating multiple pages, only allocate as many
+	 * as we actually need.  The case of processes needing a
+	 * non-power of two number of pages seems more likely than
+	 * a real world process that adds thousands of groups one at a
+	 * time.
 	 */
-	if (cr->cr_agroups)
-		cnt = cr->cr_agroups * 2;
-	else
-		cnt = MINALLOCSIZE / sizeof(gid_t);
-
-	while (cnt < n)
-		cnt *= 2;
+	if ( n < PAGE_SIZE / sizeof(gid_t) ) {
+		if (cr->cr_agroups == 0)
+			cnt = MINALLOCSIZE / sizeof(gid_t);
+		else
+			cnt = cr->cr_agroups * 2;
+
+		while (cnt < n)
+			cnt *= 2;
+	} else
+		cnt = roundup2(n, PAGE_SIZE / sizeof(gid_t));
 
 	/* Free the old array. */
 	if (cr->cr_groups)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906172056.n5HKu3XA087973>