This patch improves the performance of sendfile(2). It adds a hash
authorJeffrey Hsu <hsu@dragonflybsd.org>
Wed, 10 Dec 2003 22:26:19 +0000 (22:26 +0000)
committerJeffrey Hsu <hsu@dragonflybsd.org>
Wed, 10 Dec 2003 22:26:19 +0000 (22:26 +0000)
commitdfbcf5a390e68e4a5fb3883c755b9b9b92bac473
tree940315829984ad805598e3bdecf4775eac620daf
parenta9b6669339ea74d477f570f0bd9f77a07ccb1d1a
This patch improves the performance of sendfile(2).  It adds a hash
table of active sf_buf mappings to ensure there is exactly one
(ref-counted) sf_buf for each vm_page.  This saves on the number
of sf_bufs used when sendfile(2) sends the same file over and over
again to multiple connections simultaneously.  It also does lazy
updates on the hw page table when a sf_buf ref count goes to zero,
placing them on a freelist instead, in effect, making sf_bufs a
cache of virtual-to-physical translations with LRU replacement on
the inactive sf_bufs.  Finally, it does a wakeup_one() instead of
a broadcast wakeup() when a free sf_buf becomes available.

This patch roughly corresponds to FreeBSD revs 1.219 and 1.220 of
sys/i386/i386/vm_machdep.c:

  revision 1.219
  date: 2003/11/17 18:22:24;  author: alc;  state: Exp;  lines: +48 -26
  Change the i386's sf_buf implementation so that it never allocates
  more than one sf_buf for one vm_page.  To accomplish this, we add
  a global hash table mapping vm_pages to sf_bufs and a reference
  count to each sf_buf.  (This is similar to the patches for RELENG_4
  at http://www.cs.princeton.edu/~yruan/debox/.)

  For the uninitiated, an sf_buf is nothing more than a kernel virtual
  address that is used for temporary virtual-to-physical mappings by
  sendfile(2) and zero-copy sockets.  As such, there is no reason for
  one vm_page to have several sf_bufs mapping it.  In fact, using more
  than one sf_buf for a single vm_page increases the likelihood that
  sendfile(2) blocks, hurting throughput.
  (See http://www.cs.princeton.edu/~yruan/debox/.)

  revision 1.220
  date: 2003/12/07 22:49:25;  author: alc;  state: Exp;  lines: +10 -9
  Don't remove the virtual-to-physical mapping when an sf_buf is freed.
  Instead, allow the mapping to persist, but add the sf_buf to a free list.
  If a later sendfile(2) or zero-copy send resends the same physical page,
  perhaps with the same or different contents, then the mapping overhead is
  avoided and the sf_buf is simply removed from the free list.

  In other words, the i386 sf_buf implementation now behaves as a cache of
  virtual-to-physical translations using an LRU replacement policy on
  inactive sf_bufs.  This is similar in concept to a part of
  http://www.cs.princeton.edu/~yruan/debox/ patch, but much simpler in
  implementation.  Note: none of this is required on alpha, amd64, or ia64.
  They now use their direct virtual-to-physical mapping to avoid any
  emphemeral mapping overheads in their sf_buf implementations.

Reviewed by: dillon
sys/kern/uipc_syscalls.c
sys/sys/socketvar.h