Mercurial > illumos > illumos-gate
changeset 3930:59477feabc54
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)
author | nr123932 |
---|---|
date | Fri, 30 Mar 2007 01:55:41 -0700 |
parents | ef76fe400493 |
children | 0347144fd43b |
files | usr/src/cmd/fs.d/autofs/Makefile usr/src/cmd/fs.d/autofs/autod_main.c usr/src/cmd/fs.d/autofs/autod_mount.c usr/src/cmd/fs.d/autofs/automount.h usr/src/cmd/fs.d/autofs/ns_files.c usr/src/uts/common/os/condvar.c usr/src/uts/common/os/sig.c usr/src/uts/common/sys/klwp.h usr/src/uts/common/vm/vm_as.c usr/src/uts/intel/fs/proc/prmachdep.c usr/src/uts/sparc/fs/proc/prmachdep.c |
diffstat | 11 files changed, 310 insertions(+), 135 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/fs.d/autofs/Makefile Fri Mar 30 01:18:25 2007 -0700 +++ b/usr/src/cmd/fs.d/autofs/Makefile Fri Mar 30 01:55:41 2007 -0700 @@ -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 @@ 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
--- a/usr/src/cmd/fs.d/autofs/autod_main.c Fri Mar 30 01:18:25 2007 -0700 +++ b/usr/src/cmd/fs.d/autofs/autod_main.c Fri Mar 30 01:55:41 2007 -0700 @@ -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 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 @@ 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 @@ 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 @@ (*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); +}
--- a/usr/src/cmd/fs.d/autofs/autod_mount.c Fri Mar 30 01:18:25 2007 -0700 +++ b/usr/src/cmd/fs.d/autofs/autod_mount.c Fri Mar 30 01:55:41 2007 -0700 @@ -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); +}
--- a/usr/src/cmd/fs.d/autofs/automount.h Fri Mar 30 01:18:25 2007 -0700 +++ b/usr/src/cmd/fs.d/autofs/automount.h Fri Mar 30 01:55:41 2007 -0700 @@ -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 @@ #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 *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 __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
--- a/usr/src/cmd/fs.d/autofs/ns_files.c Fri Mar 30 01:18:25 2007 -0700 +++ b/usr/src/cmd/fs.d/autofs/ns_files.c Fri Mar 30 01:55:41 2007 -0700 @@ -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 @@ 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 @@ 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); +}
--- a/usr/src/uts/common/os/condvar.c Fri Mar 30 01:18:25 2007 -0700 +++ b/usr/src/uts/common/os/condvar.c Fri Mar 30 01:55:41 2007 -0700 @@ -555,49 +555,45 @@ (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; }
--- a/usr/src/uts/common/os/sig.c Fri Mar 30 01:18:25 2007 -0700 +++ b/usr/src/uts/common/os/sig.c Fri Mar 30 01:55:41 2007 -0700 @@ -447,10 +447,10 @@ 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 @@ * 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 @@ /* * 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; /*
--- a/usr/src/uts/common/sys/klwp.h Fri Mar 30 01:18:25 2007 -0700 +++ b/usr/src/uts/common/sys/klwp.h Fri Mar 30 01:55:41 2007 -0700 @@ -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 @@ 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.
--- a/usr/src/uts/common/vm/vm_as.c Fri Mar 30 01:18:25 2007 -0700 +++ b/usr/src/uts/common/vm/vm_as.c Fri Mar 30 01:55:41 2007 -0700 @@ -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 @@ * 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 @@ 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 @@ } 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 @@ * 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 @@ 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 @@ 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
--- a/usr/src/uts/intel/fs/proc/prmachdep.c Fri Mar 30 01:18:25 2007 -0700 +++ b/usr/src/uts/intel/fs/proc/prmachdep.c Fri Mar 30 01:55:41 2007 -0700 @@ -433,11 +433,11 @@ 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 @@ } (void) save_syscall_args(); - lwp->lwp_nostop--; - lwp->lwp_nostop_r--; + ASSERT(lwp->lwp_nostop == 1); + lwp->lwp_nostop = 0; } /*
--- a/usr/src/uts/sparc/fs/proc/prmachdep.c Fri Mar 30 01:18:25 2007 -0700 +++ b/usr/src/uts/sparc/fs/proc/prmachdep.c Fri Mar 30 01:55:41 2007 -0700 @@ -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 @@ 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 @@ } (void) save_syscall_args(); - lwp->lwp_nostop--; - lwp->lwp_nostop_r--; + ASSERT(lwp->lwp_nostop == 1); + lwp->lwp_nostop = 0; } /*