move uvm reserve enforcement to pmemrange
so all allocators obey it, not just uvm_pagealloc (which is increasingly rarely called). This actually makes it a lot harder to deadlock the machine under very heavy memory pressure (uvm_pglistalloc for 7 pages when you have 7 pages left, for example). I have been using variants of this diff on my machines for months. I have discussed doing this with ariane@ many many times. here's the diff: ok? -0- Index: uvm/uvm_page.c === RCS file: /cvs/src/sys/uvm/uvm_page.c,v retrieving revision 1.111 diff -u -p -r1.111 uvm_page.c --- uvm/uvm_page.c 3 Jul 2011 18:34:14 - 1.111 +++ uvm/uvm_page.c 3 Jul 2011 20:14:37 - @@ -76,7 +76,6 @@ #include sys/sched.h #include sys/kernel.h #include sys/vnode.h -#include sys/mount.h #include sys/proc.h #include uvm/uvm.h @@ -885,43 +884,19 @@ uvm_pagealloc(struct uvm_object *obj, vo struct vm_page *pg; struct pglist pgl; int pmr_flags; - boolean_t use_reserve; KASSERT(obj == NULL || anon == NULL); KASSERT(off == trunc_page(off)); - /* -* check to see if we need to generate some free pages waking -* the pagedaemon. -*/ - if ((uvmexp.free - BUFPAGES_DEFICIT) uvmexp.freemin || - ((uvmexp.free - BUFPAGES_DEFICIT) uvmexp.freetarg - (uvmexp.inactive + BUFPAGES_INACT) uvmexp.inactarg)) - wakeup(uvm.pagedaemon); - - /* -* fail if any of these conditions is true: -* [1] there really are no free pages, or -* [2] only kernel reserved pages remain and -*the page isn't being allocated to a kernel object. -* [3] only pagedaemon reserved pages remain and -*the requestor isn't the pagedaemon. -*/ - - use_reserve = (flags UVM_PGA_USERESERVE) || - (obj UVM_OBJ_IS_KERN_OBJECT(obj)); - if ((uvmexp.free = uvmexp.reserve_kernel !use_reserve) || - (uvmexp.free = uvmexp.reserve_pagedaemon -!((curproc == uvm.pagedaemon_proc) || - (curproc == syncerproc - goto fail; - + /* XXX these functions should share flags */ pmr_flags = UVM_PLA_NOWAIT; if (flags UVM_PGA_ZERO) pmr_flags |= UVM_PLA_ZERO; + if (flags UVM_PGA_USERESERVE) + pmr_flags |= UVM_PLA_USERESERVE; TAILQ_INIT(pgl); if (uvm_pmr_getpages(1, 0, 0, 1, 0, 1, pmr_flags, pgl) != 0) - goto fail; + return (NULL); pg = TAILQ_FIRST(pgl); KASSERT(pg != NULL TAILQ_NEXT(pg, pageq) == NULL); @@ -932,10 +907,7 @@ uvm_pagealloc(struct uvm_object *obj, vo if (flags UVM_PGA_ZERO) atomic_clearbits_int(pg-pg_flags, PG_CLEAN); - return(pg); - - fail: - return (NULL); + return (pg); } /* Index: uvm/uvm_pmemrange.c === RCS file: /cvs/src/sys/uvm/uvm_pmemrange.c,v retrieving revision 1.25 diff -u -p -r1.25 uvm_pmemrange.c --- uvm/uvm_pmemrange.c 22 Jun 2011 00:16:47 - 1.25 +++ uvm/uvm_pmemrange.c 3 Jul 2011 20:14:37 - @@ -19,6 +19,7 @@ #include sys/param.h #include uvm/uvm.h #include sys/malloc.h +#include sys/mount.h /* for BUFPAGES defines */ #include sys/proc.h /* XXX for atomic */ /* @@ -747,6 +748,7 @@ uvm_pmr_getpages(psize_t count, paddr_t int memtype;/* Requested memtype. */ int memtype_init; /* Best memtype. */ int desperate; /* True if allocation failed. */ + int is_pdaemon; #ifdef DIAGNOSTIC struct vm_page *diag_prev; /* Used during validation. */ #endif /* DIAGNOSTIC */ @@ -762,6 +764,27 @@ uvm_pmr_getpages(psize_t count, paddr_t (boundary == 0 || maxseg * boundary = count) TAILQ_EMPTY(result)); + is_pdaemon = ((curproc == uvm.pagedaemon_proc) || + (curproc == syncerproc)); + + /* +* All allocations by the pagedaemon automatically get access to +* the kernel reserve of pages so swapping can catch up with memory +* exhaustion +*/ + if (is_pdaemon) + flags |= UVM_PLA_USERESERVE; + + /* +* check to see if we need to generate some free pages waking +* the pagedaemon. +*/ + if ((uvmexp.free - BUFPAGES_DEFICIT) uvmexp.freemin || + ((uvmexp.free - BUFPAGES_DEFICIT) uvmexp.freetarg + (uvmexp.inactive + BUFPAGES_INACT) uvmexp.inactarg)) + wakeup(uvm.pagedaemon); + + /* * TRYCONTIG is a noop if you only want a single segment. * Remove it if that's the case: otherwise it'll deny the fast @@ -835,6 +858,20 @@ retry: /* Return point after sleeping. fnsegs = 0; uvm_lock_fpageq(); + + /* +
better bread
bread doesn't need the cred argument, remove it. Index: isofs/cd9660/cd9660_lookup.c === RCS file: /cvs/src/sys/isofs/cd9660/cd9660_lookup.c,v retrieving revision 1.17 diff -u -r1.17 cd9660_lookup.c --- isofs/cd9660/cd9660_lookup.c17 Jan 2010 20:25:58 - 1.17 +++ isofs/cd9660/cd9660_lookup.c3 Jul 2011 23:08:18 - @@ -438,7 +438,7 @@ lbn = lblkno(imp, offset); bsize = blksize(imp, ip, lbn); - if ((error = bread(vp, lbn, bsize, NOCRED, bp)) != 0) { + if ((error = bread(vp, lbn, bsize, bp)) != 0) { brelse(bp); *bpp = NULL; return (error); Index: isofs/cd9660/cd9660_rrip.c === RCS file: /cvs/src/sys/isofs/cd9660/cd9660_rrip.c,v retrieving revision 1.9 diff -u -r1.9 cd9660_rrip.c --- isofs/cd9660/cd9660_rrip.c 14 Feb 2007 00:53:48 - 1.9 +++ isofs/cd9660/cd9660_rrip.c 3 Jul 2011 23:08:19 - @@ -590,7 +590,7 @@ ana-imp-logical_block_size || bread(ana-imp-im_devvp, ana-iso_ce_blk (ana-imp-im_bshift - DEV_BSHIFT), - ana-imp-logical_block_size, NOCRED, bp)) + ana-imp-logical_block_size, bp)) /* what to do now? */ break; phead = Index: isofs/cd9660/cd9660_vfsops.c === RCS file: /cvs/src/sys/isofs/cd9660/cd9660_vfsops.c,v retrieving revision 1.58 diff -u -r1.58 cd9660_vfsops.c --- isofs/cd9660/cd9660_vfsops.c16 Apr 2011 03:21:15 - 1.58 +++ isofs/cd9660/cd9660_vfsops.c3 Jul 2011 23:08:19 - @@ -283,7 +283,7 @@ for (iso_blknum = 16; iso_blknum 100; iso_blknum++) { if ((error = bread(devvp, (iso_blknum + sess) * btodb(iso_bsize), - iso_bsize, NOCRED, bp)) != 0) + iso_bsize, bp)) != 0) goto out; vdp = (struct iso_volume_descriptor *)bp-b_data; @@ -386,7 +386,7 @@ if ((error = bread(isomp-im_devvp, (isomp-root_extent + isonum_711(rootp-ext_attr_length)) (isomp-im_bshift - DEV_BSHIFT), - isomp-logical_block_size, NOCRED, bp)) != 0) + isomp-logical_block_size, bp)) != 0) goto out; rootp = (struct iso_directory_record *)bp-b_data; @@ -815,7 +815,7 @@ error = bread(imp-im_devvp, lbn (imp-im_bshift - DEV_BSHIFT), - imp-logical_block_size, NOCRED, bp); + imp-logical_block_size, bp); if (error) { vput(vp); brelse(bp); Index: isofs/cd9660/cd9660_vnops.c === RCS file: /cvs/src/sys/isofs/cd9660/cd9660_vnops.c,v retrieving revision 1.53 diff -u -r1.53 cd9660_vnops.c --- isofs/cd9660/cd9660_vnops.c 5 Apr 2011 14:14:07 - 1.53 +++ isofs/cd9660/cd9660_vnops.c 3 Jul 2011 23:08:19 - @@ -326,10 +326,10 @@ ra-sizes[i] = blksize(imp, ip, rablock + i); } error = breadn(vp, lbn, size, ra-blks, - ra-sizes, i, NOCRED, bp); + ra-sizes, i, bp); free(ra, M_TEMP); } else - error = bread(vp, lbn, size, NOCRED, bp); + error = bread(vp, lbn, size, bp); ci-ci_lastr = lbn; n = min(n, size - bp-b_resid); if (error) { @@ -700,7 +700,7 @@ error = bread(imp-im_devvp, (ip-i_number imp-im_bshift) (imp-im_bshift - DEV_BSHIFT), - imp-logical_block_size, NOCRED, bp); + imp-logical_block_size, bp); if (error) { brelse(bp); return (EINVAL); Index: isofs/udf/udf.h === RCS file: /cvs/src/sys/isofs/udf/udf.h,v retrieving revision 1.13 diff -u -r1.13 udf.h --- isofs/udf/udf.h 14 Aug 2009 22:23:45 - 1.13 +++ isofs/udf/udf.h 3 Jul 2011 23:08:19 - @@ -104,7 +104,7 @@ * Can the block layer be forced to use a different block size? */ #defineRDSECTOR(devvp, sector, size, bp) \ - bread(devvp, sector (ump-um_bshift - DEV_BSHIFT), size, NOCRED, bp) + bread(devvp, sector (ump-um_bshift - DEV_BSHIFT), size, bp) static __inline int udf_readlblks(struct umount *ump, int sector, int
wcsdup
From NetBSD with overflow check and a couple of minor tweaks by me. libc minor bump. Needed for libedit with wide characters which might be nice sometime. Comments/ok? Index: include/wchar.h === RCS file: /cvs/src/include/wchar.h,v retrieving revision 1.17 diff -u -p -r1.17 wchar.h --- include/wchar.h 1 Jun 2011 16:39:07 - 1.17 +++ include/wchar.h 4 Jul 2011 04:04:42 - @@ -146,6 +146,7 @@ unsigned long int wcstoul(const wchar_t int base); #if __POSIX_VISIBLE = 200809 +wchar_t*wcsdup(const wchar_t *); int wcscasecmp(const wchar_t *, const wchar_t *); int wcsncasecmp(const wchar_t *, const wchar_t *, size_t); #endif Index: lib/libc/shlib_version === RCS file: /cvs/src/lib/libc/shlib_version,v retrieving revision 1.132 diff -u -p -r1.132 shlib_version @@ -1,4 +1,4 @@ major=58 -minor=3 +minor=4 # note: If changes were made to include/thread_private.h or if system # calls were added/changed then libpthread must also be updated. Index: lib/libc/string/Makefile.inc === RCS file: /cvs/src/lib/libc/string/Makefile.inc,v retrieving revision 1.25 diff -u -p -r1.25 Makefile.inc --- lib/libc/string/Makefile.inc28 May 2011 15:16:46 - 1.25 +++ lib/libc/string/Makefile.inc4 Jul 2011 01:02:53 - @@ -9,7 +9,7 @@ SRCS+= bm.c memccpy.c memrchr.c strcasec wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \ wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcspbrk.c wcsrchr.c wcsspn.c \ wcsstr.c wcstok.c wcswcs.c wcswidth.c wmemchr.c wmemcmp.c wmemcpy.c \ - wmemmove.c wmemset.c \ + wmemmove.c wmemset.c wcsdup.c \ timingsafe_bcmp.c wcscasecmp.c # machine-dependent net sources @@ -144,7 +144,7 @@ MAN+= bm.3 bcmp.3 bcopy.3 bstring.3 bzer strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strerror.3 \ string.3 strlen.3 strmode.3 strdup.3 strpbrk.3 strrchr.3 strsep.3 \ strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 strlcpy.3 \ - wcstok.3 wmemchr.3 wcswidth.3 + wcstok.3 wmemchr.3 wcswidth.3 wcsdup.3 MLINKS+=bm.3 bm_comp.3 bm.3 bm_exec.3 bm.3 bm_free.3 MLINKS+=memchr.3 memrchr.3 Index: lib/libc/string/wcsdup.3 === RCS file: lib/libc/string/wcsdup.3 diff -N lib/libc/string/wcsdup.3 --- /dev/null 1 Jan 1970 00:00:00 - +++ lib/libc/string/wcsdup.34 Jul 2011 03:50:27 - @@ -0,0 +1,86 @@ +.\$OpenBSD$ +.\$NetBSD: wcsdup.3,v 1.3 2010/12/16 17:42:28 wiz Exp $ +.\ +.\ Copyright (c) 1990, 1991, 1993 +.\The Regents of the University of California. All rights reserved. +.\ +.\ Redistribution and use in source and binary forms, with or without +.\ modification, are permitted provided that the following conditions +.\ are met: +.\ 1. Redistributions of source code must retain the above copyright +.\notice, this list of conditions and the following disclaimer. +.\ 2. Redistributions in binary form must reproduce the above copyright +.\notice, this list of conditions and the following disclaimer in the +.\documentation and/or other materials provided with the distribution. +.\ 3. Neither the name of the University nor the names of its contributors +.\may be used to endorse or promote products derived from this software +.\without specific prior written permission. +.\ +.\ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\ SUCH DAMAGE. +.\ +.\ from: @(#)strdup.3 8.1 (Berkeley) 6/9/93 +.\ +.Dd $Mdocdate$ +.Dt WCSDUP 3 +.Os +.Sh NAME +.Nm wcsdup +.Nd save a copy of a string +.Sh SYNOPSIS +.In wchar.h +.Ft wchar_t * +.Fn wcsdup const wchar_t *str +.Sh DESCRIPTION +The +.Fn wcsdup +function +allocates sufficient memory for a copy +of the wide-character string +.Fa str , +does the copy, and returns a pointer to it. +The pointer may subsequently be used as an +argument to the function +.Xr free 3 . +.Pp +If insufficient memory is available, +.Dv NULL +is returned. +.Sh EXAMPLES +The following will point +.Va p +to an allocated area of memory containing the