swap_pager_reserve bug (not arm depend and any version of FreeBSD)
Daisuke Aoyama
aoyama at peach.ne.jp
Sat Nov 8 16:58:35 UTC 2014
Hello,
In short, I get a bug of kernel code. swap_pager_reserve never free unused area.
Because of this, you can't clean up correctly by vm_object_deallocate.
The part of my code in the kernel module is like this:
vm_object_t obj;
obj = vm_pager_allocate(OBJT_SWAP, NULL, 32768, VM_PROT_DEFAULT, 0, NULL);
swap_pager_reserve(obj, 0, OFF_TO_IDX(32768));
(using...)
vm_object_deallocate(obj);
Allocate 32KB as swap object, then reserve all and deallocate it after using.
In this case, swap_pager_reserve take 128KB(32xPAGE_SIZE) swap on it,
but vm_object_deallocate will free only 32KB.
Probably, left 96KB will cause a kernel panic when you remove(swapoff) the swap device
(including shutdown).
I think this is a rare case but don't want get a panic...
Here is my test patch. If you have more better code, please help me.
Currently, I've tested on 9.3 amd64 and 11-current arm RPi.
Index: swap_pager.c
===================================================================
--- swap_pager.c (revision 274088)
+++ swap_pager.c (working copy)
@@ -858,7 +858,7 @@
VM_OBJECT_WLOCK(object);
while (size) {
if (n == 0) {
- n = BLIST_MAX_ALLOC;
+ n = min(BLIST_MAX_ALLOC, size); /* happy with small size */
while ((blk = swp_pager_getswapspace(n)) == SWAPBLK_NONE) {
n >>= 1;
if (n == 0) {
Thanks,
--
Daisuke Aoyama
More information about the freebsd-arm
mailing list