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++)
|