DragonFly commits List (threaded) for 2010-09
git: Kernel - Implement swapoff
Author: Matthew Dillon <firstname.lastname@example.org>
Date: Mon Sep 13 16:41:40 2010 -0700
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 <email@example.com>
Summary of changes:
include/unistd.h | 1 +
lib/libc/sys/Makefile.inc | 1 +
lib/libc/sys/swapon.2 | 86 +++++++---
lib/libkvm/kvm_getswapinfo.c | 401 ++++++++++++++++--------------------------
sbin/swapon/Makefile | 7 +
sbin/swapon/swapon.8 | 169 ++++++++++++++----
sbin/swapon/swapon.c | 285 ++++++++++++++++++++++++++----
sys/kern/subr_blist.c | 143 +++++++++++++++
sys/kern/syscalls.master | 1 +
sys/sys/blist.h | 2 +
sys/sys/conf.h | 1 +
sys/vm/swap_pager.c | 98 ++++++++++-
sys/vm/swap_pager.h | 2 +
sys/vm/vm_fault.c | 5 +
sys/vm/vm_map.h | 1 +
sys/vm/vm_swap.c | 169 +++++++++++++++++-
16 files changed, 1022 insertions(+), 350 deletions(-)
DragonFly BSD source repository