Date: Wed, 26 Aug 2009 12:01:12 GMT From: Marko Zec <zec@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 167829 for review Message-ID: <200908261201.n7QC1Cbm032046@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=167829 Change 167829 by zec@zec_tpx32 on 2009/08/26 12:00:31 Attempt to preempt panics in vnet_alloc() call graph by doing a brute-force check whether a reasonable amount of kmem is available. This is not guaranteed to work all the time (no protection against races on memory allocations), but given that now jail -c may fail as vnet_alloc() fails, this could serve as an indicator to sysadmins that an imminent panic due to kmem starvation may be around the corner. This is a better-than-nothing alternative to current behavior, which guarantees a panic on jail -c vnet when kmem is in short supply. Affected files ... .. //depot/projects/vimage-commit2/src/sys/kern/kern_jail.c#34 edit .. //depot/projects/vimage-commit2/src/sys/net/vnet.c#6 edit Differences ... ==== //depot/projects/vimage-commit2/src/sys/kern/kern_jail.c#34 (text+ko) ==== @@ -1199,6 +1199,11 @@ /* Allocate a new vnet if specified. */ pr->pr_vnet = (pr_flags & PR_VNET) ? vnet_alloc() : ppr->pr_vnet; + if (pr->pr_vnet == NULL) { + prison_deref(pr, PD_LIST_XLOCKED); + error = ENOMEM; + goto done_releroot; + } #endif /* * Allocate a dedicated cpuset for each jail. @@ -2456,7 +2461,7 @@ sx_downgrade(&allprison_lock); #ifdef VIMAGE - if (pr->pr_vnet != ppr->pr_vnet) + if (pr->pr_vnet != NULL && pr->pr_vnet != ppr->pr_vnet) vnet_destroy(pr->pr_vnet); #endif if (pr->pr_root != NULL) { ==== //depot/projects/vimage-commit2/src/sys/net/vnet.c#6 (text+ko) ==== @@ -216,6 +216,18 @@ { struct vnet *vnet; + /* + * Do not proceed with a lengthy chain of direct and indirect + * mallocs if kmem shortage can be anticipated. This ad-hoc + * check applies only to non-default vnets. + */ + if (vnet0 != NULL) { + vnet = malloc(1024*1024, M_VNET, M_NOWAIT | M_ZERO); + if (vnet == NULL) + return (NULL); + free(vnet, M_VNET); + } + vnet = malloc(sizeof(struct vnet), M_VNET, M_WAITOK | M_ZERO); vnet->vnet_magic_n = VNET_MAGIC_N;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908261201.n7QC1Cbm032046>