diff options
author | nr123932 <none@none> | 2007-03-30 01:55:41 -0700 |
---|---|---|
committer | nr123932 <none@none> | 2007-03-30 01:55:41 -0700 |
commit | 8548bf79039833dba8615afdf63258b2cb122121 (patch) | |
tree | c9d7f506296f12858a99b42d94bda969bb1a4ebc | |
parent | 3a62633b4e364efc25704bee4e40b1107709521e (diff) | |
download | illumos-gate-8548bf79039833dba8615afdf63258b2cb122121.tar.gz |
6368753 Need a patch solution to 4522909 automountd hangs with executeable maps
6509943 Apparent deadlock between fork()'s use of lwp_suspend and NFS locking (Backout 4522909)
-rw-r--r-- | usr/src/cmd/fs.d/autofs/Makefile | 6 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/autofs/autod_main.c | 77 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/autofs/autod_mount.c | 129 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/autofs/automount.h | 26 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/autofs/ns_files.c | 75 | ||||
-rw-r--r-- | usr/src/uts/common/os/condvar.c | 22 | ||||
-rw-r--r-- | usr/src/uts/common/os/sig.c | 22 | ||||
-rw-r--r-- | usr/src/uts/common/sys/klwp.h | 30 | ||||
-rw-r--r-- | usr/src/uts/common/vm/vm_as.c | 27 | ||||
-rw-r--r-- | usr/src/uts/intel/fs/proc/prmachdep.c | 12 | ||||
-rw-r--r-- | usr/src/uts/sparc/fs/proc/prmachdep.c | 19 |
11 files changed, 310 insertions, 135 deletions
diff --git a/usr/src/cmd/fs.d/autofs/Makefile b/usr/src/cmd/fs.d/autofs/Makefile index 47fb37668e..7365a9132a 100644 --- a/usr/src/cmd/fs.d/autofs/Makefile +++ b/usr/src/cmd/fs.d/autofs/Makefile @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -85,9 +85,9 @@ POFILE= autofs.po GREP= egrep SED= sed -$(AUTO) := LDLIBS += -lnsl -lsldap +$(AUTO) := LDLIBS += -lnsl -lsldap -ldoor $(MOUNT):= LDLIBS += -lnsl -$(TYPEPROG) := LDLIBS += -lrpcsvc -lsocket -lnsl -lsldap -lkstat +$(TYPEPROG) := LDLIBS += -lrpcsvc -lsocket -lnsl -lsldap -lkstat -ldoor $(TYPEPROG) := LDFLAGS += -R/usr/lib/fs/$(FSTYPE) CFLAGS += $(CCVERBOSE) -D_FILE_OFFSET_BITS=64 diff --git a/usr/src/cmd/fs.d/autofs/autod_main.c b/usr/src/cmd/fs.d/autofs/autod_main.c index 1c0a51d7a1..cee127cb9b 100644 --- a/usr/src/cmd/fs.d/autofs/autod_main.c +++ b/usr/src/cmd/fs.d/autofs/autod_main.c @@ -60,6 +60,7 @@ #include <sys/thread.h> #include <nfs/rnode.h> #include <nfs/nfs.h> +#include <wait.h> static void autofs_doorfunc(void *, char *, size_t, door_desc_t *, uint_t); static void autofs_setdoor(int); @@ -77,6 +78,7 @@ static void usage(); static void warn_hup(int); static void free_action_list(); static int start_autofs_svcs(); +static void automountd_wait_for_cleanup(pid_t); /* @@ -188,6 +190,50 @@ main(argc, argv) openlog("automountd", LOG_PID, LOG_DAEMON); (void) setlocale(LC_ALL, ""); + /* + * Create the door_servers to manage fork/exec requests for + * mounts and executable automount maps + */ + if ((did_fork_exec = door_create(automountd_do_fork_exec, + NULL, NULL)) == -1) { + syslog(LOG_ERR, "door_create failed: %m, Exiting."); + exit(errno); + } + if ((did_exec_map = door_create(automountd_do_exec_map, + NULL, NULL)) == -1) { + syslog(LOG_ERR, "door_create failed: %m, Exiting."); + if (door_revoke(did_fork_exec) == -1) { + syslog(LOG_ERR, "failed to door_revoke(%d) %m", + did_fork_exec); + } + exit(errno); + } + /* + * Before we become multithreaded we fork allowing the parent + * to become a door server to handle all mount and unmount + * requests. This works around a potential hang in using + * fork1() within a multithreaded environment + */ + + pid = fork1(); + if (pid < 0) { + syslog(LOG_ERR, + "can't fork the automountd mount process %m"); + if (door_revoke(did_fork_exec) == -1) { + syslog(LOG_ERR, "failed to door_revoke(%d) %m", + did_fork_exec); + } + if (door_revoke(did_exec_map) == -1) { + syslog(LOG_ERR, "failed to door_revoke(%d) %m", + did_exec_map); + } + exit(1); + } else if (pid > 0) { + /* this is the door server process */ + automountd_wait_for_cleanup(pid); + } + + (void) rwlock_init(&cache_lock, USYNC_THREAD, NULL); (void) rwlock_init(&autofs_rddir_cache_lock, USYNC_THREAD, NULL); @@ -220,8 +266,7 @@ main(argc, argv) case 0: break; case -1: - syslog(LOG_ERR, "error locking for %s: %s", AUTOMOUNTD, - strerror(errno)); + syslog(LOG_ERR, "error locking for %s: %m", AUTOMOUNTD); exit(2); default: /* daemon was already running */ @@ -990,3 +1035,31 @@ encode_res( (*results)->res_status = 0; return (TRUE); } + +static void +automountd_wait_for_cleanup(pid_t pid) +{ + int status; + int child_exitval; + + /* + * Wait for the main automountd process to exit so we cleanup + */ + (void) waitpid(pid, &status, 0); + + child_exitval = WEXITSTATUS(status); + + /* + * Shutdown the door server for mounting and unmounting + * filesystems + */ + if (door_revoke(did_fork_exec) == -1) { + syslog(LOG_ERR, "failed to door_revoke(%d) %m", + did_fork_exec); + } + if (door_revoke(did_exec_map) == -1) { + syslog(LOG_ERR, "failed to door_revoke(%d) %m", + did_exec_map); + } + exit(child_exitval); +} diff --git a/usr/src/cmd/fs.d/autofs/autod_mount.c b/usr/src/cmd/fs.d/autofs/autod_mount.c index b5826a0a20..31055371ef 100644 --- a/usr/src/cmd/fs.d/autofs/autod_mount.c +++ b/usr/src/cmd/fs.d/autofs/autod_mount.c @@ -52,12 +52,13 @@ #include <limits.h> #include <assert.h> #include <fcntl.h> +#include <strings.h> #include "automount.h" #include "replica.h" static int unmount_mntpnt(struct mnttab *); -static int fork_exec(char *, char *, char **, int); +static int call_fork_exec(char *, char *, char **, int); static void remove_browse_options(char *); static int inherit_options(char *, char **); @@ -373,7 +374,7 @@ mount_generic(special, fstype, opts, mntpnt, overlay) newargv[i++] = special; newargv[i++] = mntpnt; newargv[i] = NULL; - res = fork_exec(fstype, "mount", newargv, verbose); + res = call_fork_exec(fstype, "mount", newargv, verbose); if (res == 0 && trace > 1) { if (stat(mntpnt, &stbuf) == 0) { trace_prt(1, " mount of %s dev=%x rdev=%x OK\n", @@ -385,57 +386,58 @@ mount_generic(special, fstype, opts, mntpnt, overlay) return (res); } -static int -fork_exec(fstype, cmd, newargv, console) - char *fstype; - char *cmd; - char **newargv; - int console; +void +automountd_do_fork_exec(void *cookie, char *argp, size_t arg_size, + door_desc_t *dfd, uint_t n_desc) { - char path[MAXPATHLEN]; - int i; int stat_loc; int fd = 0; struct stat stbuf; int res; int child_pid; + command_t *command; + char *newargv[ARGV_MAX]; + int i; - /* build the full path name of the fstype dependent command */ - (void) sprintf(path, "%s/%s/%s", VFS_PATH, fstype, cmd); - if (stat(path, &stbuf) != 0) { - res = errno; - return (res); + command = (command_t *)argp; + if (sizeof (*command) != arg_size) { + res = EINVAL; + door_return((char *)&res, sizeof (res), NULL, 0); } - if (trace > 1) { - trace_prt(1, " fork_exec: %s ", path); - for (i = 2; newargv[i]; i++) - trace_prt(0, "%s ", newargv[i]); - trace_prt(0, "\n"); - } - - - newargv[1] = cmd; switch ((child_pid = fork1())) { case -1: syslog(LOG_ERR, "Cannot fork: %m"); - return (errno); + res = errno; + break; case 0: /* * Child */ (void) setsid(); - fd = open(console ? "/dev/console" : "/dev/null", O_WRONLY); + fd = open(command->console ? "/dev/console" : "/dev/null", + O_WRONLY); if (fd != -1) { (void) dup2(fd, 1); (void) dup2(fd, 2); (void) close(fd); } - (void) execv(path, &newargv[1]); + for (i = 0; *command->argv[i]; i++) { + newargv[i] = strdup(command->argv[i]); + if (newargv[i] == (char *)NULL) { + syslog(LOG_ERR, "failed to copy argument '%s'" + " of %s: %m", command->argv[i], + command->file); + _exit(errno); + } + } + newargv[i] = NULL; + + (void) execv(command->file, newargv); if (errno == EACCES) - syslog(LOG_ERR, "exec %s: %m", path); + syslog(LOG_ERR, "exec %s: %m", command->file); _exit(errno); default: @@ -451,22 +453,25 @@ fork_exec(fstype, cmd, newargv, console) WEXITSTATUS(stat_loc)); } - return (WEXITSTATUS(stat_loc)); - } else - if (WIFSIGNALED(stat_loc)) { - if (trace > 1) { + res = WEXITSTATUS(stat_loc); + } else if (WIFSIGNALED(stat_loc)) { + if (trace > 1) trace_prt(1, " fork_exec: returns signal status %d\n", WTERMSIG(stat_loc)); - } + res = 1; } else { if (trace > 1) trace_prt(1, " fork_exec: returns unknown status\n"); + res = 1; } - return (1); } + door_return((char *)&res, sizeof (res), NULL, 0); + trace_prt(1, "automountd_do_fork_exec, door return failed %s, %s\n", + command->file, strerror(errno)); + door_return(NULL, 0, NULL, 0); } int @@ -551,7 +556,7 @@ unmount_mntpnt(mnt) newargv[2] = mountp; newargv[3] = NULL; - res = fork_exec(fstype, "umount", newargv, verbose); + res = call_fork_exec(fstype, "umount", newargv, verbose); if (res == ENOENT) { /* * filesystem specific unmount command not found @@ -646,3 +651,57 @@ hasrestrictopt(char *opts) return (hasmntopt(&mt, MNTOPT_RESTRICT) != NULL); } + +static int +call_fork_exec(fstype, cmd, newargv, console) + char *fstype; + char *cmd; + char **newargv; + int console; +{ + command_t command; + door_arg_t darg; + char path[MAXPATHLEN]; + struct stat stbuf; + int ret; + int sz; + int status; + int i; + + bzero(&command, sizeof (command)); + /* build the full path name of the fstype dependent command */ + (void) snprintf(path, MAXPATHLEN, "%s/%s/%s", VFS_PATH, fstype, cmd); + + if (stat(path, &stbuf) != 0) { + ret = errno; + return (ret); + } + + strlcpy(command.file, path, MAXPATHLEN); + strlcpy(command.argv[0], path, MAXOPTSLEN); + for (i = 2; newargv[i]; i++) { + strlcpy(command.argv[i-1], newargv[i], MAXOPTSLEN); + } + if (trace > 1) { + trace_prt(1, " call_fork_exec: %s ", command.file); + for (i = 0; *command.argv[i]; i++) + trace_prt(0, "%s ", command.argv[i]); + trace_prt(0, "\n"); + } + + command.console = console; + + darg.data_ptr = (char *)&command; + darg.data_size = sizeof (command); + darg.desc_ptr = NULL; + darg.desc_num = 0; + darg.rbuf = (char *)&status; + darg.rsize = sizeof (status); + + ret = door_call(did_fork_exec, &darg); + if (trace > 1) { + trace_prt(1, " call_fork_exec: door_call failed %d\n", ret); + } + + return (status); +} diff --git a/usr/src/cmd/fs.d/autofs/automount.h b/usr/src/cmd/fs.d/autofs/automount.h index d9c098a4e0..5a4909b79f 100644 --- a/usr/src/cmd/fs.d/autofs/automount.h +++ b/usr/src/cmd/fs.d/autofs/automount.h @@ -36,6 +36,7 @@ #include <rpc/rpc.h> #include <sys/fs/autofs.h> #include <netinet/in.h> /* needed for sockaddr_in declaration */ +#include <door.h> #ifdef MALLOC_DEBUG #include <debug_alloc.h> @@ -93,6 +94,8 @@ extern "C" { #define INITDELAY 5 #define DELAY_BACKOFF 2 #define MAXDELAY 120 +#define ARGV_MAX 16 +#define VFS_PATH "/usr/lib/fs" #define DELAY(delay) { \ (void) sleep(delay); \ delay *= DELAY_BACKOFF; \ @@ -224,6 +227,23 @@ struct myaddrs { struct myaddrs *myaddrs_next; }; +/* + * structure used to pass commands to the door servers + */ + +typedef struct command { + char file[MAXPATHLEN]; + char argv[ARGV_MAX][MAXOPTSLEN]; + char key[MAXOPTSLEN]; + int console; +} command_t; + +/* + * globally visible door_server file descriptor + */ +int did_exec_map; +int did_fork_exec; + extern time_t timenow; /* set at start of processing of each RPC call */ extern char self[]; extern int verbose; @@ -375,6 +395,12 @@ extern int getnetmaskbynet(const struct in_addr, struct in_addr *); extern int __nis_reset_state(); extern int __rpc_negotiate_uid(int); +/* + * door_server functions to handle fork activity within the automounter + */ +void automountd_do_fork_exec(void *, char *, size_t, door_desc_t *, uint_t); +void automountd_do_exec_map(void *, char *, size_t, door_desc_t *, uint_t); + #ifdef __cplusplus } #endif diff --git a/usr/src/cmd/fs.d/autofs/ns_files.c b/usr/src/cmd/fs.d/autofs/ns_files.c index f04318a350..21a9766007 100644 --- a/usr/src/cmd/fs.d/autofs/ns_files.c +++ b/usr/src/cmd/fs.d/autofs/ns_files.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * 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. @@ -22,7 +21,7 @@ /* * ns_files.c * - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -46,10 +45,13 @@ #include <synch.h> #include <sys/types.h> #include <sys/wait.h> +#include <strings.h> #include "automount.h" static int read_execout(char *key, char **lp, char *fname, char *line, int linesz); +static int call_read_execout(char *key, char **lp, char *fname, char *line, + int linesz); static FILE *file_open(char *, char *, char **, char ***); /* @@ -114,14 +116,14 @@ getmapent_files(key, mapname, ml, stack, stkptr, iswildcard, isrestricted) fname, key); } - rc = read_execout(key, &lp, fname, ml->linebuf, LINESZ); + rc = call_read_execout(key, &lp, fname, ml->linebuf, LINESZ); if (rc != 0) { nserr = __NSW_UNAVAIL; goto done; } - if (lp == NULL || strlen(ml->linebuf) == 0) { + if (strlen(ml->linebuf) == 0) { nserr = __NSW_NOTFOUND; goto done; } @@ -643,3 +645,64 @@ read_execout(char *key, char **lp, char *fname, char *line, int linesz) return (status); } } + +void +automountd_do_exec_map(void *cookie, char *argp, size_t arg_size, + door_desc_t *dfd, uint_t n_desc) +{ + command_t *command; + char line[LINESZ]; + char *lp; + int rc; + + command = (command_t *)argp; + + if (sizeof (*command) != arg_size) { + rc = 0; + syslog(LOG_ERR, "read_execout: invalid door arguments"); + door_return((char *)&rc, sizeof (rc), NULL, 0); + } + + rc = read_execout(command->key, &lp, command->file, line, LINESZ); + + if (rc != 0) { + /* + * read_execout returned an error, return 0 to the door_client + * to indicate failure + */ + rc = 0; + door_return((char *)&rc, sizeof (rc), NULL, 0); + } else { + door_return((char *)line, LINESZ, NULL, 0); + } + trace_prt(1, "automountd_do_exec_map, door return failed %s, %s\n", + command->file, strerror(errno)); + door_return(NULL, 0, NULL, 0); +} + +int +call_read_execout(char *key, char **lp, char *fname, char *line, + int linesz) +{ + command_t command; + door_arg_t darg; + int ret; + + bzero(&command, sizeof (command)); + (void) strlcpy(command.file, fname, MAXPATHLEN); + (void) strlcpy(command.key, key, MAXOPTSLEN); + + if (trace >= 1) + trace_prt(1, "call_read_execout %s %s\n", fname, key); + darg.data_ptr = (char *)&command; + darg.data_size = sizeof (command); + darg.desc_ptr = NULL; + darg.desc_num = 0; + darg.rbuf = line; + darg.rsize = linesz; + + ret = door_call(did_exec_map, &darg); + + lp = &line; + return (ret); +} diff --git a/usr/src/uts/common/os/condvar.c b/usr/src/uts/common/os/condvar.c index 71f20c6b67..4ac03cbddb 100644 --- a/usr/src/uts/common/os/condvar.c +++ b/usr/src/uts/common/os/condvar.c @@ -555,49 +555,45 @@ cv_wait_stop(kcondvar_t *cvp, kmutex_t *mp, int wakeup_time) (void) untimeout(id); /* - * Check for reasons to stop, and stop if lwp_nostop is zero. + * Check for reasons to stop, if lwp_nostop is not true. * See issig_forreal() for explanations of the various stops. - * Like issig_forreal(), we allow a PR_SUSPENDED/SUSPEND_NORMAL - * to occur even if lwp_nostop is set. */ mutex_enter(&p->p_lock); - while (!(p->p_flag & SEXITLWPS)) { + while (lwp->lwp_nostop == 0 && !(p->p_flag & SEXITLWPS)) { /* * Hold the lwp here for watchpoint manipulation. */ - if ((t->t_proc_flag & TP_PAUSE) && !lwp->lwp_nostop) { + if (t->t_proc_flag & TP_PAUSE) { stop(PR_SUSPENDED, SUSPEND_PAUSE); continue; } /* * System checkpoint. */ - if ((t->t_proc_flag & TP_CHKPT) && !lwp->lwp_nostop) { + if (t->t_proc_flag & TP_CHKPT) { stop(PR_CHECKPOINT, 0); continue; } /* * Honor fork1(), watchpoint activity (remapping a page), - * and lwp_suspend() regardless of whether lwp_nostop is - * set but not if lwp_nostop_r is set (to avoid a recursive - * call to prstop()). + * and lwp_suspend() requests. */ - if (((p->p_flag & (SHOLDFORK1|SHOLDWATCH)) || - (t->t_proc_flag & TP_HOLDLWP)) && !lwp->lwp_nostop_r) { + if ((p->p_flag & (SHOLDFORK1|SHOLDWATCH)) || + (t->t_proc_flag & TP_HOLDLWP)) { stop(PR_SUSPENDED, SUSPEND_NORMAL); continue; } /* * Honor /proc requested stop. */ - if ((t->t_proc_flag & TP_PRSTOP) && !lwp->lwp_nostop) { + if (t->t_proc_flag & TP_PRSTOP) { stop(PR_REQUESTED, 0); } /* * If some lwp in the process has already stopped * showing PR_JOBCONTROL, stop in sympathy with it. */ - if (p->p_stopsig && !lwp->lwp_nostop && (t != p->p_agenttp)) { + if (p->p_stopsig && t != p->p_agenttp) { stop(PR_JOBCONTROL, p->p_stopsig); continue; } diff --git a/usr/src/uts/common/os/sig.c b/usr/src/uts/common/os/sig.c index 5c72fb749b..69c1074816 100644 --- a/usr/src/uts/common/os/sig.c +++ b/usr/src/uts/common/os/sig.c @@ -447,10 +447,10 @@ issig_justlooking(void) if ((lwp->lwp_asleep && MUSTRETURN(p, t)) || (p->p_flag & (SEXITLWPS|SKILLED)) || - (!lwp->lwp_nostop_r && ((p->p_flag & (SHOLDFORK1|SHOLDWATCH)) | - (t->t_proc_flag & TP_HOLDLWP))) || - (!lwp->lwp_nostop && (p->p_stopsig | (t->t_proc_flag & - (TP_PRSTOP|TP_CHKPT|TP_PAUSE)))) || + (lwp->lwp_nostop == 0 && + (p->p_stopsig | (p->p_flag & (SHOLDFORK1|SHOLDWATCH)) | + (t->t_proc_flag & + (TP_PRSTOP|TP_HOLDLWP|TP_CHKPT|TP_PAUSE)))) || lwp->lwp_cursig) return (1); @@ -588,15 +588,9 @@ issig_forreal(void) * or is executing lwp_suspend() on this lwp. * Again, go back to top of loop to check if an exit * or hold event has occurred while stopped. - * We explicitly allow this form of stopping of one - * lwp in a process by another lwp in the same process, - * even if lwp->lwp_nostop is set, because otherwise a - * process can become deadlocked on a fork1(). - * Allow this only if lwp_nostop_r is not set, - * to avoid a recursive call to prstop(). */ if (((p->p_flag & (SHOLDFORK1|SHOLDWATCH)) || - (t->t_proc_flag & TP_HOLDLWP)) && !lwp->lwp_nostop_r) { + (t->t_proc_flag & TP_HOLDLWP)) && !lwp->lwp_nostop) { stop(PR_SUSPENDED, SUSPEND_NORMAL); continue; } @@ -863,11 +857,9 @@ stop(int why, int what) /* * Make sure we don't deadlock on a recursive call to prstop(). - * prstop() sets the lwp_nostop_r flag and increments lwp_nostop. + * prstop() sets the lwp_nostop flag. */ - if (lwp->lwp_nostop_r || - (lwp->lwp_nostop && - (why != PR_SUSPENDED || what != SUSPEND_NORMAL))) + if (lwp->lwp_nostop) return; /* diff --git a/usr/src/uts/common/sys/klwp.h b/usr/src/uts/common/sys/klwp.h index 7dea5b4941..93d1e9816f 100644 --- a/usr/src/uts/common/sys/klwp.h +++ b/usr/src/uts/common/sys/klwp.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -160,34 +160,12 @@ typedef struct _klwp { struct itimerval lwp_timer[3]; /* - * There are a number of places where you do not wish an lwp to - * be stopped due to some interaction with other lwps in the process. - * In these cases the lwp_nostop value is incremented. At places where - * the lwp would normally be stopped the stop is allowed if lwp_nostop - * is zero. There are a very few cases where even if lwp_nostop is set - * we need to allow the lwp to stop. In those cases the lwp is - * stopped if lwp_nostop_r is not set regardless of the state of - * lwp_nostop. These conditions are: - * - * 1. In issig_forreal() when another lwp is undergoing fork1() - * or watchpoint activity (p_flag contains either SHOLDFORK1 or - * SHOLDWATCH or t_proc_flag contains TP_HOLDLWP) - * - * 2. In stop() when the why argument is not PR_SUSPENDED or the what - * argument is not SUSPEND_NORMAL. - * - * 3. In cv_wait_stop() when another lwp is undergoing fork1() or - * watchpoint activity (p_flag contains either SHOLDFORK1 or - * SHOLDWATCH or t_proc_flag contains TP_HOLDLWP) - * - * lwp_nostop_r is set in prstop(). ie we honour the presence of - * SHOLDFORK1 or SHOLDWATCH or TP_HOLDLWP in the case of - * stop(PR_SUSPENDED, SUSPEND_NORMAL) + * used to stop/alert lwps */ char lwp_unused; char lwp_state; /* Running in User/Kernel mode (no lock req) */ - ushort_t lwp_nostop; /* Don't stop this lwp except SUSPEND_NORMAL */ - ushort_t lwp_nostop_r; /* Don't stop this lwp (avoid recursion) */ + ushort_t lwp_nostop; /* Don't stop this lwp (no lock required) */ + ushort_t lwp_pad; /* Reserved for future use */ /* * Last failed privilege. diff --git a/usr/src/uts/common/vm/vm_as.c b/usr/src/uts/common/vm/vm_as.c index 801e55659c..42df064cc2 100644 --- a/usr/src/uts/common/vm/vm_as.c +++ b/usr/src/uts/common/vm/vm_as.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -878,10 +878,8 @@ retry: * for a pagefault. This is to avoid deadlock while debugging * a process via /proc over NFS (in particular). */ - if (lwp != NULL) { + if (lwp != NULL) lwp->lwp_nostop++; - lwp->lwp_nostop_r++; - } /* * same length must be used when we softlock and softunlock. @@ -959,10 +957,8 @@ retry: seg = as_segat(as, raddr); if (seg == NULL) { AS_LOCK_EXIT(as, &as->a_lock); - if ((lwp != NULL) && (!is_xhat)) { + if ((lwp != NULL) && (!is_xhat)) lwp->lwp_nostop--; - lwp->lwp_nostop_r--; - } return (FC_NOMAP); } @@ -1042,10 +1038,9 @@ retry: } if (as_lock_held) AS_LOCK_EXIT(as, &as->a_lock); - if ((lwp != NULL) && (!is_xhat)) { + if ((lwp != NULL) && (!is_xhat)) lwp->lwp_nostop--; - lwp->lwp_nostop_r--; - } + /* * If the lower levels returned EDEADLK for a fault, * It means that we should retry the fault. Let's wait @@ -1083,10 +1078,8 @@ retry: * for a pagefault. This is to avoid deadlock while debugging * a process via /proc over NFS (in particular). */ - if (lwp != NULL) { + if (lwp != NULL) lwp->lwp_nostop++; - lwp->lwp_nostop_r++; - } raddr = (caddr_t)((uintptr_t)addr & (uintptr_t)PAGEMASK); rsize = (((size_t)(addr + size) + PAGEOFFSET) & PAGEMASK) - @@ -1096,10 +1089,8 @@ retry: seg = as_segat(as, raddr); if (seg == NULL) { AS_LOCK_EXIT(as, &as->a_lock); - if (lwp != NULL) { + if (lwp != NULL) lwp->lwp_nostop--; - lwp->lwp_nostop_r--; - } return (FC_NOMAP); } @@ -1116,10 +1107,8 @@ retry: break; } AS_LOCK_EXIT(as, &as->a_lock); - if (lwp != NULL) { + if (lwp != NULL) lwp->lwp_nostop--; - lwp->lwp_nostop_r--; - } /* * If the lower levels returned EDEADLK for a fault, * It means that we should retry the fault. Let's wait diff --git a/usr/src/uts/intel/fs/proc/prmachdep.c b/usr/src/uts/intel/fs/proc/prmachdep.c index f9a9fc3247..caebfab916 100644 --- a/usr/src/uts/intel/fs/proc/prmachdep.c +++ b/usr/src/uts/intel/fs/proc/prmachdep.c @@ -433,11 +433,11 @@ prstop(int why, int what) struct regs *r = lwptoregs(lwp); /* - * Make sure we don't deadlock on a recursive call to prstop(). - * stop() tests the lwp_nostop_r and lwp_nostop flags. + * Make sure we don't deadlock on a recursive call + * to prstop(). stop() tests the lwp_nostop flag. */ - lwp->lwp_nostop_r++; - lwp->lwp_nostop++; + ASSERT(lwp->lwp_nostop == 0); + lwp->lwp_nostop = 1; if (copyin_nowatch((caddr_t)r->r_pc, &lwp->lwp_pcb.pcb_instr, sizeof (lwp->lwp_pcb.pcb_instr)) == 0) @@ -448,8 +448,8 @@ prstop(int why, int what) } (void) save_syscall_args(); - lwp->lwp_nostop--; - lwp->lwp_nostop_r--; + ASSERT(lwp->lwp_nostop == 1); + lwp->lwp_nostop = 0; } /* diff --git a/usr/src/uts/sparc/fs/proc/prmachdep.c b/usr/src/uts/sparc/fs/proc/prmachdep.c index 3d27ecff08..bca9d0bb2d 100644 --- a/usr/src/uts/sparc/fs/proc/prmachdep.c +++ b/usr/src/uts/sparc/fs/proc/prmachdep.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * 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. @@ -21,7 +20,7 @@ */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -881,11 +880,11 @@ prstop(int why, int what) extern void fp_prsave(kfpu_t *); /* - * Make sure we don't deadlock on a recursive call to prstop(). - * stop() tests the lwp_nostop_r and lwp_nostop flags. + * Make sure we don't deadlock on a recursive call + * to prstop(). stop() tests the lwp_nostop flag. */ - lwp->lwp_nostop_r++; - lwp->lwp_nostop++; + ASSERT(lwp->lwp_nostop == 0); + lwp->lwp_nostop = 1; (void) flush_user_windows_to_stack(NULL); if (lwp->lwp_pcb.pcb_step != STEP_NONE) (void) prundostep(); @@ -968,8 +967,8 @@ prstop(int why, int what) } (void) save_syscall_args(); - lwp->lwp_nostop--; - lwp->lwp_nostop_r--; + ASSERT(lwp->lwp_nostop == 1); + lwp->lwp_nostop = 0; } /* |