Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 8 Oct 2002 10:45:46 -0700 (PDT)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        David Schultz <dschultz@uclink.Berkeley.EDU>
Cc:        Peter Wemm <peter@wemm.org>, Sean Kelly <smkelly@zombie.org>, hackers@FreeBSD.ORG
Subject:   Re: swapoff?
Message-ID:  <200210081745.g98Hjkam078883@apollo.backplane.com>
References:  <20020713071911.GA1558@HAL9000.wox.org> <20020713073404.9869A3811@overcee.wemm.org> <20020713115746.GA2162@HAL9000.wox.org> <200207131636.g6DGaoqh081285@apollo.backplane.com> <20021007153845.GA371@HAL9000.homeunix.com> <200210072347.g97Nl3Zo049415@apollo.backplane.com> <20021008113614.GA319@HAL9000.homeunix.com>

next in thread | previous in thread | raw e-mail | index | archive | help

:...
:detect when there is insufficient space.  (I actually thought it
:was right the first time.)  Can you see anything obviously wrong
:with my math?
:
:The code works fine in all of my tests, except that calling
:swapoff() when the system is under heavy paging load and has
:multiple swap devices sometimes leads to a few pages being missed
:by the scan.  I think the problem is that some process allocates
:some swap and starts paging out just before the device is marked
:as off-limits.  Am I missing a simple solution to this problem?
:(For now, I kludge around the issue by rescanning if there are
:still blocks remaining.)

    Ok, I think the problem is in swap_pager_swapoff() and
    swp_pager_force_pagein().  Another process may be manipulating
    the swblock (or a prior swblock) while swp_pager_force_pagein()
    is blocked.

    In fact, the swap block can be ripped out from under
    swap_pager_swapoff() if swp_pager_force_pagein() blocks.  i.e.
    the 'swap' structure may be invalid after you call
    swp_pager_force_pagein().

    This is a sticky situation because both the VM object and the
    swblocks may be manipulated by other processes when you block.  I
    think what you need to try to do is this (it's a mess, if you can think
    of a better solution definitely go another route!)

    while ((swap = *pswap) != NULL) {
	if (anything_is_swapped_to_the_device) {
	    try_to_page_it_all_in
	    (note that the swblock structure is invalid the moment you
	    block, so swp_pager_force_pagein() should be given
	    the whole range).
	    /* fall through to retry */
	} else if (the_related_object_pip_count_is_not_zero) {
	    vm_object_pip_sleep(...)
	    /* fall through to retry */
	} else if (swap->swb_count <= 0) {
	    free the swap block
	    *pswap = swap->swb_hnext;
	}
    }

					-Matt
					Matthew Dillon 
					<dillon@backplane.com>

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




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