zfsonlinux/zfs — pull request #2250 by ryao (2014-04-09 20:35:10+00:00)
Title: Improve dirty page writeout performance

This refactors ->writepages and ->writepage to reduce divergence with
other Open ZFS platforms while improving performance.

->writepages has been refactored to call zfs_range_lock() once per call.
Each zfs_range_lock() does its own memory allocation and various tree
operations, so making it occur only once reduces the computational
complexity of writepages, by at least a factor of log(N) where N is the
number of pages. This brings us to parity with other Open ZFS
implementations and also avoids significant virtual memory contention
that is prevalent in Linux's vmalloc(). In addition, we now pass
WB_SYNC_NONE to write_cache_pages. This moves responsibility for
ensuring synchronous semantics entirely to zil_commit(), where it should
have been in the first place. It also eliminates an opportunity for
concurrent threads to block each other on writeback.

->writepage has been refactored to permit the changes to ->writepages.
Situations where it is told to write out an invalidated page is now
properly handled by ignoring them. This avoids a theoretical NULL
pointer dereference.

These changes substantially improve 32-thread 4K randomwrite IO on a RAM
disk in filebench's randomwrite benchmark. This has been tested with the
following commands on a boot that passed ramdisk_size=8388604 to the
kernel commandline:

modprobe loop
losetup loop0 /dev/ram0
zpool create -o ashift=12 -O recordsize=4K test /dev/loop0
zpool export test
losetup -D
zpool import -d /dev test

filebench << END
load randomwrite
set \$dir=/test
set \$nthreads=32
set \$iosize=4096
run 60
END

zpool destroy test

Previous tests on Gentoo Linux using a kernel compiled from CentOS
2.6.32-431.11.2.el6.x86_64 kernel with the default .config showed single
threaded performance at roughly 10k to 11k IOPS with 32-thread
performance at 5k-6k in this benchmark. Tests with this patch show a
performance improvement to 15k to 17k in the 32-thread case. These tests
were conducted on a single processor Xeon E5-2620 with 64GB of RAM.

Signed-off-by: Richard Yao