svn commit: r284928 - head/usr.bin/ar

Ed Maste emaste at FreeBSD.org
Mon Jun 29 13:48:45 UTC 2015


Author: emaste
Date: Mon Jun 29 13:48:44 2015
New Revision: 284928
URL: https://svnweb.freebsd.org/changeset/base/284928

Log:
  speed up ar(1) on UFS file systems
  
  Fault in the buffer prior to writing to workaround poor performance due
  to interaction with kernel fs deadlock avoidance code. See the comment
  prior to vn_io_fault_doio() in sys/kern/vfs_vnops.c for details of the
  issue.
  
  On my stable/10 desktop with a 16MB obj.o and "ar r out.a obj.o" I see
  the following run times (seconds):
  
  x ar.r284891
  + ar.patched
  +----------------------------------------------------------------------+
  |+                                                                     |
  |+                                                                    x|
  |+                                                                   xx|
  |A                                                                   |A|
  +----------------------------------------------------------------------+
      N         Min          Max        Median           Avg        Stddev
  x   3       1.307        1.321         1.315     1.3143333  0.0070237692
  +   3       0.020        0.023         0.022   0.021666667  0.0015275252
  Difference at 95.0% confidence
          -1.29267 +/- 0.0115203
          -98.3515% +/- 0.876513%
          (Student's t, pooled s = 0.00508265)
  
  Thanks to kib for diagnosing and explaining the issue and suggesting
  the workaround.
  
  Reviewed by:	eadler, kib
  MFC after:	1 week
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D2933

Modified:
  head/usr.bin/ar/write.c

Modified: head/usr.bin/ar/write.c
==============================================================================
--- head/usr.bin/ar/write.c	Mon Jun 29 13:06:24 2015	(r284927)
+++ head/usr.bin/ar/write.c	Mon Jun 29 13:48:44 2015	(r284928)
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #include <stdlib.h>
 #include <string.h>
 #include <sysexits.h>
+#include <unistd.h>
 
 #include "ar.h"
 
@@ -61,6 +62,7 @@ static void	create_symtab_entry(struct b
 static void	free_obj(struct bsdar *bsdar, struct ar_obj *obj);
 static void	insert_obj(struct bsdar *bsdar, struct ar_obj *obj,
 		    struct ar_obj *pos);
+static void	prefault_buffer(const char *buf, size_t s);
 static void	read_objs(struct bsdar *bsdar, const char *archive,
 		    int checkargv);
 static void	write_archive(struct bsdar *bsdar, char mode);
@@ -551,11 +553,35 @@ write_cleanup(struct bsdar *bsdar)
 }
 
 /*
+ * Fault in the buffer prior to writing as a workaround for poor performance
+ * due to interaction with kernel fs deadlock avoidance code. See the comment
+ * above vn_io_fault_doio() in sys/kern/vfs_vnops.c for details of the issue.
+ */
+static void
+prefault_buffer(const char *buf, size_t s)
+{
+	volatile const char *p;
+	size_t page_size;
+
+	if (s == 0)
+		return;
+	page_size = sysconf(_SC_PAGESIZE);
+	for (p = buf; p < buf + s; p += page_size)
+		*p;
+	/*
+	 * Ensure we touch the last page as well, in case the buffer is not
+	 * page-aligned.
+	 */
+	*(volatile const char *)(buf + s - 1);
+}
+
+/*
  * Wrapper for archive_write_data().
  */
 static void
 write_data(struct bsdar *bsdar, struct archive *a, const void *buf, size_t s)
 {
+	prefault_buffer(buf, s);
 	if (archive_write_data(a, buf, s) != (ssize_t)s)
 		bsdar_errc(bsdar, EX_SOFTWARE, 0, "%s",
 		    archive_error_string(a));


More information about the svn-src-all mailing list