Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 9 Nov 2014 01:58:21 +0900
From:      "Daisuke Aoyama" <aoyama@peach.ne.jp>
To:        <freebsd-arm@freebsd.org>
Subject:   swap_pager_reserve bug (not arm depend and any version of FreeBSD)
Message-ID:  <A9FF20484A844727B5D6DD3A03A94999@ad.peach.ne.jp>

next in thread | raw e-mail | index | archive | help
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
 




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?A9FF20484A844727B5D6DD3A03A94999>