Kernel - Implement swapoff
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 13 Sep 2010 23:41:40 +0000 (16:41 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 13 Sep 2010 23:41:40 +0000 (16:41 -0700)
commit9f3543c6db8d588b11ad6d877f92bb3a20d7d0f4
tree1745c2c5bda7f4dab56a3afaffee6f5afe220be5
parentd421a9d3f1b7349490af304dcf356d81eeaa0177
Kernel - Implement swapoff

* Generally port of the swapoff implementation from FreeBSD to DragonFly,
  with major modifications.

  Modifications to handle swapcache issues (VCHR vnodes with VM objects
  can have swap associations for swapcache).

* Libkvm changes

    So there are two problems with libkvm. The first is not really
    swapoff-related - the new sysctl way of reporting numbers bzero'es
    swap_max elements in the given swap_ary array. This is in contrast to
    the old kvm way, which bzero'es only those elements that will be
    actually filled. So if we have 3 swap devices and swap_max is 16, then
    the sysctl code will zero out all 16 elements and fill the first 4,
    while the old kvm code will zero out exactly 4 elements and fill them.
    Since we want to keep API stable (I learned it the hard way :-) ) I
    think this fix can be separated out and go to master as a bugfix to the
    newly introduced sysctl way of reporting things.

    The second problem only shows up if we introduce a swapoff syscall
    and enforce using of the old kvm way. It was written with the
    assumption that swap devices can only be added, not removed - it
    assumes than if I have a swap device with index 3, 4 swap
    devices are active. This is not true with swapoff - I can swapon
    A, B, C and D, then swapoff B and C and here we are - I have an
    active swap device with index 3, but only 2 devices are active.

    It turned out to be easier to just rewrite it (based on sysctl way),
    because that assumption was rather deep and everything was based on it.
    Since along with sysctl way per-device swap accounting was introduced,
    the kvm way now uses it instead of scanning blist.

    Which brings us to the last change - blist scanning code is now used
    only for debugging purposes. getswapinfo_radix() is now called only if
    DUMP_TREE flag is set. Pieces that touched swap_ary entries are removed,
    swap_ary and swap_max are no longer passed to scanning code.

    After all that both ways are now working correctly with the regards to
    the swapoff call and the old kvm way (the behaviour is exactly the same,
    all boudary cases were tested, API remains the same). The only (minor)
    difference is that swapctl numbers are a little bit bigger than kvm way
    ones. Thats because kvm way subtracts dmmax (the assumption is that the
    first dmmax is never allocated), and sysctl way does not. I tried to fix
    this, but it turns out that we need to introduce a dmmax sysctl for that.
    So if you want I can add it, but I want to hear from you first (both on
    this thing and my changes to libkvm in general).

* Userspace.  Add swapoff & adjust manual pages.

Note: Bounty project ($300)
Submitted-by: Ilya Dryomov <idryomov@gmail.com>
16 files changed:
include/unistd.h
lib/libc/sys/Makefile.inc
lib/libc/sys/swapon.2
lib/libkvm/kvm_getswapinfo.c
sbin/swapon/Makefile
sbin/swapon/swapon.8
sbin/swapon/swapon.c
sys/kern/subr_blist.c
sys/kern/syscalls.master
sys/sys/blist.h
sys/sys/conf.h
sys/vm/swap_pager.c
sys/vm/swap_pager.h
sys/vm/vm_fault.c
sys/vm/vm_map.h
sys/vm/vm_swap.c