4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  27 /*        All Rights Reserved   */
  28 
  29 #include <sys/types.h>
  30 #include <sys/param.h>
  31 #include <sys/sysmacros.h>
  32 #include <sys/proc.h>
  33 #include <sys/kmem.h>
  34 #include <sys/tuneable.h>
  35 #include <sys/var.h>
  36 #include <sys/cred.h>
  37 #include <sys/systm.h>
  38 #include <sys/prsystm.h>
  39 #include <sys/vnode.h>
  40 #include <sys/session.h>
  41 #include <sys/cpuvar.h>
  42 #include <sys/cmn_err.h>
  43 #include <sys/bitmap.h>
 
 
  95 static pid_t mpid = FAMOUS_PIDS;        /* one more than the last famous pid */
  96 static union procent *procdir;
  97 static union procent *procentfree;
  98 
  99 static struct pid *
 100 pid_lookup(pid_t pid)
 101 {
 102         struct pid *pidp;
 103 
 104         ASSERT(MUTEX_HELD(&pidlinklock));
 105 
 106         for (pidp = HASHPID(pid); pidp; pidp = pidp->pid_link) {
 107                 if (pidp->pid_id == pid) {
 108                         ASSERT(pidp->pid_ref > 0);
 109                         break;
 110                 }
 111         }
 112         return (pidp);
 113 }
 114 
 115 void
 116 pid_setmin(void)
 117 {
 118         if (jump_pid && jump_pid > mpid)
 119                 minpid = mpid = jump_pid;
 120         else
 121                 minpid = mpid;
 122 }
 123 
 124 /*
 125  * When prslots are simply used as an index to determine a process' p_lock,
 126  * adjacent prslots share adjacent p_locks.  On machines where the size
 127  * of a mutex is smaller than that of a cache line (which, as of this writing,
 128  * is true for all machines on which Solaris runs), this can potentially
 129  * induce false sharing.  The standard solution for false sharing is to pad
 130  * out one's data structures (in this case, struct plock).  However,
 131  * given the size and (generally) sparse use of the proc_lock array, this
 132  * is suboptimal.  We therefore stride through the proc_lock array with
 133  * a stride of PLOCK_SHIFT.  PLOCK_SHIFT should be defined as:
 134  *
 
 504         p->p_proc_flag |= P_PR_LOCK;
 505         THREAD_KPRI_REQUEST();
 506 }
 507 
 508 void
 509 sprunlock(proc_t *p)
 510 {
 511         if (panicstr) {
 512                 mutex_exit(&p->p_lock);
 513                 return;
 514         }
 515 
 516         ASSERT(p->p_proc_flag & P_PR_LOCK);
 517         ASSERT(MUTEX_HELD(&p->p_lock));
 518 
 519         cv_signal(&pr_pid_cv[p->p_slot]);
 520         p->p_proc_flag &= ~P_PR_LOCK;
 521         mutex_exit(&p->p_lock);
 522         THREAD_KPRI_RELEASE();
 523 }
 524 
 525 void
 526 pid_init(void)
 527 {
 528         int i;
 529 
 530         pid_hashsz = 1 << highbit(v.v_proc / pid_hashlen);
 531 
 532         pidhash = kmem_zalloc(sizeof (struct pid *) * pid_hashsz, KM_SLEEP);
 533         procdir = kmem_alloc(sizeof (union procent) * v.v_proc, KM_SLEEP);
 534         pr_pid_cv = kmem_zalloc(sizeof (kcondvar_t) * v.v_proc, KM_SLEEP);
 535         proc_lock = kmem_zalloc(sizeof (struct plock) * v.v_proc, KM_SLEEP);
 536 
 537         nproc = 1;
 538         practive = proc_sched;
 539         proc_sched->p_next = NULL;
 540         procdir[0].pe_proc = proc_sched;
 541 
 542         procentfree = &procdir[1];
 543         for (i = 1; i < v.v_proc - 1; i++)
 
 | 
 
 
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2015 Joyent, Inc.
  25  */
  26 
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  28 /*        All Rights Reserved   */
  29 
  30 #include <sys/types.h>
  31 #include <sys/param.h>
  32 #include <sys/sysmacros.h>
  33 #include <sys/proc.h>
  34 #include <sys/kmem.h>
  35 #include <sys/tuneable.h>
  36 #include <sys/var.h>
  37 #include <sys/cred.h>
  38 #include <sys/systm.h>
  39 #include <sys/prsystm.h>
  40 #include <sys/vnode.h>
  41 #include <sys/session.h>
  42 #include <sys/cpuvar.h>
  43 #include <sys/cmn_err.h>
  44 #include <sys/bitmap.h>
 
 
  96 static pid_t mpid = FAMOUS_PIDS;        /* one more than the last famous pid */
  97 static union procent *procdir;
  98 static union procent *procentfree;
  99 
 100 static struct pid *
 101 pid_lookup(pid_t pid)
 102 {
 103         struct pid *pidp;
 104 
 105         ASSERT(MUTEX_HELD(&pidlinklock));
 106 
 107         for (pidp = HASHPID(pid); pidp; pidp = pidp->pid_link) {
 108                 if (pidp->pid_id == pid) {
 109                         ASSERT(pidp->pid_ref > 0);
 110                         break;
 111                 }
 112         }
 113         return (pidp);
 114 }
 115 
 116 struct pid *
 117 pid_find(pid_t pid)
 118 {
 119         struct pid *pidp;
 120 
 121         mutex_enter(&pidlinklock);
 122         pidp = pid_lookup(pid);
 123         mutex_exit(&pidlinklock);
 124 
 125         return (pidp);
 126 }
 127 
 128 void
 129 pid_setmin(void)
 130 {
 131         if (jump_pid && jump_pid > mpid)
 132                 minpid = mpid = jump_pid;
 133         else
 134                 minpid = mpid;
 135 }
 136 
 137 /*
 138  * When prslots are simply used as an index to determine a process' p_lock,
 139  * adjacent prslots share adjacent p_locks.  On machines where the size
 140  * of a mutex is smaller than that of a cache line (which, as of this writing,
 141  * is true for all machines on which Solaris runs), this can potentially
 142  * induce false sharing.  The standard solution for false sharing is to pad
 143  * out one's data structures (in this case, struct plock).  However,
 144  * given the size and (generally) sparse use of the proc_lock array, this
 145  * is suboptimal.  We therefore stride through the proc_lock array with
 146  * a stride of PLOCK_SHIFT.  PLOCK_SHIFT should be defined as:
 147  *
 
 517         p->p_proc_flag |= P_PR_LOCK;
 518         THREAD_KPRI_REQUEST();
 519 }
 520 
 521 void
 522 sprunlock(proc_t *p)
 523 {
 524         if (panicstr) {
 525                 mutex_exit(&p->p_lock);
 526                 return;
 527         }
 528 
 529         ASSERT(p->p_proc_flag & P_PR_LOCK);
 530         ASSERT(MUTEX_HELD(&p->p_lock));
 531 
 532         cv_signal(&pr_pid_cv[p->p_slot]);
 533         p->p_proc_flag &= ~P_PR_LOCK;
 534         mutex_exit(&p->p_lock);
 535         THREAD_KPRI_RELEASE();
 536 }
 537 
 538 /*
 539  * Undo effects of sprlock but without dropping p->p_lock
 540  */
 541 void
 542 sprunprlock(proc_t *p)
 543 {
 544         ASSERT(p->p_proc_flag & P_PR_LOCK);
 545         ASSERT(MUTEX_HELD(&p->p_lock));
 546 
 547         cv_signal(&pr_pid_cv[p->p_slot]);
 548         p->p_proc_flag &= ~P_PR_LOCK;
 549         THREAD_KPRI_RELEASE();
 550 }
 551 
 552 void
 553 pid_init(void)
 554 {
 555         int i;
 556 
 557         pid_hashsz = 1 << highbit(v.v_proc / pid_hashlen);
 558 
 559         pidhash = kmem_zalloc(sizeof (struct pid *) * pid_hashsz, KM_SLEEP);
 560         procdir = kmem_alloc(sizeof (union procent) * v.v_proc, KM_SLEEP);
 561         pr_pid_cv = kmem_zalloc(sizeof (kcondvar_t) * v.v_proc, KM_SLEEP);
 562         proc_lock = kmem_zalloc(sizeof (struct plock) * v.v_proc, KM_SLEEP);
 563 
 564         nproc = 1;
 565         practive = proc_sched;
 566         proc_sched->p_next = NULL;
 567         procdir[0].pe_proc = proc_sched;
 568 
 569         procentfree = &procdir[1];
 570         for (i = 1; i < v.v_proc - 1; i++)
 
 |