NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/41765: kernel panic while allocating swap space pages



>Number:         41765
>Category:       kern
>Synopsis:       kernel panic while allocating swap space pages
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jul 22 12:00:00 +0000 2009
>Originator:     Wolfgang Stukenbrock
>Release:        NetBSD 4.0
>Organization:
Dr. Nagler & Company GmbH
        
>Environment:
        
        
System: NetBSD s012 4.0 NetBSD 4.0 (NSW-S012) #9: Fri Mar 13 12:31:52 CET 2009 
wgstuken@s012:/usr/src/sys/arch/amd64/compile/NSW-S012 amd64
Architecture: x86_64
Machine: amd64
>Description:
        There is a limitation in the blist implementation in kern/subr_blist.c.
        It cannot allocate more pages at once as specified by BLIST_BMAP_RADIX.
        For this purpose there is a definition BLIST_MAX_ALLOC in blist.h.
        In uvm/uvm_swap.c uvm_swap_alloc() there is no check against this 
number and if
        the e.g. the pagedeamon tries to swap out more, the system will panic 
with
        "panic: blist_meta_alloc: allocation too large".
        Remark: this will only happen if MAXPHYS is larger than the space in 
BLIST_MAX_ALLOC
        pages. Normaly this is not the case (64k < 128k). We have changed 
MAXPHYS on the
        system to something more suitable for a backup server, because 64k 
blocksize is
        much to small - we use 1MB.
>How-To-Repeat:
        Compile a kernel with MAXPHYS larger than 128k and allocate a large 
amount of memory
        in tmpfs. The system will try to allocate pages for MAXPHYS Kbyte and 
will panic.
>Fix:
        The fix is easy. Just check the number of pages in uvm_swap_alloc() 
prio calling blist_alloc().
        Due to the fact, that umv_swap_alloc() may fail and the caller must be 
able to handle this,
        we can abort the allocation if we may not return a smaller number of 
pages as requested.
        Otherwise we just clamp it to BLIST_MAX_ALLOC.
        The following fix runs fine on our system without any problems with 
pagedeamon anymore.
        remark: I assume, that I can change *nslots without allocating the 
uvm.swap_data_lock lock.
        Otherwise this code must be moved behind the simple_lock(), that comes 
two lines below
        the unified diff and the lock must be freed prior the "return 0;".

        Of cause it would be better to fix the allocation problem in 
subr_blist.c, but this is
        a small and effectiv work-around for the allocation problem.

        The following patch should be applyed to uvm/uvm_swap.c:
--- uvm_swap.c  2009/07/22 11:30:38     1.1
+++ uvm_swap.c  2009/07/22 11:39:44
@@ -1447,6 +1447,14 @@
        if (uvmexp.nswapdev < 1)
                return 0;
 
+       if (*nslots > BLIST_MAX_ALLOC) {
+               /* avoid panic in blist_alloc() below - cannot handle this 
amount of blocks
+                * see comment in subr_blist.c
+                */
+               if (!lessok) return 0; /* sorry - cannot handle this ... */
+               *nslots = BLIST_MAX_ALLOC;
+       }
+
        /*
         * lock data lock, convert slots into blocks, and enter loop
         */

>Unformatted:
        
        


Home | Main Index | Thread Index | Old Index