From 89b005fc27d306fad29f5e750c032358c760fd7d Mon Sep 17 00:00:00 2001 From: chs Date: Wed, 27 Dec 2000 09:17:04 +0000 Subject: [PATCH] when we fail to allocate anons to represent new swap space, just return an error rather than panicing. --- sys/uvm/uvm_anon.c | 20 ++++++++++---------- sys/uvm/uvm_anon.h | 4 ++-- sys/uvm/uvm_swap.c | 27 ++++++++++++++++++--------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/sys/uvm/uvm_anon.c b/sys/uvm/uvm_anon.c index d649cc684718..f69856031d05 100644 --- a/sys/uvm/uvm_anon.c +++ b/sys/uvm/uvm_anon.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_anon.c,v 1.10 2000/11/25 06:27:59 chs Exp $ */ +/* $NetBSD: uvm_anon.c,v 1.11 2000/12/27 09:17:04 chs Exp $ */ /* * @@ -88,7 +88,7 @@ uvm_anon_init() * * => swap_syscall_lock should be held (protects anonblock_list). */ -void +int uvm_anon_add(count) int count; { @@ -102,17 +102,16 @@ uvm_anon_add(count) simple_unlock(&uvm.afreelock); if (needed <= 0) { - return; + return 0; } - - MALLOC(anonblock, void *, sizeof(*anonblock), M_UVMAMAP, M_WAITOK); anon = (void *)uvm_km_alloc(kernel_map, sizeof(*anon) * needed); - - /* XXX Should wait for VM to free up. */ - if (anonblock == NULL || anon == NULL) { - printf("uvm_anon_add: can not allocate %d anons\n", needed); - panic("uvm_anon_add"); + if (anon == NULL) { + simple_lock(&uvm.afreelock); + uvmexp.nanonneeded -= count; + simple_unlock(&uvm.afreelock); + return ENOMEM; } + MALLOC(anonblock, void *, sizeof(*anonblock), M_UVMAMAP, M_WAITOK); anonblock->count = needed; anonblock->anons = anon; @@ -129,6 +128,7 @@ uvm_anon_add(count) simple_lock_init(&uvm.afree->an_lock); } simple_unlock(&uvm.afreelock); + return 0; } /* diff --git a/sys/uvm/uvm_anon.h b/sys/uvm/uvm_anon.h index 7ed395427a4b..fc5ba5f61030 100644 --- a/sys/uvm/uvm_anon.h +++ b/sys/uvm/uvm_anon.h @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_anon.h,v 1.12 2000/01/11 06:57:49 chs Exp $ */ +/* $NetBSD: uvm_anon.h,v 1.13 2000/12/27 09:17:04 chs Exp $ */ /* * @@ -101,7 +101,7 @@ struct vm_aref { struct vm_anon *uvm_analloc __P((void)); void uvm_anfree __P((struct vm_anon *)); void uvm_anon_init __P((void)); -void uvm_anon_add __P((int)); +int uvm_anon_add __P((int)); void uvm_anon_remove __P((int)); struct vm_page *uvm_anon_lockloanpg __P((struct vm_anon *)); void uvm_anon_dropswap __P((struct vm_anon *)); diff --git a/sys/uvm/uvm_swap.c b/sys/uvm/uvm_swap.c index a66ac45cd664..724dfddfacf0 100644 --- a/sys/uvm/uvm_swap.c +++ b/sys/uvm/uvm_swap.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_swap.c,v 1.42 2000/12/23 12:13:05 enami Exp $ */ +/* $NetBSD: uvm_swap.c,v 1.43 2000/12/27 09:17:04 chs Exp $ */ /* * Copyright (c) 1995, 1996, 1997 Matthew R. Green @@ -927,16 +927,20 @@ swap_on(p, sdp) printf("leaving %d pages of swap\n", size); } + /* + * try to add anons to reflect the new swap space. + */ + + error = uvm_anon_add(size); + if (error) { + goto bad; + } + /* * add a ref to vp to reflect usage as a swap device. */ vref(vp); - /* - * add anons to reflect the new swap space - */ - uvm_anon_add(size); - /* * now add the new swapdev to the drum and enable. */ @@ -949,12 +953,17 @@ swap_on(p, sdp) simple_unlock(&uvm.swap_data_lock); return (0); -bad: /* - * failure: close device if necessary and return error. + * failure: clean up and return error. */ - if (vp != rootvp) + +bad: + if (sdp->swd_ex) { + extent_destroy(sdp->swd_ex); + } + if (vp != rootvp) { (void)VOP_CLOSE(vp, FREAD|FWRITE, p->p_ucred, p); + } return (error); }