Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Jun 2015 10:21:34 -0700
From:      Adrian Chadd <adrian.chadd@gmail.com>
To:        Ed Maste <emaste@freebsd.org>
Cc:        "src-committers@freebsd.org" <src-committers@freebsd.org>,  "svn-src-all@freebsd.org" <svn-src-all@freebsd.org>,  "svn-src-head@freebsd.org" <svn-src-head@freebsd.org>
Subject:   Re: svn commit: r284928 - head/usr.bin/ar
Message-ID:  <CAJ-Vmon9335Ayv_C76v6-X1r8P0WEyLMSVUACUN8oGyzK6KdfA@mail.gmail.com>
In-Reply-To: <201506291348.t5TDmiZG039322@svn.freebsd.org>
References:  <201506291348.t5TDmiZG039322@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Is this potentially an issue for other applications? Why is it such a
big issue for ar?


-a


On 29 June 2015 at 06:48, Ed Maste <emaste@freebsd.org> wrote:
> 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));
>



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