summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc
diff options
context:
space:
mode:
authorRoger A. Faulkner <Roger.Faulkner@Sun.COM>2009-03-25 17:21:37 -0700
committerRoger A. Faulkner <Roger.Faulkner@Sun.COM>2009-03-25 17:21:37 -0700
commit09ce0d4acf1a79c720d7e54b60e87cbfa0f1b2d6 (patch)
tree93c46b6617bd292c19e8b839ab1233af69b7dfc5 /usr/src/lib/libc
parent7a088f03b431bdffa96c3b2175964d4d38420caa (diff)
downloadillumos-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/Makefile6
-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.com11
-rw-r--r--usr/src/lib/libc/inc/thr_uberdata.h22
-rw-r--r--usr/src/lib/libc/port/gen/mmap.c59
-rw-r--r--usr/src/lib/libc/port/gen/munmap.c40
-rw-r--r--usr/src/lib/libc/port/gen/nss_common.c14
-rw-r--r--usr/src/lib/libc/port/sys/shmsys.c90
-rw-r--r--usr/src/lib/libc/port/threads/scalls.c6
-rw-r--r--usr/src/lib/libc/port/threads/synch.c104
-rw-r--r--usr/src/lib/libc/port/threads/thr.c1
-rw-r--r--usr/src/lib/libc/sparc/Makefile11
-rw-r--r--usr/src/lib/libc/sparcv9/Makefile6
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 \