sdp = CIRCLEQ_NEXT(sdp, swd_next)) { if (sdp->swd_flags & SWF_FAKE) continue;
sdp = CIRCLEQ_NEXT(sdp, swd_next))
static struct swapdev	*swapdrum_getsdp __P((int));static struct swapdev	*swaplist_find __P((struct vnode *, int));static void		 swaplist_insert __P((struct swapdev *,					     struct swappri *, int));static void		 swaplist_trim __P((void));static int swap_on __P((struct proc *, struct swapdev *));static int swap_off __P((struct proc *, struct swapdev *));static void sw_reg_strategy __P((struct swapdev *, struct buf *, int));static void sw_reg_iodone __P((struct buf *));static void sw_reg_start __P((struct swapdev *));static int uvm_swap_io __P((struct vm_page **, int, int, int));static void swapmount __P((void));#ifdef UVM_SWAP_ENCRYPT/* for swap encrypt */boolean_t uvm_swap_allocpages __P((struct vm_page **, int));void uvm_swap_markdecrypt __P((struct swapdev *, int, int, int));boolean_t uvm_swap_needdecrypt __P((struct swapdev *, int));void uvm_swap_initcrypt __P((struct swapdev *, int));#endif/* * uvm_swap_init: init the swap system data structures and locks * * => called at boot time from init_main.c after the filesystems *	are brought up (which happens after uvm_init()) */voiduvm_swap_init(){	UVMHIST_FUNC("uvm_swap_init");	UVMHIST_CALLED(pdhist);	/*	 * first, init the swap list, its counter, and its lock.	 * then get a handle on the vnode for /dev/drum by using	 * the its dev_t number ("swapdev", from MD conf.c).	 */	LIST_INIT(&swap_priority);	uvmexp.nswapdev = 0;	lockinit(&swap_syscall_lock, PVM, "swapsys", 0, 0);	simple_lock_init(&uvm.swap_data_lock);	if (!swapdev_vp && bdevvp(swapdev, &swapdev_vp))		panic("uvm_swap_init: can't get vnode for swap device");	/*	 * create swap block resource map to map /dev/drum.   the range	 * from 1 to INT_MAX allows 2 gigablocks of swap space.  note	 * that block 0 is reserved (used to indicate an allocation	 * failure, or no allocation).	 */	swapmap = extent_create("swapmap", 1, INT_MAX,				M_VMSWAP, 0, 0, EX_NOWAIT);	if (swapmap == 0)		panic("uvm_swap_init: extent_create failed");	/*	 * allocate pools for structures used for swapping to files.	 */	pool_init(&vndxfer_pool, sizeof(struct vndxfer), 0, 0, 0, "swp vnx",			    0, NULL, NULL, 0);	pool_init(&vndbuf_pool, sizeof(struct vndbuf), 0, 0, 0, "swp vnd", 0,			    NULL, NULL, 0);	/*	 * Setup the initial swap partition	 */	swapmount();	/*	 * done!	 */	UVMHIST_LOG(pdhist, "<- done", 0, 0, 0, 0);}#ifdef UVM_SWAP_ENCRYPTvoiduvm_swap_initcrypt_all(void){	struct swapdev *sdp;	struct swappri *spp;	simple_lock(&uvm.swap_data_lock);	for (spp = swap_priority.lh_first; spp != NULL;	     spp = spp->spi_swappri.le_next) {		for (sdp = spp->spi_swapdev.cqh_first;		     sdp != (void *)&spp->spi_swapdev;		     sdp = sdp->swd_next.cqe_next)			if (sdp->swd_decrypt == NULL)				uvm_swap_initcrypt(sdp, sdp->swd_npages);	}	simple_unlock(&uvm.swap_data_lock);}voiduvm_swap_initcrypt(struct swapdev *sdp, int npages){	/*	 * keep information if a page needs to be decrypted when we get it	 * from the swap device.	 * We cannot chance a malloc later, if we are doing ASYNC puts,	 * we may not call malloc with M_WAITOK.  This consumes only	 * 8KB memory for a 256MB swap partition.	 */	sdp->swd_decrypt = malloc(SWD_DCRYPT_SIZE(npages), M_VMSWAP, M_WAITOK);	memset(sdp->swd_decrypt, 0, SWD_DCRYPT_SIZE(npages));	sdp->swd_keys = malloc((npages >> SWD_KEY_SHIFT) * sizeof(struct swap_key),			       M_VMSWAP, M_WAITOK);	memset(sdp->swd_keys, 0, (npages >> SWD_KEY_SHIFT) * sizeof(struct swap_key));	sdp->swd_nkeys = 0;}boolean_tuvm_swap_allocpages(struct vm_page **pps, int npages){	int i, s;	int minus, reserve;	boolean_t fail;	/* Estimate if we will succeed */	s = uvm_lock_fpageq();	minus = uvmexp.free - npages;	reserve = uvmexp.reserve_kernel;	fail = uvmexp.free - npages < uvmexp.reserve_kernel;	uvm_unlock_fpageq(s);	if (fail)		return FALSE;	/* Get new pages */	for (i = 0; i < npages; i++) {		pps[i] = uvm_pagealloc(NULL, 0, NULL, 0);		if (pps[i] == NULL)			break;	}	/* On failure free and return */	if (i < npages) {		uvm_swap_freepages(pps, i);		return FALSE;	}	return TRUE;}voiduvm_swap_freepages(struct vm_page **pps, int npages){	int i;	uvm_lock_pageq();	for (i = 0; i < npages; i++)		uvm_pagefree(pps[i]);	uvm_unlock_pageq();}/* * Mark pages on the swap device for later decryption */voiduvm_swap_markdecrypt(struct swapdev *sdp, int startslot, int npages,		     int decrypt){	int pagestart, i;	int off, bit;		if (!sdp)		return;	pagestart = startslot - sdp->swd_drumoffset;	for (i = 0; i < npages; i++, pagestart++) {		off = SWD_DCRYPT_OFF(pagestart);		bit = SWD_DCRYPT_BIT(pagestart);		if (decrypt)			/* pages read need decryption */			sdp->swd_decrypt[off] |= 1 << bit;		else 			/* pages read do not need decryption */			sdp->swd_decrypt[off] &= ~(1 << bit);	}}/* * Check if the page that we got from disk needs to be decrypted */boolean_tuvm_swap_needdecrypt(struct swapdev *sdp, int off){	if (!sdp)		return FALSE;	off -= sdp->swd_drumoffset;	return sdp->swd_decrypt[SWD_DCRYPT_OFF(off)] & (1 << SWD_DCRYPT_BIT(off)) ?		TRUE : FALSE;}#endif /* UVM_SWAP_ENCRYPT *//* * swaplist functions: functions that operate on the list of swap * devices on the system. *//* * swaplist_insert: insert swap device "sdp" into the global list * * => caller must hold both swap_syscall_lock and uvm.swap_data_lock * => caller must provide a newly malloc'd swappri structure (we will *	FREE it if we don't need it... this it to prevent malloc blocking *	here while adding swap) */static voidswaplist_insert(sdp, newspp, priority)	struct swapdev *sdp;	struct swappri *newspp;	int priority;{	struct swappri *spp, *pspp;	UVMHIST_FUNC("swaplist_insert"); UVMHIST_CALLED(pdhist);	/*	 * find entry at or after which to insert the new device.	 */	for (pspp = NULL, spp = LIST_FIRST(&swap_priority); spp != NULL;	     spp = LIST_NEXT(spp, spi_swappri)) {		if (priority <= spp->spi_priority)			break;		pspp = spp;	}	/*	 * new priority?	 */	if (spp == NULL || spp->spi_priority != priority) {		spp = newspp;  /* use newspp! */		UVMHIST_LOG(pdhist, "created new swappri = %d",			    priority, 0, 0, 0);		spp->spi_priority = priority;		CIRCLEQ_INIT(&spp->spi_swapdev);		if (pspp)			LIST_INSERT_AFTER(pspp, spp, spi_swappri);		else			LIST_INSERT_HEAD(&swap_priority, spp, spi_swappri);	} else {	  	/* we don't need a new priority structure, free it */		FREE(newspp, M_VMSWAP);	}	/*	 * priority found (or created).   now insert on the priority's	 * circleq list and bump the total number of swapdevs.	 */	sdp->swd_priority = priority;	CIRCLEQ_INSERT_TAIL(&spp->spi_swapdev, sdp, swd_next);	uvmexp.nswapdev++;}/* * swaplist_find: find and optionally remove a swap device from the *	global list. * * => caller must hold both swap_syscall_lock and uvm.swap_data_lock * => we return the swapdev we found (and removed) */static struct swapdev *swaplist_find(vp, remove)	struct vnode *vp;	boolean_t remove;{	struct swapdev *sdp;	struct swappri *spp;	/*	 * search the lists for the requested vp	 */	for (spp = LIST_FIRST(&swap_priority); spp != NULL;	     spp = LIST_NEXT(spp, spi_swappri)) {		for (sdp = CIRCLEQ_FIRST(&spp->spi_swapdev);		     sdp != (void *)&spp->spi_swapdev;		     sdp = CIRCLEQ_NEXT(sdp, swd_next))			if (sdp->swd_vp == vp) {				if (remove) {					CIRCLEQ_REMOVE(&spp->spi_swapdev,					    sdp, swd_next);					uvmexp.nswapdev--;				}				return(sdp);			}	}	return (NULL);}/* * swaplist_trim: scan priority list for empty priority entries and kill *	them. * * => caller must hold both swap_syscall_lock and uvm.swap_data_lock */static voidswaplist_trim(){	struct swappri *spp, *nextspp;	for (spp = LIST_FIRST(&swap_priority); spp != NULL; spp = nextspp) {		nextspp = LIST_NEXT(spp, spi_swappri);		if (CIRCLEQ_FIRST(&spp->spi_swapdev) !=		    (void *)&spp->spi_swapdev)			continue;		LIST_REMOVE(spp, spi_swappri);		free(spp, M_VMSWAP);	}}/* * swapdrum_getsdp: given a page offset in /dev/drum, convert it back *	to the "swapdev" that maps that section of the drum. * * => each swapdev takes one big contig chunk of the drum * => caller must hold uvm.swap_data_lock */static struct swapdev *swapdrum_getsdp(pgno)	int pgno;{	struct swapdev *sdp;	struct swappri *spp;	for (spp = LIST_FIRST(&swap_priority); spp != NULL;	     spp = LIST_NEXT(spp, spi_swappri))		for (sdp = CIRCLEQ_FIRST(&spp->spi_swapdev);		     sdp != (void *)&spp->spi_swapdev;		     sdp = CIRCLEQ_NEXT(sdp, swd_next)) {			if (sdp->swd_flags & SWF_FAKE)				continue;			if (pgno >= sdp->swd_drumoffset &&			    pgno < (sdp->swd_drumoffset + sdp->swd_drumsize)) {				return sdp;			}		}	return NULL;}