diff options
author | Roger A. Faulkner <Roger.Faulkner@Sun.COM> | 2009-03-25 17:21:37 -0700 |
---|---|---|
committer | Roger A. Faulkner <Roger.Faulkner@Sun.COM> | 2009-03-25 17:21:37 -0700 |
commit | 09ce0d4acf1a79c720d7e54b60e87cbfa0f1b2d6 (patch) | |
tree | 93c46b6617bd292c19e8b839ab1233af69b7dfc5 /usr/src/lib/libc | |
parent | 7a088f03b431bdffa96c3b2175964d4d38420caa (diff) | |
download | illumos-joyent-09ce0d4acf1a79c720d7e54b60e87cbfa0f1b2d6.tar.gz |
6816409 mutex_lock() for process robust mutex could not return EOWNERDEAD with 137111-01 or later
--HG--
rename : usr/src/lib/libc/common/sys/mmap.s => usr/src/lib/libc/common/sys/__mmap.s
rename : usr/src/lib/libc/common/sys/munmap.s => usr/src/lib/libc/common/sys/__munmap.s
Diffstat (limited to 'usr/src/lib/libc')
-rw-r--r-- | usr/src/lib/libc/amd64/Makefile | 6 | ||||
-rw-r--r-- | usr/src/lib/libc/common/sys/__mmap.s (renamed from usr/src/lib/libc/common/sys/mmap.s) | 28 | ||||
-rw-r--r-- | usr/src/lib/libc/common/sys/__munmap.s (renamed from usr/src/lib/libc/common/sys/munmap.s) | 20 | ||||
-rw-r--r-- | usr/src/lib/libc/i386/Makefile.com | 11 | ||||
-rw-r--r-- | usr/src/lib/libc/inc/thr_uberdata.h | 22 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/mmap.c | 59 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/munmap.c | 40 | ||||
-rw-r--r-- | usr/src/lib/libc/port/gen/nss_common.c | 14 | ||||
-rw-r--r-- | usr/src/lib/libc/port/sys/shmsys.c | 90 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/scalls.c | 6 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/synch.c | 104 | ||||
-rw-r--r-- | usr/src/lib/libc/port/threads/thr.c | 1 | ||||
-rw-r--r-- | usr/src/lib/libc/sparc/Makefile | 11 | ||||
-rw-r--r-- | usr/src/lib/libc/sparcv9/Makefile | 6 |
14 files changed, 336 insertions, 82 deletions
diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile index 5824f3aaa3..7d72c12ec4 100644 --- a/usr/src/lib/libc/amd64/Makefile +++ b/usr/src/lib/libc/amd64/Makefile @@ -140,6 +140,8 @@ SYSOBJS64= COMSYSOBJS= \ __clock_timer.o \ __getloadavg.o \ + __mmap.o \ + __munmap.o \ __rusagesys.o \ __signotify.o \ __sigrt.o \ @@ -225,11 +227,9 @@ COMSYSOBJS= \ mincore.o \ mkdir.o \ mknod.o \ - mmap.o \ modctl.o \ mount.o \ mprotect.o \ - munmap.o \ nice.o \ ntp_adjtime.o \ ntp_gettime.o \ @@ -471,10 +471,12 @@ PORTGEN= \ mktemp.o \ mlock.o \ mlockall.o \ + mmap.o \ mon.o \ msync.o \ munlock.o \ munlockall.o \ + munmap.o \ ndbm.o \ nftw.o \ nlspath_checks.o \ diff --git a/usr/src/lib/libc/common/sys/mmap.s b/usr/src/lib/libc/common/sys/__mmap.s index 4175283eb8..62fd93e7ce 100644 --- a/usr/src/lib/libc/common/sys/mmap.s +++ b/usr/src/lib/libc/common/sys/__mmap.s @@ -20,22 +20,14 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ - .file "mmap.s" - -#include <sys/asm_linkage.h> - -#if !defined(_LARGEFILE_SOURCE) - ANSI_PRAGMA_WEAK(mmap,function) -#else - ANSI_PRAGMA_WEAK(mmap64,function) -#endif + .file "__mmap.s" #include "SYS.h" #include <sys/mman.h> /* Need _MAP_NEW definition */ @@ -43,12 +35,12 @@ #if !defined(_LARGEFILE_SOURCE) /* - * C library -- mmap - * caddr_t mmap(caddr_t addr, size_t len, int prot, + * Raw system call, private to libc: + * caddr_t __mmap(caddr_t addr, size_t len, int prot, * int flags, int fd, off_t off) */ - ENTRY(mmap) + ENTRY(__mmap) #if defined(__sparc) /* this depends upon the _MAP_NEW flag being in the top bits */ sethi %hi(_MAP_NEW), %g1 @@ -57,17 +49,17 @@ SYSTRAP_RVAL1(mmap) SYSCERROR RET - SET_SIZE(mmap) + SET_SIZE(__mmap) #else /* - * C library -- mmap64 - * caddr_t mmap64(caddr_t addr, size_t len, int prot, + * Raw system call, private to libc: + * caddr_t __mmap64(caddr_t addr, size_t len, int prot, * int flags, int fd, off64_t off) */ - ENTRY(mmap64) + ENTRY(__mmap64) #if defined(__sparc) /* this depends upon the _MAP_NEW flag being in the top bits */ sethi %hi(_MAP_NEW), %g1 @@ -76,6 +68,6 @@ SYSTRAP_RVAL1(mmap64) SYSCERROR RET - SET_SIZE(mmap64) + SET_SIZE(__mmap64) #endif diff --git a/usr/src/lib/libc/common/sys/munmap.s b/usr/src/lib/libc/common/sys/__munmap.s index 2ea70a1454..7aae4de151 100644 --- a/usr/src/lib/libc/common/sys/munmap.s +++ b/usr/src/lib/libc/common/sys/__munmap.s @@ -20,24 +20,24 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ - .file "munmap.s" + .file "__munmap.s" -/* C library -- munmap */ -/* int munmap(caddr_t addr, size_t len) */ - -#include <sys/asm_linkage.h> - - ANSI_PRAGMA_WEAK(munmap,function) +/* + * Raw system call: + * int __munmap(caddr_t addr, size_t len) + */ #include "SYS.h" - SYSCALL_RVAL1(munmap) + ENTRY(__munmap) + SYSTRAP_RVAL1(munmap) + SYSCERROR RETC - SET_SIZE(munmap) + SET_SIZE(__munmap) diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com index 1222822d94..4a4b81227f 100644 --- a/usr/src/lib/libc/i386/Makefile.com +++ b/usr/src/lib/libc/i386/Makefile.com @@ -145,6 +145,7 @@ GENOBJS= \ # sysobjs that contain large-file interfaces COMSYSOBJS64= \ + __mmap64.o \ creat64.o \ fstat64.o \ fstatvfs64.o \ @@ -159,12 +160,13 @@ COMSYSOBJS64= \ stat64.o \ statvfs64.o -SYSOBJS64= \ - mmap64.o +SYSOBJS64= COMSYSOBJS= \ __clock_timer.o \ __getloadavg.o \ + __mmap.o \ + __munmap.o \ __rusagesys.o \ __signotify.o \ __sigrt.o \ @@ -250,11 +252,9 @@ COMSYSOBJS= \ mincore.o \ mkdir.o \ mknod.o \ - mmap.o \ modctl.o \ mount.o \ mprotect.o \ - munmap.o \ nice.o \ ntp_adjtime.o \ ntp_gettime.o \ @@ -347,6 +347,7 @@ PORTGEN64= \ attropen64.o \ ftw64.o \ mkstemp64.o \ + mmap64.o \ nftw64.o \ tell64.o \ truncate64.o @@ -504,10 +505,12 @@ PORTGEN= \ mktemp.o \ mlock.o \ mlockall.o \ + mmap.o \ mon.o \ msync.o \ munlock.o \ munlockall.o \ + munmap.o \ ndbm.o \ nftw.o \ nlspath_checks.o \ diff --git a/usr/src/lib/libc/inc/thr_uberdata.h b/usr/src/lib/libc/inc/thr_uberdata.h index 745547208c..442098a2d1 100644 --- a/usr/src/lib/libc/inc/thr_uberdata.h +++ b/usr/src/lib/libc/inc/thr_uberdata.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -705,16 +705,23 @@ typedef struct atfork { } atfork_t; /* - * Element in the table of registered process robust locks. - * We keep track of these to make sure that we only call - * ___lwp_mutex_register() once for each such lock. + * Element in the table and in the list of registered process + * robust locks. We keep track of these to make sure that we + * only call ___lwp_mutex_register() once for each such lock + * after it is first mapped in (or newly mapped in). */ typedef struct robust { - struct robust *robust_next; + struct robust *robust_next; /* hash table list */ + struct robust *robust_list; /* global list */ mutex_t *robust_lock; } robust_t; /* + * Invalid address, used to mark an unused element in the hash table. + */ +#define INVALID_ADDR ((void *)(uintptr_t)(-1L)) + +/* * Parameters of the lock registration hash table. */ #define LOCKSHIFT 15 /* number of hashing bits */ @@ -888,6 +895,7 @@ typedef struct uberdata { ulwp_t *ulwp_replace_last; atfork_t *atforklist; /* circular Q for fork handlers */ robust_t **robustlocks; /* table of registered robust locks */ + robust_t *robustlist; /* list of registered robust locks */ struct uberdata **tdb_bootstrap; tdb_t tdb; /* thread debug interfaces (for libc_db) */ } uberdata_t; @@ -1096,6 +1104,7 @@ typedef struct uberdata32 { caddr32_t ulwp_replace_last; caddr32_t atforklist; caddr32_t robustlocks; + caddr32_t robustlist; caddr32_t tdb_bootstrap; tdb32_t tdb; } uberdata32_t; @@ -1207,7 +1216,8 @@ extern void record_spin_locks(ulwp_t *); extern void remember_lock(mutex_t *); extern void forget_lock(mutex_t *); extern void register_lock(mutex_t *); -extern void unregister_locks(void); +extern void unregister_locks(caddr_t, size_t); +extern void unregister_all_locks(void); #if defined(__sparc) extern void _flush_windows(void); #else diff --git a/usr/src/lib/libc/port/gen/mmap.c b/usr/src/lib/libc/port/gen/mmap.c new file mode 100644 index 0000000000..ea5b56c905 --- /dev/null +++ b/usr/src/lib/libc/port/gen/mmap.c @@ -0,0 +1,59 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include "lint.h" +#include <sys/feature_tests.h> +#include <sys/mman.h> + +extern void unregister_locks(caddr_t, size_t); + +#if !defined(_LP64) && _FILE_OFFSET_BITS == 64 + +extern caddr_t __mmap64(caddr_t, size_t, int, int, int, off64_t); + +#pragma weak _mmap64 = mmap64 +caddr_t +mmap64(caddr_t addr, size_t len, int prot, int flags, int fildes, off64_t off) +{ + if (flags & MAP_FIXED) + unregister_locks(addr, len); + return (__mmap64(addr, len, prot, flags, fildes, off)); +} + +#else + +extern caddr_t __mmap(caddr_t, size_t, int, int, int, off_t); + +#pragma weak _mmap = mmap +caddr_t +mmap(caddr_t addr, size_t len, int prot, int flags, int fildes, off_t off) +{ + if (flags & MAP_FIXED) + unregister_locks(addr, len); + return (__mmap(addr, len, prot, flags, fildes, off)); +} + +#endif diff --git a/usr/src/lib/libc/port/gen/munmap.c b/usr/src/lib/libc/port/gen/munmap.c new file mode 100644 index 0000000000..c7d7b34f3f --- /dev/null +++ b/usr/src/lib/libc/port/gen/munmap.c @@ -0,0 +1,40 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma weak _munmap = munmap + +#include "lint.h" +#include <sys/mman.h> + +extern void unregister_locks(caddr_t, size_t); +extern int __munmap(caddr_t, size_t); + +int +munmap(caddr_t addr, size_t len) +{ + unregister_locks(addr, len); + return (__munmap(addr, len)); +} diff --git a/usr/src/lib/libc/port/gen/nss_common.c b/usr/src/lib/libc/port/gen/nss_common.c index c4d033a141..d82075b30b 100644 --- a/usr/src/lib/libc/port/gen/nss_common.c +++ b/usr/src/lib/libc/port/gen/nss_common.c @@ -20,12 +20,10 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Shared code used by the name-service-switch frontends (e.g. getpwnam_r()) */ @@ -2056,7 +2054,7 @@ _nsc_search(nss_db_root_t *rootp, nss_db_initf_t initf, int search_fnum, */ if (doorptr != (void *)pbuf) { _nsc_resizedoorbuf(bufsize); - munmap((void *)doorptr, bufsize); + (void) munmap((void *)doorptr, bufsize); } return (NSS_TRYLOCAL); } @@ -2071,7 +2069,7 @@ _nsc_search(nss_db_root_t *rootp, nss_db_initf_t initf, int search_fnum, */ if (doorptr != (void *)pbuf) { _nsc_resizedoorbuf(bufsize); - munmap((void *)doorptr, bufsize); + (void) munmap((void *)doorptr, bufsize); } return (status); } @@ -2153,7 +2151,7 @@ _nsc_setent_u(nss_db_root_t *rootp, nss_db_initf_t initf, */ if (doorptr != (void *)pbuf) { _nsc_resizedoorbuf(bufsize); - munmap((void *)doorptr, bufsize); + (void) munmap((void *)doorptr, bufsize); } return (status); } @@ -2220,7 +2218,7 @@ _nsc_getent_u(nss_db_root_t *rootp, nss_db_initf_t initf, */ if (doorptr != (void *)pbuf) { _nsc_resizedoorbuf(bufsize); - munmap((void *)doorptr, bufsize); + (void) munmap((void *)doorptr, bufsize); } return (status); } @@ -2270,7 +2268,7 @@ _nsc_endent_u(nss_db_root_t *rootp, nss_db_initf_t initf, */ if (doorptr != (void *)pbuf) { _nsc_resizedoorbuf(bufsize); - munmap((void *)doorptr, bufsize); + (void) munmap((void *)doorptr, bufsize); } /* clean up initf setup */ diff --git a/usr/src/lib/libc/port/sys/shmsys.c b/usr/src/lib/libc/port/sys/shmsys.c index 141dedf1c9..89d5b8b113 100644 --- a/usr/src/lib/libc/port/sys/shmsys.c +++ b/usr/src/lib/libc/port/sys/shmsys.c @@ -20,15 +20,13 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1988 AT&T */ /* All Rights Reserved */ -#pragma ident "%Z%%M% %I% %E% SMI" - #pragma weak _shmat = shmat #pragma weak _shmctl = shmctl #pragma weak _shmctl64 = shmctl64 @@ -37,6 +35,7 @@ #pragma weak _shmids = shmids #include "lint.h" +#include "thr_uberdata.h" #include <sys/types.h> #include <sys/ipc.h> #include <sys/ipc_impl.h> @@ -45,16 +44,92 @@ #include <sys/syscall.h> #include <errno.h> +/* + * List of all shared memory segments. + * We need this to keep track of the sizes so that we can unregister + * any robust locks that are contained in a segment that is detached. + */ +static struct shm_size { + void *shm_addr; + size_t shm_size; + struct shm_size *shm_next; +} *shm_list = NULL; + +static mutex_t shm_lock = DEFAULTMUTEX; /* protects shm_list */ + +extern void unregister_locks(caddr_t, size_t); + +/* + * Add a shared memory address and size to the remembered list. + */ +static void +add_shm_size(void *addr, size_t size) +{ + struct shm_size **list; + struct shm_size *elem; + + lmutex_lock(&shm_lock); + + for (list = &shm_list; (elem = *list) != NULL; list = &elem->shm_next) { + if (elem->shm_addr == addr) { /* won't happen? */ + elem->shm_size = size; + lmutex_unlock(&shm_lock); + return; + } + } + elem = lmalloc(sizeof (*elem)); + elem->shm_addr = addr; + elem->shm_size = size; + elem->shm_next = NULL; + *list = elem; + + lmutex_unlock(&shm_lock); +} + +/* + * Delete the shared memory address from the remembered list + * and unregister all of the robust locks contained therein. + */ +static void +delete_shm_size(void *addr) +{ + struct shm_size **list; + struct shm_size *elem; + size_t size = 0; + + lmutex_lock(&shm_lock); + + for (list = &shm_list; (elem = *list) != NULL; list = &elem->shm_next) { + if (elem->shm_addr == addr) { + size = elem->shm_size; + *list = elem->shm_next; + lfree(elem, sizeof (*elem)); + break; + } + } + + lmutex_unlock(&shm_lock); + + if (size != 0) + unregister_locks(addr, size); +} + void * shmat(int shmid, const void *shmaddr, int shmflg) { sysret_t rval; int error; + void *addr; + struct shmid_ds shmds; error = __systemcall(&rval, SYS_shmsys, SHMAT, shmid, shmaddr, shmflg); - if (error) + addr = (void *)rval.sys_rval1; + if (error) { (void) __set_errno(error); - return ((void *)rval.sys_rval1); + } else if (shmctl(shmid, IPC_STAT, &shmds) == 0) { + add_shm_size(addr, shmds.shm_segsz); + } + return (addr); } int @@ -80,7 +155,10 @@ shmctl64(int shmid, int cmd, struct shmid_ds64 *buf) int shmdt(char *shmaddr) { - return (syscall(SYS_shmsys, SHMDT, shmaddr)); + int rval = syscall(SYS_shmsys, SHMDT, shmaddr); + if (rval == 0) + delete_shm_size(shmaddr); + return (rval); } int diff --git a/usr/src/lib/libc/port/threads/scalls.c b/usr/src/lib/libc/port/threads/scalls.c index d2d528db95..42a1c754a3 100644 --- a/usr/src/lib/libc/port/threads/scalls.c +++ b/usr/src/lib/libc/port/threads/scalls.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -243,7 +243,7 @@ forkx(int flags) self->ul_siginfo.si_signo = 0; udp->pid = getpid(); /* reset the library's data structures to reflect one thread */ - unregister_locks(); + unregister_all_locks(); postfork1_child(); restore_signals(self); (void) mutex_unlock(&udp->fork_lock); @@ -321,7 +321,7 @@ forkallx(int flags) self->ul_cursig = 0; self->ul_siginfo.si_signo = 0; udp->pid = getpid(); - unregister_locks(); + unregister_all_locks(); continue_fork(1); } else { continue_fork(0); diff --git a/usr/src/lib/libc/port/threads/synch.c b/usr/src/lib/libc/port/threads/synch.c index f3eab82f07..06e9abb88c 100644 --- a/usr/src/lib/libc/port/threads/synch.c +++ b/usr/src/lib/libc/port/threads/synch.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -1937,6 +1937,7 @@ register_lock(mutex_t *mp) uberdata_t *udp = curthread->ul_uberdata; uint_t hash = LOCK_HASH(mp); robust_t *rlp; + robust_t *invalid; robust_t **rlpp; robust_t **table; @@ -1967,6 +1968,7 @@ register_lock(mutex_t *mp) */ lmutex_lock(&udp->tdb_hash_lock); + invalid = NULL; for (rlpp = &table[hash]; (rlp = *rlpp) != NULL; rlpp = &rlp->robust_next) { @@ -1974,17 +1976,75 @@ register_lock(mutex_t *mp) lmutex_unlock(&udp->tdb_hash_lock); return; } + /* remember the first invalid entry, if any */ + if (rlp->robust_lock == INVALID_ADDR && invalid == NULL) + invalid = rlp; } /* * The lock has never been registered. - * Register it now and add it to the table. + * Add it to the table and register it now. */ + if (invalid != NULL) { + /* + * Reuse the invalid entry we found above. + * The linkages are still correct. + */ + invalid->robust_lock = mp; + membar_producer(); + } else { + /* + * Allocate a new entry and add it to + * the hash table and to the global list. + */ + rlp = lmalloc(sizeof (*rlp)); + rlp->robust_lock = mp; + rlp->robust_next = NULL; + rlp->robust_list = udp->robustlist; + udp->robustlist = rlp; + membar_producer(); + *rlpp = rlp; + } + + lmutex_unlock(&udp->tdb_hash_lock); + (void) ___lwp_mutex_register(mp); - rlp = lmalloc(sizeof (*rlp)); - rlp->robust_lock = mp; - membar_producer(); - *rlpp = rlp; +} + +/* + * This is called from mmap(), munmap() and shmdt() to unregister + * all robust locks contained in the mapping that is going away. + * We don't delete the entries in the hash table, since the hash table + * is constrained never to shrink; we just invalidate the addresses. + */ +void +unregister_locks(caddr_t addr, size_t len) +{ + static size_t pagesize = 0; + uberdata_t *udp = curthread->ul_uberdata; + robust_t *rlp; + caddr_t eaddr; + caddr_t maddr; + + /* + * Round up len to a multiple of pagesize. + */ + if (pagesize == 0) /* do this once */ + pagesize = _sysconf(_SC_PAGESIZE); + eaddr = addr + ((len + pagesize - 1) & -pagesize); + + lmutex_lock(&udp->tdb_hash_lock); + + /* + * Do this by traversing the global list, not the hash table. + * The hash table is large (32K buckets) and sparsely populated. + * The global list contains all of the registered entries. + */ + for (rlp = udp->robustlist; rlp != NULL; rlp = rlp->robust_list) { + maddr = (caddr_t)rlp->robust_lock; + if (addr <= maddr && maddr < eaddr) + rlp->robust_lock = INVALID_ADDR; + } lmutex_unlock(&udp->tdb_hash_lock); } @@ -1995,26 +2055,32 @@ register_lock(mutex_t *mp) * No locks are needed because all other threads are suspended or gone. */ void -unregister_locks(void) +unregister_all_locks(void) { uberdata_t *udp = curthread->ul_uberdata; - uint_t hash; robust_t **table; robust_t *rlp; robust_t *next; - if ((table = udp->robustlocks) != NULL) { - for (hash = 0; hash < LOCKHASHSZ; hash++) { - rlp = table[hash]; - while (rlp != NULL) { - next = rlp->robust_next; - lfree(rlp, sizeof (*rlp)); - rlp = next; - } - } - lfree(table, LOCKHASHSZ * sizeof (robust_t *)); - udp->robustlocks = NULL; + /* + * Do this first, before calling lfree(). + * lfree() may call munmap(), which calls unregister_locks(). + */ + table = udp->robustlocks; + udp->robustlocks = NULL; + rlp = udp->robustlist; + udp->robustlist = NULL; + + /* + * As above, do this by traversing the global list, not the hash table. + */ + while (rlp != NULL) { + next = rlp->robust_list; + lfree(rlp, sizeof (*rlp)); + rlp = next; } + if (table != NULL) + lfree(table, LOCKHASHSZ * sizeof (robust_t *)); } /* diff --git a/usr/src/lib/libc/port/threads/thr.c b/usr/src/lib/libc/port/threads/thr.c index 8e85d1c8b9..fdcf549f26 100644 --- a/usr/src/lib/libc/port/threads/thr.c +++ b/usr/src/lib/libc/port/threads/thr.c @@ -132,6 +132,7 @@ uberdata_t __uberdata = { NULL, /* ulwp_replace_last */ NULL, /* atforklist */ NULL, /* robustlocks */ + NULL, /* robustlist */ NULL, /* __tdb_bootstrap */ { /* tdb */ NULL, /* tdb_sync_addr_hash */ diff --git a/usr/src/lib/libc/sparc/Makefile b/usr/src/lib/libc/sparc/Makefile index 5b69107630..72fa454eea 100644 --- a/usr/src/lib/libc/sparc/Makefile +++ b/usr/src/lib/libc/sparc/Makefile @@ -162,6 +162,7 @@ GENOBJS= \ # sysobjs that contain large-file interfaces COMSYSOBJS64= \ + __mmap64.o \ creat64.o \ fstat64.o \ fstatvfs64.o \ @@ -176,12 +177,13 @@ COMSYSOBJS64= \ stat64.o \ statvfs64.o -SYSOBJS64= \ - mmap64.o +SYSOBJS64= COMSYSOBJS= \ __clock_timer.o \ __getloadavg.o \ + __mmap.o \ + __munmap.o \ __rusagesys.o \ __signotify.o \ __sigrt.o \ @@ -266,12 +268,10 @@ COMSYSOBJS= \ mincore.o \ mkdir.o \ mknod.o \ - mmap.o \ mmapobjsys.o \ modctl.o \ mount.o \ mprotect.o \ - munmap.o \ nice.o \ ntp_adjtime.o \ ntp_gettime.o \ @@ -355,6 +355,7 @@ PORTGEN64= \ attropen64.o \ ftw64.o \ mkstemp64.o \ + mmap64.o \ nftw64.o \ tell64.o \ truncate64.o @@ -528,10 +529,12 @@ PORTGEN= \ mktemp.o \ mlock.o \ mlockall.o \ + mmap.o \ mon.o \ msync.o \ munlock.o \ munlockall.o \ + munmap.o \ ndbm.o \ nftw.o \ nlspath_checks.o \ diff --git a/usr/src/lib/libc/sparcv9/Makefile b/usr/src/lib/libc/sparcv9/Makefile index ca6763246f..556ef9bc5d 100644 --- a/usr/src/lib/libc/sparcv9/Makefile +++ b/usr/src/lib/libc/sparcv9/Makefile @@ -164,6 +164,8 @@ SYSOBJS64= COMSYSOBJS= \ __clock_timer.o \ __getloadavg.o \ + __mmap.o \ + __munmap.o \ __rusagesys.o \ __signotify.o \ __sigrt.o \ @@ -248,12 +250,10 @@ COMSYSOBJS= \ mincore.o \ mkdir.o \ mknod.o \ - mmap.o \ mmapobjsys.o \ modctl.o \ mount.o \ mprotect.o \ - munmap.o \ nice.o \ ntp_adjtime.o \ ntp_gettime.o \ @@ -489,10 +489,12 @@ PORTGEN= \ mktemp.o \ mlock.o \ mlockall.o \ + mmap.o \ mon.o \ msync.o \ munlock.o \ munlockall.o \ + munmap.o \ ndbm.o \ nftw.o \ nlspath_checks.o \ |