usr/src/uts/common/disp/thread.c
author Joshua M. Clulow <jmc@joyent.com>
Mon, 04 Mar 2013 23:52:56 +0000
changeset 14188 afe390b9f1e0
parent 13146 8315ff49e22e
permissions -rw-r--r--
4020 Make ldi_ev_remove_callbacks safe to use in LDI callbacks Reviewed by: Robert Mustacchi <[email protected]> Approved by: Dan McDonald <[email protected]>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1217
diff changeset
     5
 * Common Development and Distribution License (the "License").
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1217
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
6247
ad4c702ff226 PSARC 2007/661 delete sched_nice
raf
parents: 5834
diff changeset
    21
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
13146
8315ff49e22e 6958308 XSAVE/XRSTOR mechanism to save and restore processor state
Kuriakose Kuruvilla <kuriakose.kuruvilla@oracle.com>
parents: 11292
diff changeset
    23
 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
#include <sys/types.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
#include <sys/param.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
#include <sys/sysmacros.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
#include <sys/signal.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    30
#include <sys/stack.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
#include <sys/pcb.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
#include <sys/user.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
#include <sys/systm.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
#include <sys/sysinfo.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
#include <sys/errno.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
#include <sys/cmn_err.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
#include <sys/cred.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
#include <sys/resource.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
#include <sys/task.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
#include <sys/project.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
#include <sys/proc.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
#include <sys/debug.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
#include <sys/disp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
#include <sys/class.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include <vm/seg_kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
#include <vm/seg_kp.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <sys/machlock.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <sys/kmem.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <sys/varargs.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
#include <sys/turnstile.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
#include <sys/poll.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
#include <sys/vtrace.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
#include <sys/callb.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
#include <c2/audit.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
#include <sys/tnf.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
#include <sys/sobject.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
#include <sys/cpupart.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
#include <sys/pset.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
#include <sys/door.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#include <sys/spl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
#include <sys/copyops.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
#include <sys/rctl.h>
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2646
diff changeset
    63
#include <sys/brand.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include <sys/pool.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
#include <sys/zone.h>
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1217
diff changeset
    66
#include <sys/tsol/label.h>
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1217
diff changeset
    67
#include <sys/tsol/tndb.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
#include <sys/cpc_impl.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
#include <sys/sdt.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
#include <sys/reboot.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
#include <sys/kdi.h>
6247
ad4c702ff226 PSARC 2007/661 delete sched_nice
raf
parents: 5834
diff changeset
    72
#include <sys/schedctl.h>
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
    73
#include <sys/waitq.h>
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
    74
#include <sys/cpucaps.h>
5206
34f0b41fc3c5 6608681 PSARC/2007/173 kiconv - framework and kiconv_emea (phase 1)
is
parents: 5023
diff changeset
    75
#include <sys/kiconv.h>
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
struct kmem_cache *thread_cache;	/* cache of free threads */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
struct kmem_cache *lwp_cache;		/* cache of free lwps */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
struct kmem_cache *turnstile_cache;	/* cache of free turnstiles */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
 * allthreads is only for use by kmem_readers.  All kernel loops can use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
 * the current thread as a start/end point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
static kthread_t *allthreads = &t0;	/* circular list of all threads */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
static kcondvar_t reaper_cv;		/* synchronization var */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
kthread_t	*thread_deathrow;	/* circular list of reapable threads */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
kthread_t	*lwp_deathrow;		/* circular list of reapable threads */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
kmutex_t	reaplock;		/* protects lwp and thread deathrows */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
int	thread_reapcnt = 0;		/* number of threads on deathrow */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
int	lwp_reapcnt = 0;		/* number of lwps on deathrow */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
int	reaplimit = 16;			/* delay reaping until reaplimit */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
5788
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
    95
thread_free_lock_t	*thread_free_lock;
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
    96
					/* protects tick thread from reaper */
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
    97
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
extern int nthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
11173
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11066
diff changeset
   100
/* System Scheduling classes. */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
id_t	syscid;				/* system scheduling class ID */
11173
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11066
diff changeset
   102
id_t	sysdccid = CLASS_UNUSED;	/* reset when SDC loads */
87f3734e64df 6881015 ZFS write activity prevents other threads from running in a timely manner
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11066
diff changeset
   103
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
void	*segkp_thread;			/* cookie for segkp pool */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
int lwp_cache_sz = 32;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
int t_cache_sz = 8;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
static kt_did_t next_t_id = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
6298
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 6247
diff changeset
   110
/* Default mode for thread binding to CPUs and processor sets */
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 6247
diff changeset
   111
int default_binding_mode = TB_ALLHARD;
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 6247
diff changeset
   112
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
 * Min/Max stack sizes for stack size parameters
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
#define	MAX_STKSIZE	(32 * DEFAULTSTKSZ)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
#define	MIN_STKSIZE	DEFAULTSTKSZ
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
 * default_stksize overrides lwp_default_stksize if it is set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
int	default_stksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
int	lwp_default_stksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
static zone_key_t zone_thread_key;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
7854
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   127
unsigned int kmem_stackinfo;		/* stackinfo feature on-off */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   128
kmem_stkinfo_t *kmem_stkinfo_log;	/* stackinfo circular log */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   129
static kmutex_t kmem_stkinfo_lock;	/* protects kmem_stkinfo_log */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   130
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
 * forward declarations for internal thread specific data (tsd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
static void *tsd_realloc(void *, size_t, size_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
4036
9db83fcc6245 5078264 assertion failure: proc_pageout != NULL, file: ../../common/vm/vm_page.c
praks
parents: 3868
diff changeset
   136
void thread_reaper(void);
9db83fcc6245 5078264 assertion failure: proc_pageout != NULL, file: ../../common/vm/vm_page.c
praks
parents: 3868
diff changeset
   137
7854
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   138
/* forward declarations for stackinfo feature */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   139
static void stkinfo_begin(kthread_t *);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   140
static void stkinfo_end(kthread_t *);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   141
static size_t stkinfo_percent(caddr_t, caddr_t, caddr_t);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   142
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
static int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
turnstile_constructor(void *buf, void *cdrarg, int kmflags)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
	bzero(buf, sizeof (turnstile_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
/*ARGSUSED*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
turnstile_destructor(void *buf, void *cdrarg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
	turnstile_t *ts = buf;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
	ASSERT(ts->ts_free == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
	ASSERT(ts->ts_waiters == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
	ASSERT(ts->ts_inheritor == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
	ASSERT(ts->ts_sleepq[0].sq_first == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
	ASSERT(ts->ts_sleepq[1].sq_first == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
thread_init(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	kthread_t *tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
	extern char sys_name[];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
	extern void idle();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
	struct cpu *cpu = CPU;
5788
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   171
	int i;
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   172
	kmutex_t *lp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
	mutex_init(&reaplock, NULL, MUTEX_SPIN, (void *)ipltospl(DISP_LEVEL));
5788
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   175
	thread_free_lock =
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   176
	    kmem_alloc(sizeof (thread_free_lock_t) * THREAD_FREE_NUM, KM_SLEEP);
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   177
	for (i = 0; i < THREAD_FREE_NUM; i++) {
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   178
		lp = &thread_free_lock[i].tf_lock;
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   179
		mutex_init(lp, NULL, MUTEX_DEFAULT, NULL);
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   180
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
#if defined(__i386) || defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	thread_cache = kmem_cache_create("thread_cache", sizeof (kthread_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
	    PTR24_ALIGN, NULL, NULL, NULL, NULL, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
	 * "struct _klwp" includes a "struct pcb", which includes a
13146
8315ff49e22e 6958308 XSAVE/XRSTOR mechanism to save and restore processor state
Kuriakose Kuruvilla <kuriakose.kuruvilla@oracle.com>
parents: 11292
diff changeset
   188
	 * "struct fpu", which needs to be 64-byte aligned on amd64
8315ff49e22e 6958308 XSAVE/XRSTOR mechanism to save and restore processor state
Kuriakose Kuruvilla <kuriakose.kuruvilla@oracle.com>
parents: 11292
diff changeset
   189
	 * (and even on i386) for xsave/xrstor.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
	lwp_cache = kmem_cache_create("lwp_cache", sizeof (klwp_t),
13146
8315ff49e22e 6958308 XSAVE/XRSTOR mechanism to save and restore processor state
Kuriakose Kuruvilla <kuriakose.kuruvilla@oracle.com>
parents: 11292
diff changeset
   192
	    64, NULL, NULL, NULL, NULL, NULL, 0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
	 * Allocate thread structures from static_arena.  This prevents
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
	 * issues where a thread tries to relocate its own thread
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	 * structure and touches it after the mapping has been suspended.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
	thread_cache = kmem_cache_create("thread_cache", sizeof (kthread_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
	    PTR24_ALIGN, NULL, NULL, NULL, NULL, static_arena, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
2005
dffa1ddbabfa 6301942 system crashes with overwritten machpcb
elowe
parents: 1845
diff changeset
   202
	lwp_stk_cache_init();
dffa1ddbabfa 6301942 system crashes with overwritten machpcb
elowe
parents: 1845
diff changeset
   203
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
	lwp_cache = kmem_cache_create("lwp_cache", sizeof (klwp_t),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
	    0, NULL, NULL, NULL, NULL, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	turnstile_cache = kmem_cache_create("turnstile_cache",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	    sizeof (turnstile_t), 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
	    turnstile_constructor, turnstile_destructor, NULL, NULL, NULL, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1217
diff changeset
   212
	label_init();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
	cred_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
   215
	/*
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
   216
	 * Initialize various resource management facilities.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
   217
	 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
	rctl_init();
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
   219
	cpucaps_init();
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
   220
	/*
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
   221
	 * Zone_init() should be called before project_init() so that project ID
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
   222
	 * for the first project is initialized correctly.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
   223
	 */
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
   224
	zone_init();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	project_init();
2712
f74a135872bc PSARC/2005/471 BrandZ: Support for non-native zones
nn35248
parents: 2646
diff changeset
   226
	brand_init();
5206
34f0b41fc3c5 6608681 PSARC/2007/173 kiconv - framework and kiconv_emea (phase 1)
is
parents: 5023
diff changeset
   227
	kiconv_init();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	task_init();
1676
37f4a3e2bd99 PSARC/2002/762 Layered Trusted Solaris
jpk
parents: 1217
diff changeset
   229
	tcache_init();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
	pool_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	curthread->t_ts = kmem_cache_alloc(turnstile_cache, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
	 * Originally, we had two parameters to set default stack
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
	 * size: one for lwp's (lwp_default_stksize), and one for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
	 * kernel-only threads (DEFAULTSTKSZ, a.k.a. _defaultstksz).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
	 * Now we have a third parameter that overrides both if it is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
	 * set to a legal stack size, called default_stksize.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
	if (default_stksize == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
		default_stksize = DEFAULTSTKSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	} else if (default_stksize % PAGESIZE != 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
	    default_stksize > MAX_STKSIZE ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
	    default_stksize < MIN_STKSIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
		cmn_err(CE_WARN, "Illegal stack size. Using %d",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
		    (int)DEFAULTSTKSZ);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
		default_stksize = DEFAULTSTKSZ;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
		lwp_default_stksize = default_stksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
	if (lwp_default_stksize == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
		lwp_default_stksize = default_stksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
	} else if (lwp_default_stksize % PAGESIZE != 0 ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
	    lwp_default_stksize > MAX_STKSIZE ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
	    lwp_default_stksize < MIN_STKSIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
		cmn_err(CE_WARN, "Illegal stack size. Using %d",
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
		    default_stksize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
		lwp_default_stksize = default_stksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	segkp_lwp = segkp_cache_init(segkp, lwp_cache_sz,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
	    lwp_default_stksize,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
	    (KPD_NOWAIT | KPD_HASREDZONE | KPD_LOCKED));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
	segkp_thread = segkp_cache_init(segkp, t_cache_sz,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
	    default_stksize, KPD_HASREDZONE | KPD_LOCKED | KPD_NO_ANON);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
	(void) getcid(sys_name, &syscid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
	curthread->t_cid = syscid;	/* current thread is t0 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
	 * Set up the first CPU's idle thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
	 * It runs whenever the CPU has nothing worthwhile to do.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
	tp = thread_create(NULL, 0, idle, NULL, 0, &p0, TS_STOPPED, -1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
	cpu->cpu_idle_thread = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	tp->t_preempt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
	tp->t_disp_queue = cpu->cpu_disp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
	ASSERT(tp->t_disp_queue != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
	tp->t_bound_cpu = cpu;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
	tp->t_affinitycnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
	 * Registering a thread in the callback table is usually
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
	 * done in the initialization code of the thread. In this
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	 * case, we do it right after thread creation to avoid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
	 * blocking idle thread while registering itself. It also
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	 * avoids the possibility of reregistration in case a CPU
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
	 * restarts its idle thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
	CALLB_CPR_INIT_SAFE(tp, "idle");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
	/*
4036
9db83fcc6245 5078264 assertion failure: proc_pageout != NULL, file: ../../common/vm/vm_page.c
praks
parents: 3868
diff changeset
   297
	 * Create the thread_reaper daemon. From this point on, exited
9db83fcc6245 5078264 assertion failure: proc_pageout != NULL, file: ../../common/vm/vm_page.c
praks
parents: 3868
diff changeset
   298
	 * threads will get reaped.
9db83fcc6245 5078264 assertion failure: proc_pageout != NULL, file: ../../common/vm/vm_page.c
praks
parents: 3868
diff changeset
   299
	 */
9db83fcc6245 5078264 assertion failure: proc_pageout != NULL, file: ../../common/vm/vm_page.c
praks
parents: 3868
diff changeset
   300
	(void) thread_create(NULL, 0, (void (*)())thread_reaper,
9db83fcc6245 5078264 assertion failure: proc_pageout != NULL, file: ../../common/vm/vm_page.c
praks
parents: 3868
diff changeset
   301
	    NULL, 0, &p0, TS_RUN, minclsyspri);
9db83fcc6245 5078264 assertion failure: proc_pageout != NULL, file: ../../common/vm/vm_page.c
praks
parents: 3868
diff changeset
   302
9db83fcc6245 5078264 assertion failure: proc_pageout != NULL, file: ../../common/vm/vm_page.c
praks
parents: 3868
diff changeset
   303
	/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
	 * Finish initializing the kernel memory allocator now that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
	 * thread_create() is available.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
	kmem_thread_init();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
	if (boothowto & RB_DEBUG)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
		kdi_dvec_thravail();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
 * Create a thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
 * thread_create() blocks for memory if necessary.  It never fails.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
 * If stk is NULL, the thread is created at the base of the stack
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
 * and cannot be swapped.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
kthread_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
thread_create(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   323
	caddr_t	stk,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
	size_t	stksize,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
	void	(*proc)(),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   326
	void	*arg,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
	size_t	len,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
	proc_t	 *pp,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
	int	state,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
	pri_t	pri)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
	kthread_t *t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	extern struct classfuncs sys_classfuncs;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
	turnstile_t *ts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
	 * Every thread keeps a turnstile around in case it needs to block.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
	 * The only reason the turnstile is not simply part of the thread
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	 * structure is that we may have to break the association whenever
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
	 * more than one thread blocks on a given synchronization object.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   341
	 * From a memory-management standpoint, turnstiles are like the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
	 * "attached mblks" that hang off dblks in the streams allocator.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
	ts = kmem_cache_alloc(turnstile_cache, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
	if (stk == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
		 * alloc both thread and stack in segkp chunk
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   349
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
		if (stksize < default_stksize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
			stksize = default_stksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
		if (stksize == default_stksize) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
			stk = (caddr_t)segkp_cache_get(segkp_thread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
			stksize = roundup(stksize, PAGESIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
			stk = (caddr_t)segkp_get(segkp, stksize,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   359
			    (KPD_HASREDZONE | KPD_NO_ANON | KPD_LOCKED));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
		ASSERT(stk != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
		 * The machine-dependent mutex code may require that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
		 * thread pointers (since they may be used for mutex owner
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
		 * fields) have certain alignment requirements.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
		 * PTR24_ALIGN is the size of the alignment quanta.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
		 * XXX - assumes stack grows toward low addresses.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
		if (stksize <= sizeof (kthread_t) + PTR24_ALIGN)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
			cmn_err(CE_PANIC, "thread_create: proposed stack size"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
			    " too small to hold thread.");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
#ifdef STACK_GROWTH_DOWN
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
		stksize -= SA(sizeof (kthread_t) + PTR24_ALIGN - 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
		stksize &= -PTR24_ALIGN;	/* make thread aligned */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
		t = (kthread_t *)(stk + stksize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
		bzero(t, sizeof (kthread_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
		if (audit_active)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
			audit_thread_create(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
		t->t_stk = stk + stksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
		t->t_stkbase = stk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
#else	/* stack grows to larger addresses */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
		stksize -= SA(sizeof (kthread_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
		t = (kthread_t *)(stk);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
		bzero(t, sizeof (kthread_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
		t->t_stk = stk + sizeof (kthread_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
		t->t_stkbase = stk + stksize + sizeof (kthread_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
#endif	/* STACK_GROWTH_DOWN */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
		t->t_flag |= T_TALLOCSTK;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
		t->t_swap = stk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
		t = kmem_cache_alloc(thread_cache, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
		bzero(t, sizeof (kthread_t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
		ASSERT(((uintptr_t)t & (PTR24_ALIGN - 1)) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
		if (audit_active)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
			audit_thread_create(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
		 * Initialize t_stk to the kernel stack pointer to use
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
		 * upon entry to the kernel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
#ifdef STACK_GROWTH_DOWN
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
		t->t_stk = stk + stksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
		t->t_stkbase = stk;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
#else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
		t->t_stk = stk;			/* 3b2-like */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
		t->t_stkbase = stk + stksize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   408
#endif /* STACK_GROWTH_DOWN */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
7854
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   411
	if (kmem_stackinfo != 0) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   412
		stkinfo_begin(t);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   413
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   414
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
	t->t_ts = ts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
	 * p_cred could be NULL if it thread_create is called before cred_init
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
	 * is called in main.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   421
	mutex_enter(&pp->p_crlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
	if (pp->p_cred)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
		crhold(t->t_cred = pp->p_cred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
	mutex_exit(&pp->p_crlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
	t->t_start = gethrestime_sec();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
	t->t_startpc = proc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
	t->t_procp = pp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	t->t_clfuncs = &sys_classfuncs.thread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
	t->t_cid = syscid;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
	t->t_pri = pri;
11066
cebb50cbe4f9 PSARC/2009/396 Tickless Kernel Architecture / lbolt decoupling
Rafael Vanoni <rafael.vanoni@sun.com>
parents: 9717
diff changeset
   431
	t->t_stime = ddi_get_lbolt();
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
	t->t_schedflag = TS_LOAD | TS_DONT_SWAP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
	t->t_bind_cpu = PBIND_NONE;
6298
060278005c21 PSARC 2008/138 Soft CPU and processor set bindings
akolb
parents: 6247
diff changeset
   434
	t->t_bindflag = (uchar_t)default_binding_mode;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
	t->t_bind_pset = PS_NONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
	t->t_plockp = &pp->p_lock;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	t->t_copyops = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	t->t_taskq = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
	t->t_anttime = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	t->t_hatdepth = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
	t->t_dtrace_vtime = 1;	/* assure vtimestamp is always non-zero */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
	CPU_STATS_ADDQ(CPU, sys, nthreads, 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
#ifndef NPROBE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   446
	/* Kernel probe */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
	tnf_thread_create(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
#endif /* NPROBE */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
	LOCK_INIT_CLEAR(&t->t_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
	 * Callers who give us a NULL proc must do their own
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
	 * stack initialization.  e.g. lwp_create()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
	if (proc != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
		t->t_stk = thread_stk_init(t->t_stk);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
		thread_load(t, proc, arg, len);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
	 * Put a hold on project0. If this thread is actually in a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
	 * different project, then t_proj will be changed later in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
	 * lwp_create().  All kernel-only threads must be in project 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
	t->t_proj = project_hold(proj0p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
	lgrp_affinity_init(&t->t_lgrp_affinity);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
	nthread++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   471
	t->t_did = next_t_id++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
	t->t_prev = curthread->t_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
	t->t_next = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
	 * Add the thread to the list of all threads, and initialize
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
	 * its t_cpu pointer.  We need to block preemption since
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
	 * cpu_offline walks the thread list looking for threads
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
	 * with t_cpu pointing to the CPU being offlined.  We want
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
	 * to make sure that the list is consistent and that if t_cpu
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
	 * is set, the thread is on the list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
	kpreempt_disable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
	curthread->t_prev->t_next = t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
	curthread->t_prev = t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
	 * Threads should never have a NULL t_cpu pointer so assign it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
	 * here.  If the thread is being created with state TS_RUN a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
	 * better CPU may be chosen when it is placed on the run queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
	 * We need to keep kernel preemption disabled when setting all
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
	 * three fields to keep them in sync.  Also, always create in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
	 * the default partition since that's where kernel threads go
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
	 * (if this isn't a kernel thread, t_cpupart will be changed
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
	 * in lwp_create before setting the thread runnable).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
	t->t_cpupart = &cp_default;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
	 * For now, affiliate this thread with the root lgroup.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
	 * Since the kernel does not (presently) allocate its memory
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
	 * in a locality aware fashion, the root is an appropriate home.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
	 * If this thread is later associated with an lwp, it will have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
	 * it's lgroup re-assigned at that time.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
	lgrp_move_thread(t, &cp_default.cp_lgrploads[LGRP_ROOTID], 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
	 * Inherit the current cpu.  If this cpu isn't part of the chosen
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
	 * lgroup, a new cpu will be chosen by cpu_choose when the thread
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
	 * is ready to run.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
	if (CPU->cpu_part == &cp_default)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
		t->t_cpu = CPU;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
		t->t_cpu = disp_lowpri_cpu(cp_default.cp_cpulist, t->t_lpl,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
		    t->t_pri, NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
	t->t_disp_queue = t->t_cpu->cpu_disp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
	kpreempt_enable();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
	 * Initialize thread state and the dispatcher lock pointer.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
	 * Need to hold onto pidlock to block allthreads walkers until
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
	 * the state is set.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
	switch (state) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
	case TS_RUN:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
		curthread->t_oldspl = splhigh();	/* get dispatcher spl */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
		THREAD_SET_STATE(t, TS_STOPPED, &transition_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
		CL_SETRUN(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
		thread_unlock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
	case TS_ONPROC:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
		THREAD_ONPROC(t, t->t_cpu);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
	case TS_FREE:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
		 * Free state will be used for intr threads.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
		 * The interrupt routine must set the thread dispatcher
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
		 * lock pointer (t_lockp) if starting on a CPU
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
		 * other than the current one.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
		THREAD_FREEINTR(t, CPU);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
	case TS_STOPPED:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
		THREAD_SET_STATE(t, TS_STOPPED, &stop_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
		break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
	default:			/* TS_SLEEP, TS_ZOMB or TS_TRANS */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
		cmn_err(CE_PANIC, "thread_create: invalid state %d", state);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
	return (t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
 * Move thread to project0 and take care of project reference counters.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
thread_rele(kthread_t *t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
	kproject_t *kpj;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
	thread_lock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
	ASSERT(t == curthread || t->t_state == TS_FREE || t->t_procp == &p0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
	kpj = ttoproj(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
	t->t_proj = proj0p;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
	thread_unlock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
	if (kpj != proj0p) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
		project_rele(kpj);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
		(void) project_hold(proj0p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
void
5023
e0c678e511a7 6203568 accumulating number of threads behind rw_lock in ire_walk_ill_tables IRB_REFRELE
carlsonj
parents: 4686
diff changeset
   584
thread_exit(void)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
	kthread_t *t = curthread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
	if ((t->t_proc_flag & TP_ZTHREAD) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
		cmn_err(CE_PANIC, "thread_exit: zthread_exit() not called");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
	tsd_exit();		/* Clean up this thread's TSD */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
	kcpc_passivate();	/* clean up performance counter state */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
	 * No kernel thread should have called poll() without arranging
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
	 * calling pollcleanup() here.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
	ASSERT(t->t_pollstate == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
	ASSERT(t->t_schedctl == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
	if (t->t_door)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
		door_slam();	/* in case thread did an upcall */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
#ifndef NPROBE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
	/* Kernel probe */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
	if (t->t_tnf_tpdp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
		tnf_thread_exit();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
#endif /* NPROBE */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
	thread_rele(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
	t->t_preempt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
	 * remove thread from the all threads list so that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
	 * death-row can use the same pointers.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
	t->t_next->t_prev = t->t_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
	t->t_prev->t_next = t->t_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
	ASSERT(allthreads != t);	/* t0 never exits */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
	cv_broadcast(&t->t_joincv);	/* wake up anyone in thread_join */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
	if (t->t_ctx != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
		exitctx(t);
1217
f95ffdc997b7 6219276 need per-process equivalent of device context
rab
parents: 641
diff changeset
   626
	if (t->t_procp->p_pctx != NULL)
f95ffdc997b7 6219276 need per-process equivalent of device context
rab
parents: 641
diff changeset
   627
		exitpctx(t->t_procp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
7854
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   629
	if (kmem_stackinfo != 0) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   630
		stkinfo_end(t);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   631
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
   632
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
	t->t_state = TS_ZOMB;	/* set zombie thread */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
	swtch_from_zombie();	/* give up the CPU */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
	/* NOTREACHED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
 * Check to see if the specified thread is active (defined as being on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
 * the thread list).  This is certainly a slow way to do this; if there's
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
 * ever a reason to speed it up, we could maintain a hash table of active
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
 * threads indexed by their t_did.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
static kthread_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
did_to_thread(kt_did_t tid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
	kthread_t *t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
	ASSERT(MUTEX_HELD(&pidlock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
	for (t = curthread->t_next; t != curthread; t = t->t_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
		if (t->t_did == tid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
	if (t->t_did == tid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
		return (t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
 * Wait for specified thread to exit.  Returns immediately if the thread
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
 * could not be found, meaning that it has either already exited or never
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
 * existed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
thread_join(kt_did_t tid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
	kthread_t *t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
	ASSERT(tid != curthread->t_did);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
	ASSERT(tid != t0.t_did);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
	mutex_enter(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
	 * Make sure we check that the thread is on the thread list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
	 * before blocking on it; otherwise we could end up blocking on
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
	 * a cv that's already been freed.  In other words, don't cache
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
	 * the thread pointer across calls to cv_wait.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
	 * The choice of loop invariant means that whenever a thread
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
	 * is taken off the allthreads list, a cv_broadcast must be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	 * performed on that thread's t_joincv to wake up any waiters.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
	 * The broadcast doesn't have to happen right away, but it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	 * shouldn't be postponed indefinitely (e.g., by doing it in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
	 * thread_free which may only be executed when the deathrow
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
	 * queue is processed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
	while (t = did_to_thread(tid))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
		cv_wait(&t->t_joincv, &pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
	mutex_exit(&pidlock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
void
5788
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   695
thread_free_prevent(kthread_t *t)
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   696
{
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   697
	kmutex_t *lp;
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   698
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   699
	lp = &thread_free_lock[THREAD_FREE_HASH(t)].tf_lock;
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   700
	mutex_enter(lp);
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   701
}
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   702
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   703
void
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   704
thread_free_allow(kthread_t *t)
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   705
{
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   706
	kmutex_t *lp;
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   707
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   708
	lp = &thread_free_lock[THREAD_FREE_HASH(t)].tf_lock;
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   709
	mutex_exit(lp);
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   710
}
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   711
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   712
static void
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   713
thread_free_barrier(kthread_t *t)
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   714
{
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   715
	kmutex_t *lp;
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   716
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   717
	lp = &thread_free_lock[THREAD_FREE_HASH(t)].tf_lock;
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   718
	mutex_enter(lp);
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   719
	mutex_exit(lp);
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   720
}
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   721
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   722
void
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
thread_free(kthread_t *t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
{
11292
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   725
	boolean_t allocstk = (t->t_flag & T_TALLOCSTK);
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   726
	klwp_t *lwp = t->t_lwp;
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   727
	caddr_t swap = t->t_swap;
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   728
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
	ASSERT(t != &t0 && t->t_state == TS_FREE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
	ASSERT(t->t_door == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
	ASSERT(t->t_schedctl == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
	ASSERT(t->t_pollstate == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
	t->t_pri = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
	t->t_pc = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
	t->t_sp = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
	t->t_wchan0 = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
	t->t_wchan = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
	if (t->t_cred != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
		crfree(t->t_cred);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
		t->t_cred = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
	if (t->t_pdmsg) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
		kmem_free(t->t_pdmsg, strlen(t->t_pdmsg) + 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
		t->t_pdmsg = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
	if (audit_active)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
		audit_thread_free(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
#ifndef NPROBE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
	if (t->t_tnf_tpdp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
		tnf_thread_free(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
#endif /* NPROBE */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
	if (t->t_cldata) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
		CL_EXITCLASS(t->t_cid, (caddr_t *)t->t_cldata);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
	if (t->t_rprof != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
		kmem_free(t->t_rprof, sizeof (*t->t_rprof));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
		t->t_rprof = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
	t->t_lockp = NULL;	/* nothing should try to lock this thread now */
11292
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   761
	if (lwp)
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   762
		lwp_freeregs(lwp, 0);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
	if (t->t_ctx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
		freectx(t, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
	t->t_stk = NULL;
11292
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   766
	if (lwp)
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   767
		lwp_stk_fini(lwp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
	lock_clear(&t->t_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
	if (t->t_ts->ts_waiters > 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
		panic("thread_free: turnstile still active");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
	kmem_cache_free(turnstile_cache, t->t_ts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
	free_afd(&t->t_activefd);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
	/*
5788
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   778
	 * Barrier for the tick accounting code.  The tick accounting code
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   779
	 * holds this lock to keep the thread from going away while it's
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   780
	 * looking at it.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
	 */
5788
9b0eb06889bb 6619224 Tick accounting needs to be made scalable
mv143129
parents: 5753
diff changeset
   782
	thread_free_barrier(t);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
	ASSERT(ttoproj(t) == proj0p);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
	project_rele(ttoproj(t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
	lgrp_affinity_free(&t->t_lgrp_affinity);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
11292
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   789
	mutex_enter(&pidlock);
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   790
	nthread--;
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   791
	mutex_exit(&pidlock);
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   792
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
	/*
11292
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   794
	 * Free thread, lwp and stack.  This needs to be done carefully, since
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   795
	 * if T_TALLOCSTK is set, the thread is part of the stack.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
	 */
11292
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   797
	t->t_lwp = NULL;
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   798
	t->t_swap = NULL;
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   799
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   800
	if (swap) {
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   801
		segkp_release(segkp, swap);
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   802
	}
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   803
	if (lwp) {
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   804
		kmem_cache_free(lwp_cache, lwp);
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   805
	}
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   806
	if (!allocstk) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
		kmem_cache_free(thread_cache, t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
 * Removes threads associated with the given zone from a deathrow queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
 * tp is a pointer to the head of the deathrow queue, and countp is a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
 * pointer to the current deathrow count.  Returns a linked list of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
 * threads removed from the list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
static kthread_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
thread_zone_cleanup(kthread_t **tp, int *countp, zoneid_t zoneid)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
	kthread_t *tmp, *list = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
	cred_t *cr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
	ASSERT(MUTEX_HELD(&reaplock));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
	while (*tp != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
		if ((cr = (*tp)->t_cred) != NULL && crgetzoneid(cr) == zoneid) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
			tmp = *tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
			*tp = tmp->t_forw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
			tmp->t_forw = list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
			list = tmp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
			(*countp)--;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
			tp = &(*tp)->t_forw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
	return (list);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
thread_reap_list(kthread_t *t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
	kthread_t *next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
	while (t != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
		next = t->t_forw;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
		thread_free(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
		t = next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
thread_zone_destroy(zoneid_t zoneid, void *unused)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
	kthread_t *t, *l;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   856
	mutex_enter(&reaplock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   857
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   858
	 * Pull threads and lwps associated with zone off deathrow lists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   859
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
	t = thread_zone_cleanup(&thread_deathrow, &thread_reapcnt, zoneid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   861
	l = thread_zone_cleanup(&lwp_deathrow, &lwp_reapcnt, zoneid);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
	mutex_exit(&reaplock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   863
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
	/*
5834
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   865
	 * Guard against race condition in mutex_owner_running:
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   866
	 * 	thread=owner(mutex)
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   867
	 * 	<interrupt>
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   868
	 * 				thread exits mutex
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   869
	 * 				thread exits
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   870
	 * 				thread reaped
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   871
	 * 				thread struct freed
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   872
	 * cpu = thread->t_cpu <- BAD POINTER DEREFERENCE.
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   873
	 * A cross call to all cpus will cause the interrupt handler
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   874
	 * to reset the PC if it is in mutex_owner_running, refreshing
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   875
	 * stale thread pointers.
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   876
	 */
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   877
	mutex_sync();   /* sync with mutex code */
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   878
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   879
	/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
	 * Reap threads
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
	thread_reap_list(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
	 * Reap lwps
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
	thread_reap_list(l);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
 * cleanup zombie threads that are on deathrow.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
thread_reaper()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
	kthread_t *t, *l;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
	callb_cpr_t cprinfo;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
	 * Register callback to clean up threads when zone is destroyed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
	zone_key_create(&zone_thread_key, NULL, NULL, thread_zone_destroy);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
	CALLB_CPR_INIT(&cprinfo, &reaplock, callb_generic_cpr, "t_reaper");
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
		mutex_enter(&reaplock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
		while (thread_deathrow == NULL && lwp_deathrow == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
			CALLB_CPR_SAFE_BEGIN(&cprinfo);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
			cv_wait(&reaper_cv, &reaplock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
			CALLB_CPR_SAFE_END(&cprinfo, &reaplock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
		}
5834
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   912
		/*
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   913
		 * mutex_sync() needs to be called when reaping, but
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   914
		 * not too often.  We limit reaping rate to once
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   915
		 * per second.  Reaplimit is max rate at which threads can
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   916
		 * be freed. Does not impact thread destruction/creation.
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   917
		 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
		t = thread_deathrow;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
		l = lwp_deathrow;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
		thread_deathrow = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
		lwp_deathrow = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
		thread_reapcnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
		lwp_reapcnt = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   924
		mutex_exit(&reaplock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   925
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   926
		/*
5834
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   927
		 * Guard against race condition in mutex_owner_running:
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   928
		 * 	thread=owner(mutex)
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   929
		 * 	<interrupt>
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   930
		 * 				thread exits mutex
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   931
		 * 				thread exits
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   932
		 * 				thread reaped
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   933
		 * 				thread struct freed
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   934
		 * cpu = thread->t_cpu <- BAD POINTER DEREFERENCE.
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   935
		 * A cross call to all cpus will cause the interrupt handler
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   936
		 * to reset the PC if it is in mutex_owner_running, refreshing
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   937
		 * stale thread pointers.
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   938
		 */
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   939
		mutex_sync();   /* sync with mutex code */
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   940
		/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   941
		 * Reap threads
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   942
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   943
		thread_reap_list(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   944
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   945
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   946
		 * Reap lwps
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   947
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   948
		thread_reap_list(l);
5834
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   949
		delay(hz);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   950
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   951
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   952
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   953
/*
5834
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   954
 * This is called by lwpcreate, etc.() to put a lwp_deathrow thread onto
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   955
 * thread_deathrow. The thread's state is changed already TS_FREE to indicate
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   956
 * that is reapable. The thread already holds the reaplock, and was already
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   957
 * freed.
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   958
 */
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   959
void
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   960
reapq_move_lq_to_tq(kthread_t *t)
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   961
{
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   962
	ASSERT(t->t_state == TS_FREE);
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   963
	ASSERT(MUTEX_HELD(&reaplock));
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   964
	t->t_forw = thread_deathrow;
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   965
	thread_deathrow = t;
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   966
	thread_reapcnt++;
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   967
	if (lwp_reapcnt + thread_reapcnt > reaplimit)
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   968
		cv_signal(&reaper_cv);  /* wake the reaper */
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   969
}
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   970
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   971
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   972
 * This is called by resume() to put a zombie thread onto deathrow.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   973
 * The thread's state is changed to TS_FREE to indicate that is reapable.
5834
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
   974
 * This is called from the idle thread so it must not block - just spin.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   975
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   976
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   977
reapq_add(kthread_t *t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   978
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   979
	mutex_enter(&reaplock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   980
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   981
	/*
11292
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   982
	 * lwp_deathrow contains threads with lwp linkage and
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   983
	 * swappable thread stacks which have the default stacksize.
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   984
	 * These threads' lwps and stacks may be reused by lwp_create().
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   985
	 *
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   986
	 * Anything else goes on thread_deathrow(), where it will eventually
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   987
	 * be thread_free()d.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   988
	 */
11292
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   989
	if (t->t_flag & T_LWPREUSE) {
f9f7f6a68749 6905982 panic: NULL pointer dereference in anon_get_ptr() in swapout thread
Jonathan Adams <Jonathan.Adams@Sun.COM>
parents: 11173
diff changeset
   990
		ASSERT(ttolwp(t) != NULL);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   991
		t->t_forw = lwp_deathrow;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   992
		lwp_deathrow = t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   993
		lwp_reapcnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   994
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   995
		t->t_forw = thread_deathrow;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   996
		thread_deathrow = t;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   997
		thread_reapcnt++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   998
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   999
	if (lwp_reapcnt + thread_reapcnt > reaplimit)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1000
		cv_signal(&reaper_cv);	/* wake the reaper */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1001
	t->t_state = TS_FREE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1002
	lock_clear(&t->t_lock);
4686
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1003
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1004
	/*
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1005
	 * Before we return, we need to grab and drop the thread lock for
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1006
	 * the dead thread.  At this point, the current thread is the idle
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1007
	 * thread, and the dead thread's CPU lock points to the current
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1008
	 * CPU -- and we must grab and drop the lock to synchronize with
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1009
	 * a racing thread walking a blocking chain that the zombie thread
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1010
	 * was recently in.  By this point, that blocking chain is (by
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1011
	 * definition) stale:  the dead thread is not holding any locks, and
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1012
	 * is therefore not in any blocking chains -- but if we do not regrab
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1013
	 * our lock before freeing the dead thread's data structures, the
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1014
	 * thread walking the (stale) blocking chain will die on memory
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1015
	 * corruption when it attempts to drop the dead thread's lock.  We
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1016
	 * only need do this once because there is no way for the dead thread
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1017
	 * to ever again be on a blocking chain:  once we have grabbed and
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1018
	 * dropped the thread lock, we are guaranteed that anyone that could
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1019
	 * have seen this thread in a blocking chain can no longer see it.
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1020
	 */
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1021
	thread_lock(t);
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1022
	thread_unlock(t);
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1023
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1024
	mutex_exit(&reaplock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1025
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1026
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1027
/*
1217
f95ffdc997b7 6219276 need per-process equivalent of device context
rab
parents: 641
diff changeset
  1028
 * Install thread context ops for the current thread.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1029
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1030
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1031
installctx(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1032
	kthread_t *t,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1033
	void	*arg,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1034
	void	(*save)(void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1035
	void	(*restore)(void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1036
	void	(*fork)(void *, void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1037
	void	(*lwp_create)(void *, void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1038
	void	(*exit)(void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1039
	void	(*free)(void *, int))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1040
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1041
	struct ctxop *ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1042
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1043
	ctx = kmem_alloc(sizeof (struct ctxop), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1044
	ctx->save_op = save;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1045
	ctx->restore_op = restore;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1046
	ctx->fork_op = fork;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1047
	ctx->lwp_create_op = lwp_create;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1048
	ctx->exit_op = exit;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1049
	ctx->free_op = free;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1050
	ctx->arg = arg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1051
	ctx->next = t->t_ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1052
	t->t_ctx = ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1053
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1054
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1055
/*
2646
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1056
 * Remove the thread context ops from a thread.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1057
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1058
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1059
removectx(
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1060
	kthread_t *t,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1061
	void	*arg,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1062
	void	(*save)(void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1063
	void	(*restore)(void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1064
	void	(*fork)(void *, void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1065
	void	(*lwp_create)(void *, void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1066
	void	(*exit)(void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1067
	void	(*free)(void *, int))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1068
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1069
	struct ctxop *ctx, *prev_ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1070
2646
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1071
	/*
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1072
	 * The incoming kthread_t (which is the thread for which the
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1073
	 * context ops will be removed) should be one of the following:
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1074
	 *
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1075
	 * a) the current thread,
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1076
	 *
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1077
	 * b) a thread of a process that's being forked (SIDL),
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1078
	 *
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1079
	 * c) a thread that belongs to the same process as the current
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1080
	 *    thread and for which the current thread is the agent thread,
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1081
	 *
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1082
	 * d) a thread that is TS_STOPPED which is indicative of it
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1083
	 *    being (if curthread is not an agent) a thread being created
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1084
	 *    as part of an lwp creation.
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1085
	 */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1086
	ASSERT(t == curthread || ttoproc(t)->p_stat == SIDL ||
2337
2076d8738ffa backout 6351092: causes 6447223
dm120769
parents: 2328
diff changeset
  1087
	    ttoproc(t)->p_agenttp == curthread || t->t_state == TS_STOPPED);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1088
2646
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1089
	/*
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1090
	 * Serialize modifications to t->t_ctx to prevent the agent thread
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1091
	 * and the target thread from racing with each other during lwp exit.
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1092
	 */
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1093
	mutex_enter(&t->t_ctx_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1094
	prev_ctx = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1095
	for (ctx = t->t_ctx; ctx != NULL; ctx = ctx->next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1096
		if (ctx->save_op == save && ctx->restore_op == restore &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1097
		    ctx->fork_op == fork && ctx->lwp_create_op == lwp_create &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1098
		    ctx->exit_op == exit && ctx->free_op == free &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1099
		    ctx->arg == arg) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1100
			if (prev_ctx)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1101
				prev_ctx->next = ctx->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1102
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1103
				t->t_ctx = ctx->next;
2646
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1104
			mutex_exit(&t->t_ctx_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1105
			if (ctx->free_op != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1106
				(ctx->free_op)(ctx->arg, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1107
			kmem_free(ctx, sizeof (struct ctxop));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1108
			return (1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1109
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1110
		prev_ctx = ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1111
	}
2646
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1112
	mutex_exit(&t->t_ctx_lock);
5c699a479a2a 6351092 Race for t_ctx in removectx() can lead to panic.
trevtom
parents: 2337
diff changeset
  1113
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1114
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1115
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1116
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1117
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1118
savectx(kthread_t *t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1119
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1120
	struct ctxop *ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1121
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1122
	ASSERT(t == curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1123
	for (ctx = t->t_ctx; ctx != 0; ctx = ctx->next)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1124
		if (ctx->save_op != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1125
			(ctx->save_op)(ctx->arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1126
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1127
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1128
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1129
restorectx(kthread_t *t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1130
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1131
	struct ctxop *ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1132
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1133
	ASSERT(t == curthread);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1134
	for (ctx = t->t_ctx; ctx != 0; ctx = ctx->next)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1135
		if (ctx->restore_op != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1136
			(ctx->restore_op)(ctx->arg);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1137
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1138
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1139
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1140
forkctx(kthread_t *t, kthread_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1141
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1142
	struct ctxop *ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1143
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1144
	for (ctx = t->t_ctx; ctx != NULL; ctx = ctx->next)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1145
		if (ctx->fork_op != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1146
			(ctx->fork_op)(t, ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1147
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1148
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1149
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1150
 * Note that this operator is only invoked via the _lwp_create
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1151
 * system call.  The system may have other reasons to create lwps
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1152
 * e.g. the agent lwp or the doors unreferenced lwp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1153
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1154
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1155
lwp_createctx(kthread_t *t, kthread_t *ct)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1156
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1157
	struct ctxop *ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1158
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1159
	for (ctx = t->t_ctx; ctx != NULL; ctx = ctx->next)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1160
		if (ctx->lwp_create_op != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1161
			(ctx->lwp_create_op)(t, ct);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1162
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1163
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1164
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1165
 * exitctx is called from thread_exit() and lwp_exit() to perform any actions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1166
 * needed when the thread/LWP leaves the processor for the last time. This
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1167
 * routine is not intended to deal with freeing memory; freectx() is used for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1168
 * that purpose during thread_free(). This routine is provided to allow for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1169
 * clean-up that can't wait until thread_free().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1170
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1171
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1172
exitctx(kthread_t *t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1173
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1174
	struct ctxop *ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1175
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1176
	for (ctx = t->t_ctx; ctx != NULL; ctx = ctx->next)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1177
		if (ctx->exit_op != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1178
			(ctx->exit_op)(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1179
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1180
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1181
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1182
 * freectx is called from thread_free() and exec() to get
1217
f95ffdc997b7 6219276 need per-process equivalent of device context
rab
parents: 641
diff changeset
  1183
 * rid of old thread context ops.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1184
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1185
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1186
freectx(kthread_t *t, int isexec)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1187
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1188
	struct ctxop *ctx;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1189
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1190
	while ((ctx = t->t_ctx) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1191
		t->t_ctx = ctx->next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1192
		if (ctx->free_op != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1193
			(ctx->free_op)(ctx->arg, isexec);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1194
		kmem_free(ctx, sizeof (struct ctxop));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1195
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1196
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1197
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1198
/*
5834
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1199
 * freectx_ctx is called from lwp_create() when lwp is reused from
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1200
 * lwp_deathrow and its thread structure is added to thread_deathrow.
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1201
 * The thread structure to which this ctx was attached may be already
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1202
 * freed by the thread reaper so free_op implementations shouldn't rely
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1203
 * on thread structure to which this ctx was attached still being around.
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1204
 */
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1205
void
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1206
freectx_ctx(struct ctxop *ctx)
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1207
{
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1208
	struct ctxop *nctx;
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1209
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1210
	ASSERT(ctx != NULL);
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1211
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1212
	do {
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1213
		nctx = ctx->next;
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1214
		if (ctx->free_op != NULL)
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1215
			(ctx->free_op)(ctx->arg, 0);
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1216
		kmem_free(ctx, sizeof (struct ctxop));
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1217
	} while ((ctx = nctx) != NULL);
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1218
}
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1219
66e26b3fbcc7 6182418 mutex_vector_enter has scaling issues on 25k
pt157919
parents: 5788
diff changeset
  1220
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1221
 * Set the thread running; arrange for it to be swapped in if necessary.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1222
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1223
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1224
setrun_locked(kthread_t *t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1225
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1226
	ASSERT(THREAD_LOCK_HELD(t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1227
	if (t->t_state == TS_SLEEP) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1228
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1229
		 * Take off sleep queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1230
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1231
		SOBJ_UNSLEEP(t->t_sobj_ops, t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1232
	} else if (t->t_state & (TS_RUN | TS_ONPROC)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1233
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1234
		 * Already on dispatcher queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1235
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1236
		return;
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1237
	} else if (t->t_state == TS_WAIT) {
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1238
		waitq_setrun(t);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1239
	} else if (t->t_state == TS_STOPPED) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1240
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1241
		 * All of the sending of SIGCONT (TC_XSTART) and /proc
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1242
		 * (TC_PSTART) and lwp_continue() (TC_CSTART) must have
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1243
		 * requested that the thread be run.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1244
		 * Just calling setrun() is not sufficient to set a stopped
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1245
		 * thread running.  TP_TXSTART is always set if the thread
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1246
		 * is not stopped by a jobcontrol stop signal.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1247
		 * TP_TPSTART is always set if /proc is not controlling it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1248
		 * TP_TCSTART is always set if lwp_suspend() didn't stop it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1249
		 * The thread won't be stopped unless one of these
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1250
		 * three mechanisms did it.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1251
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1252
		 * These flags must be set before calling setrun_locked(t).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1253
		 * They can't be passed as arguments because the streams
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1254
		 * code calls setrun() indirectly and the mechanism for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1255
		 * doing so admits only one argument.  Note that the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1256
		 * thread must be locked in order to change t_schedflags.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1257
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1258
		if ((t->t_schedflag & TS_ALLSTART) != TS_ALLSTART)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1259
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1260
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1261
		 * Process is no longer stopped (a thread is running).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1262
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1263
		t->t_whystop = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1264
		t->t_whatstop = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1265
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1266
		 * Strictly speaking, we do not have to clear these
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1267
		 * flags here; they are cleared on entry to stop().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1268
		 * However, they are confusing when doing kernel
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1269
		 * debugging or when they are revealed by ps(1).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1270
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1271
		t->t_schedflag &= ~TS_ALLSTART;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1272
		THREAD_TRANSITION(t);	/* drop stopped-thread lock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1273
		ASSERT(t->t_lockp == &transition_lock);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1274
		ASSERT(t->t_wchan0 == NULL && t->t_wchan == NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1275
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1276
		 * Let the class put the process on the dispatcher queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1277
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1278
		CL_SETRUN(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1279
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1280
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1281
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1282
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1283
setrun(kthread_t *t)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1284
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1285
	thread_lock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1286
	setrun_locked(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1287
	thread_unlock(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1288
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1289
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1290
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1291
 * Unpin an interrupted thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1292
 *	When an interrupt occurs, the interrupt is handled on the stack
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1293
 *	of an interrupt thread, taken from a pool linked to the CPU structure.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1294
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1295
 *	When swtch() is switching away from an interrupt thread because it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1296
 *	blocked or was preempted, this routine is called to complete the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1297
 *	saving of the interrupted thread state, and returns the interrupted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1298
 *	thread pointer so it may be resumed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1299
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1300
 *	Called by swtch() only at high spl.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1301
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1302
kthread_t *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1303
thread_unpin()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1304
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1305
	kthread_t	*t = curthread;	/* current thread */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1306
	kthread_t	*itp;		/* interrupted thread */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1307
	int		i;		/* interrupt level */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1308
	extern int	intr_passivate();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1309
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1310
	ASSERT(t->t_intr != NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1311
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1312
	itp = t->t_intr;		/* interrupted thread */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1313
	t->t_intr = NULL;		/* clear interrupt ptr */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1314
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1315
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1316
	 * Get state from interrupt thread for the one
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1317
	 * it interrupted.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1318
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1319
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1320
	i = intr_passivate(t, itp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1322
	TRACE_5(TR_FAC_INTR, TR_INTR_PASSIVATE,
4686
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1323
	    "intr_passivate:level %d curthread %p (%T) ithread %p (%T)",
8b4b414c2f6f 6472192 panic in cv_wait when exiting a process
qiao
parents: 4136
diff changeset
  1324
	    i, t, t, itp, itp);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1325
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1326
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1327
	 * Dissociate the current thread from the interrupted thread's LWP.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1328
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1329
	t->t_lwp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1330
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1331
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1332
	 * Interrupt handlers above the level that spinlocks block must
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1333
	 * not block.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1334
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1335
#if DEBUG
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1336
	if (i < 0 || i > LOCK_LEVEL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1337
		cmn_err(CE_PANIC, "thread_unpin: ipl out of range %x", i);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1338
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1339
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1340
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1341
	 * Compute the CPU's base interrupt level based on the active
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1342
	 * interrupts.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1343
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1344
	ASSERT(CPU->cpu_intr_actv & (1 << i));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1345
	set_base_spl();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1346
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1347
	return (itp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1348
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1349
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1350
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1351
 * Create and initialize an interrupt thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1352
 *	Returns non-zero on error.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1353
 *	Called at spl7() or better.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1354
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1355
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1356
thread_create_intr(struct cpu *cp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1357
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1358
	kthread_t *tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1359
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1360
	tp = thread_create(NULL, 0,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1361
	    (void (*)())thread_create_intr, NULL, 0, &p0, TS_ONPROC, 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1362
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1363
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1364
	 * Set the thread in the TS_FREE state.  The state will change
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1365
	 * to TS_ONPROC only while the interrupt is active.  Think of these
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1366
	 * as being on a private free list for the CPU.  Being TS_FREE keeps
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1367
	 * inactive interrupt threads out of debugger thread lists.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1368
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1369
	 * We cannot call thread_create with TS_FREE because of the current
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1370
	 * checks there for ONPROC.  Fix this when thread_create takes flags.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1371
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1372
	THREAD_FREEINTR(tp, cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1373
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1374
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1375
	 * Nobody should ever reference the credentials of an interrupt
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1376
	 * thread so make it NULL to catch any such references.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1377
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1378
	tp->t_cred = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1379
	tp->t_flag |= T_INTR_THREAD;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1380
	tp->t_cpu = cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1381
	tp->t_bound_cpu = cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1382
	tp->t_disp_queue = cp->cpu_disp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1383
	tp->t_affinitycnt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1384
	tp->t_preempt = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1385
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1386
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1387
	 * Don't make a user-requested binding on this thread so that
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1388
	 * the processor can be offlined.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1389
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1390
	tp->t_bind_cpu = PBIND_NONE;	/* no USER-requested binding */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1391
	tp->t_bind_pset = PS_NONE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1392
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1393
#if defined(__i386) || defined(__amd64)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1394
	tp->t_stk -= STACK_ALIGN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1395
	*(tp->t_stk) = 0;		/* terminate intr thread stack */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1396
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1397
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1398
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1399
	 * Link onto CPU's interrupt pool.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1400
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1401
	tp->t_link = cp->cpu_intr_thread;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1402
	cp->cpu_intr_thread = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1403
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1404
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1405
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1406
 * TSD -- THREAD SPECIFIC DATA
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1407
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1408
static kmutex_t		tsd_mutex;	 /* linked list spin lock */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1409
static uint_t		tsd_nkeys;	 /* size of destructor array */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1410
/* per-key destructor funcs */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1411
static void 		(**tsd_destructor)(void *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1412
/* list of tsd_thread's */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1413
static struct tsd_thread	*tsd_list;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1414
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1415
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1416
 * Default destructor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1417
 *	Needed because NULL destructor means that the key is unused
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1418
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1419
/* ARGSUSED */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1420
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1421
tsd_defaultdestructor(void *value)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1422
{}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1423
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1424
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1425
 * Create a key (index into per thread array)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1426
 *	Locks out tsd_create, tsd_destroy, and tsd_exit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1427
 *	May allocate memory with lock held
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1428
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1429
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1430
tsd_create(uint_t *keyp, void (*destructor)(void *))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1431
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1432
	int	i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1433
	uint_t	nkeys;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1434
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1435
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1436
	 * if key is allocated, do nothing
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1437
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1438
	mutex_enter(&tsd_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1439
	if (*keyp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1440
		mutex_exit(&tsd_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1441
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1442
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1443
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1444
	 * find an unused key
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1445
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1446
	if (destructor == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1447
		destructor = tsd_defaultdestructor;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1448
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1449
	for (i = 0; i < tsd_nkeys; ++i)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1450
		if (tsd_destructor[i] == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1451
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1452
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1453
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1454
	 * if no unused keys, increase the size of the destructor array
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1455
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1456
	if (i == tsd_nkeys) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1457
		if ((nkeys = (tsd_nkeys << 1)) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1458
			nkeys = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1459
		tsd_destructor =
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1460
		    (void (**)(void *))tsd_realloc((void *)tsd_destructor,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1461
		    (size_t)(tsd_nkeys * sizeof (void (*)(void *))),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1462
		    (size_t)(nkeys * sizeof (void (*)(void *))));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1463
		tsd_nkeys = nkeys;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1464
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1465
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1466
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1467
	 * allocate the next available unused key
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1468
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1469
	tsd_destructor[i] = destructor;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1470
	*keyp = i + 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1471
	mutex_exit(&tsd_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1472
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1473
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1474
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1475
 * Destroy a key -- this is for unloadable modules
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1476
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1477
 * Assumes that the caller is preventing tsd_set and tsd_get
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1478
 * Locks out tsd_create, tsd_destroy, and tsd_exit
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1479
 * May free memory with lock held
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1480
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1481
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1482
tsd_destroy(uint_t *keyp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1483
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1484
	uint_t key;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1485
	struct tsd_thread *tsd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1486
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1487
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1488
	 * protect the key namespace and our destructor lists
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1489
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1490
	mutex_enter(&tsd_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1491
	key = *keyp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1492
	*keyp = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1493
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1494
	ASSERT(key <= tsd_nkeys);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1495
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1496
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1497
	 * if the key is valid
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1498
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1499
	if (key != 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1500
		uint_t k = key - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1501
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1502
		 * for every thread with TSD, call key's destructor
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1503
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1504
		for (tsd = tsd_list; tsd; tsd = tsd->ts_next) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1505
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1506
			 * no TSD for key in this thread
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1507
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1508
			if (key > tsd->ts_nkeys)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1509
				continue;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1510
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1511
			 * call destructor for key
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1512
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1513
			if (tsd->ts_value[k] && tsd_destructor[k])
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1514
				(*tsd_destructor[k])(tsd->ts_value[k]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1515
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1516
			 * reset value for key
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1517
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1518
			tsd->ts_value[k] = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1519
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1520
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1521
		 * actually free the key (NULL destructor == unused)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1522
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1523
		tsd_destructor[k] = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1524
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1525
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1526
	mutex_exit(&tsd_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1527
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1528
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1529
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1530
 * Quickly return the per thread value that was stored with the specified key
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1531
 * Assumes the caller is protecting key from tsd_create and tsd_destroy
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1532
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1533
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1534
tsd_get(uint_t key)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1535
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1536
	return (tsd_agent_get(curthread, key));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1537
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1538
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1539
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1540
 * Set a per thread value indexed with the specified key
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1541
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1542
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1543
tsd_set(uint_t key, void *value)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1544
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1545
	return (tsd_agent_set(curthread, key, value));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1546
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1547
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1548
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1549
 * Like tsd_get(), except that the agent lwp can get the tsd of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1550
 * another thread in the same process (the agent thread only runs when the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1551
 * process is completely stopped by /proc), or syslwp is creating a new lwp.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1552
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1553
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1554
tsd_agent_get(kthread_t *t, uint_t key)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1555
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1556
	struct tsd_thread *tsd = t->t_tsd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1557
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1558
	ASSERT(t == curthread ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1559
	    ttoproc(t)->p_agenttp == curthread || t->t_state == TS_STOPPED);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1560
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1561
	if (key && tsd != NULL && key <= tsd->ts_nkeys)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1562
		return (tsd->ts_value[key - 1]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1563
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1564
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1565
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1566
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1567
 * Like tsd_set(), except that the agent lwp can set the tsd of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1568
 * another thread in the same process, or syslwp can set the tsd
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1569
 * of a thread it's in the middle of creating.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1570
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1571
 * Assumes the caller is protecting key from tsd_create and tsd_destroy
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1572
 * May lock out tsd_destroy (and tsd_create), may allocate memory with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1573
 * lock held
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1574
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1575
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1576
tsd_agent_set(kthread_t *t, uint_t key, void *value)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1577
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1578
	struct tsd_thread *tsd = t->t_tsd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1579
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1580
	ASSERT(t == curthread ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1581
	    ttoproc(t)->p_agenttp == curthread || t->t_state == TS_STOPPED);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1582
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1583
	if (key == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1584
		return (EINVAL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1585
	if (tsd == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1586
		tsd = t->t_tsd = kmem_zalloc(sizeof (*tsd), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1587
	if (key <= tsd->ts_nkeys) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1588
		tsd->ts_value[key - 1] = value;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1589
		return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1590
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1591
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1592
	ASSERT(key <= tsd_nkeys);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1593
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1594
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1595
	 * lock out tsd_destroy()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1596
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1597
	mutex_enter(&tsd_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1598
	if (tsd->ts_nkeys == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1599
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1600
		 * Link onto list of threads with TSD
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1601
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1602
		if ((tsd->ts_next = tsd_list) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1603
			tsd_list->ts_prev = tsd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1604
		tsd_list = tsd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1605
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1606
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1607
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1608
	 * Allocate thread local storage and set the value for key
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1609
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1610
	tsd->ts_value = tsd_realloc(tsd->ts_value,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1611
	    tsd->ts_nkeys * sizeof (void *),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1612
	    key * sizeof (void *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1613
	tsd->ts_nkeys = key;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1614
	tsd->ts_value[key - 1] = value;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1615
	mutex_exit(&tsd_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1616
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1617
	return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1618
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1619
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1620
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1621
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1622
 * Return the per thread value that was stored with the specified key
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1623
 *	If necessary, create the key and the value
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1624
 *	Assumes the caller is protecting *keyp from tsd_destroy
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1625
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1626
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1627
tsd_getcreate(uint_t *keyp, void (*destroy)(void *), void *(*allocate)(void))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1628
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1629
	void *value;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1630
	uint_t key = *keyp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1631
	struct tsd_thread *tsd = curthread->t_tsd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1632
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1633
	if (tsd == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1634
		tsd = curthread->t_tsd = kmem_zalloc(sizeof (*tsd), KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1635
	if (key && key <= tsd->ts_nkeys && (value = tsd->ts_value[key - 1]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1636
		return (value);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1637
	if (key == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1638
		tsd_create(keyp, destroy);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1639
	(void) tsd_set(*keyp, value = (*allocate)());
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1640
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1641
	return (value);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1642
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1643
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1644
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1645
 * Called from thread_exit() to run the destructor function for each tsd
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1646
 *	Locks out tsd_create and tsd_destroy
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1647
 *	Assumes that the destructor *DOES NOT* use tsd
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1648
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1649
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1650
tsd_exit(void)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1651
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1652
	int i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1653
	struct tsd_thread *tsd = curthread->t_tsd;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1654
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1655
	if (tsd == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1656
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1657
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1658
	if (tsd->ts_nkeys == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1659
		kmem_free(tsd, sizeof (*tsd));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1660
		curthread->t_tsd = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1661
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1662
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1663
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1664
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1665
	 * lock out tsd_create and tsd_destroy, call
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1666
	 * the destructor, and mark the value as destroyed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1667
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1668
	mutex_enter(&tsd_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1669
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1670
	for (i = 0; i < tsd->ts_nkeys; i++) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1671
		if (tsd->ts_value[i] && tsd_destructor[i])
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1672
			(*tsd_destructor[i])(tsd->ts_value[i]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1673
		tsd->ts_value[i] = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1674
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1675
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1676
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1677
	 * remove from linked list of threads with TSD
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1678
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1679
	if (tsd->ts_next)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1680
		tsd->ts_next->ts_prev = tsd->ts_prev;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1681
	if (tsd->ts_prev)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1682
		tsd->ts_prev->ts_next = tsd->ts_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1683
	if (tsd_list == tsd)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1684
		tsd_list = tsd->ts_next;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1685
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1686
	mutex_exit(&tsd_mutex);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1687
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1688
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1689
	 * free up the TSD
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1690
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1691
	kmem_free(tsd->ts_value, tsd->ts_nkeys * sizeof (void *));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1692
	kmem_free(tsd, sizeof (struct tsd_thread));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1693
	curthread->t_tsd = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1694
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1696
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1697
 * realloc
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1698
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1699
static void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1700
tsd_realloc(void *old, size_t osize, size_t nsize)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1701
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1702
	void *new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1703
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1704
	new = kmem_zalloc(nsize, KM_SLEEP);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1705
	if (old) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1706
		bcopy(old, new, osize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1707
		kmem_free(old, osize);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1708
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1709
	return (new);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1710
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1711
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1712
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1713
 * Return non-zero if an interrupt is being serviced.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1714
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1715
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1716
servicing_interrupt()
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1717
{
1845
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1718
	int onintr = 0;
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1719
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1720
	/* Are we an interrupt thread */
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1721
	if (curthread->t_flag & T_INTR_THREAD)
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1722
		return (1);
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1723
	/* Are we servicing a high level interrupt? */
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1724
	if (CPU_ON_INTR(CPU)) {
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1725
		kpreempt_disable();
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1726
		onintr = CPU_ON_INTR(CPU);
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1727
		kpreempt_enable();
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1728
	}
178e04e5effe 6315610 servicing_interrupt() can return true even if the thread is not in interrupt context
sudheer
parents: 1676
diff changeset
  1729
	return (onintr);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1730
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1731
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1732
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1733
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1734
 * Change the dispatch priority of a thread in the system.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1735
 * Used when raising or lowering a thread's priority.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1736
 * (E.g., priority inheritance)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1737
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1738
 * Since threads are queued according to their priority, we
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1739
 * we must check the thread's state to determine whether it
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1740
 * is on a queue somewhere. If it is, we've got to:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1741
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1742
 *	o Dequeue the thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1743
 *	o Change its effective priority.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1744
 *	o Enqueue the thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1745
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1746
 * Assumptions: The thread whose priority we wish to change
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1747
 * must be locked before we call thread_change_(e)pri().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1748
 * The thread_change(e)pri() function doesn't drop the thread
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1749
 * lock--that must be done by its caller.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1750
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1751
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1752
thread_change_epri(kthread_t *t, pri_t disp_pri)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1753
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1754
	uint_t	state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1755
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1756
	ASSERT(THREAD_LOCK_HELD(t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1757
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1758
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1759
	 * If the inherited priority hasn't actually changed,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1760
	 * just return.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1761
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1762
	if (t->t_epri == disp_pri)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1763
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1764
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1765
	state = t->t_state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1766
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1767
	/*
6247
ad4c702ff226 PSARC 2007/661 delete sched_nice
raf
parents: 5834
diff changeset
  1768
	 * If it's not on a queue, change the priority with impunity.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1769
	 */
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1770
	if ((state & (TS_SLEEP | TS_RUN | TS_WAIT)) == 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1771
		t->t_epri = disp_pri;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1772
		if (state == TS_ONPROC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1773
			cpu_t *cp = t->t_disp_queue->disp_cpu;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1774
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1775
			if (t == cp->cpu_dispthread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1776
				cp->cpu_dispatch_pri = DISP_PRIO(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1777
		}
6247
ad4c702ff226 PSARC 2007/661 delete sched_nice
raf
parents: 5834
diff changeset
  1778
	} else if (state == TS_SLEEP) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1779
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1780
		 * Take the thread out of its sleep queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1781
		 * Change the inherited priority.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1782
		 * Re-enqueue the thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1783
		 * Each synchronization object exports a function
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1784
		 * to do this in an appropriate manner.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1785
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1786
		SOBJ_CHANGE_EPRI(t->t_sobj_ops, t, disp_pri);
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1787
	} else if (state == TS_WAIT) {
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1788
		/*
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1789
		 * Re-enqueue a thread on the wait queue if its
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1790
		 * effective priority needs to change.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1791
		 */
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1792
		if (disp_pri != t->t_epri)
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1793
			waitq_change_pri(t, disp_pri);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1794
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1795
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1796
		 * The thread is on a run queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1797
		 * Note: setbackdq() may not put the thread
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1798
		 * back on the same run queue where it originally
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1799
		 * resided.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1800
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1801
		(void) dispdeq(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1802
		t->t_epri = disp_pri;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1803
		setbackdq(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1804
	}
6247
ad4c702ff226 PSARC 2007/661 delete sched_nice
raf
parents: 5834
diff changeset
  1805
	schedctl_set_cidpri(t);
ad4c702ff226 PSARC 2007/661 delete sched_nice
raf
parents: 5834
diff changeset
  1806
}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1807
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1808
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1809
 * Function: Change the t_pri field of a thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1810
 * Side Effects: Adjust the thread ordering on a run queue
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1811
 *		 or sleep queue, if necessary.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1812
 * Returns: 1 if the thread was on a run queue, else 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1813
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1814
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1815
thread_change_pri(kthread_t *t, pri_t disp_pri, int front)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1816
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1817
	uint_t	state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1818
	int	on_rq = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1819
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1820
	ASSERT(THREAD_LOCK_HELD(t));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1821
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1822
	state = t->t_state;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1823
	THREAD_WILLCHANGE_PRI(t, disp_pri);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1824
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1825
	/*
6247
ad4c702ff226 PSARC 2007/661 delete sched_nice
raf
parents: 5834
diff changeset
  1826
	 * If it's not on a queue, change the priority with impunity.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1827
	 */
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1828
	if ((state & (TS_SLEEP | TS_RUN | TS_WAIT)) == 0) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1829
		t->t_pri = disp_pri;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1830
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1831
		if (state == TS_ONPROC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1832
			cpu_t *cp = t->t_disp_queue->disp_cpu;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1833
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1834
			if (t == cp->cpu_dispthread)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1835
				cp->cpu_dispatch_pri = DISP_PRIO(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1836
		}
6247
ad4c702ff226 PSARC 2007/661 delete sched_nice
raf
parents: 5834
diff changeset
  1837
	} else if (state == TS_SLEEP) {
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1838
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1839
		 * If the priority has changed, take the thread out of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1840
		 * its sleep queue and change the priority.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1841
		 * Re-enqueue the thread.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1842
		 * Each synchronization object exports a function
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1843
		 * to do this in an appropriate manner.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1844
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1845
		if (disp_pri != t->t_pri)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1846
			SOBJ_CHANGE_PRI(t->t_sobj_ops, t, disp_pri);
3792
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1847
	} else if (state == TS_WAIT) {
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1848
		/*
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1849
		 * Re-enqueue a thread on the wait queue if its
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1850
		 * priority needs to change.
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1851
		 */
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1852
		if (disp_pri != t->t_pri)
57ba782523b7 PSARC/2004/402 CPU Caps
akolb
parents: 2712
diff changeset
  1853
			waitq_change_pri(t, disp_pri);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1854
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1855
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1856
		 * The thread is on a run queue.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1857
		 * Note: setbackdq() may not put the thread
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1858
		 * back on the same run queue where it originally
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1859
		 * resided.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1860
		 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1861
		 * We still requeue the thread even if the priority
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1862
		 * is unchanged to preserve round-robin (and other)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1863
		 * effects between threads of the same priority.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1864
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1865
		on_rq = dispdeq(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1866
		ASSERT(on_rq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1867
		t->t_pri = disp_pri;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1868
		if (front) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1869
			setfrontdq(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1870
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1871
			setbackdq(t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1872
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1873
	}
6247
ad4c702ff226 PSARC 2007/661 delete sched_nice
raf
parents: 5834
diff changeset
  1874
	schedctl_set_cidpri(t);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1875
	return (on_rq);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
  1876
}
7854
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1877
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1878
/*
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1879
 * Tunable kmem_stackinfo is set, fill the kernel thread stack with a
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1880
 * specific pattern.
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1881
 */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1882
static void
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1883
stkinfo_begin(kthread_t *t)
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1884
{
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1885
	caddr_t	start;	/* stack start */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1886
	caddr_t	end;	/* stack end  */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1887
	uint64_t *ptr;	/* pattern pointer */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1888
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1889
	/*
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1890
	 * Stack grows up or down, see thread_create(),
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1891
	 * compute stack memory area start and end (start < end).
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1892
	 */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1893
	if (t->t_stk > t->t_stkbase) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1894
		/* stack grows down */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1895
		start = t->t_stkbase;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1896
		end = t->t_stk;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1897
	} else {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1898
		/* stack grows up */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1899
		start = t->t_stk;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1900
		end = t->t_stkbase;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1901
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1902
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1903
	/*
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1904
	 * Stackinfo pattern size is 8 bytes. Ensure proper 8 bytes
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1905
	 * alignement for start and end in stack area boundaries
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1906
	 * (protection against corrupt t_stkbase/t_stk data).
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1907
	 */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1908
	if ((((uintptr_t)start) & 0x7) != 0) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1909
		start = (caddr_t)((((uintptr_t)start) & (~0x7)) + 8);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1910
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1911
	end = (caddr_t)(((uintptr_t)end) & (~0x7));
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1912
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1913
	if ((end <= start) || (end - start) > (1024 * 1024)) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1914
		/* negative or stack size > 1 meg, assume bogus */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1915
		return;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1916
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1917
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1918
	/* fill stack area with a pattern (instead of zeros) */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1919
	ptr = (uint64_t *)((void *)start);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1920
	while (ptr < (uint64_t *)((void *)end)) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1921
		*ptr++ = KMEM_STKINFO_PATTERN;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1922
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1923
}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1924
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1925
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1926
/*
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1927
 * Tunable kmem_stackinfo is set, create stackinfo log if doesn't already exist,
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1928
 * compute the percentage of kernel stack really used, and set in the log
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1929
 * if it's the latest highest percentage.
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1930
 */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1931
static void
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1932
stkinfo_end(kthread_t *t)
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1933
{
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1934
	caddr_t	start;	/* stack start */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1935
	caddr_t	end;	/* stack end  */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1936
	uint64_t *ptr;	/* pattern pointer */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1937
	size_t stksz;	/* stack size */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1938
	size_t smallest = 0;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1939
	size_t percent = 0;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1940
	uint_t index = 0;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1941
	uint_t i;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1942
	static size_t smallest_percent = (size_t)-1;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1943
	static uint_t full = 0;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1944
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1945
	/* create the stackinfo log, if doesn't already exist */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1946
	mutex_enter(&kmem_stkinfo_lock);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1947
	if (kmem_stkinfo_log == NULL) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1948
		kmem_stkinfo_log = (kmem_stkinfo_t *)
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1949
		    kmem_zalloc(KMEM_STKINFO_LOG_SIZE *
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1950
		    (sizeof (kmem_stkinfo_t)), KM_NOSLEEP);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1951
		if (kmem_stkinfo_log == NULL) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1952
			mutex_exit(&kmem_stkinfo_lock);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1953
			return;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1954
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1955
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1956
	mutex_exit(&kmem_stkinfo_lock);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1957
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1958
	/*
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1959
	 * Stack grows up or down, see thread_create(),
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1960
	 * compute stack memory area start and end (start < end).
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1961
	 */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1962
	if (t->t_stk > t->t_stkbase) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1963
		/* stack grows down */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1964
		start = t->t_stkbase;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1965
		end = t->t_stk;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1966
	} else {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1967
		/* stack grows up */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1968
		start = t->t_stk;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1969
		end = t->t_stkbase;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1970
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1971
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1972
	/* stack size as found in kthread_t */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1973
	stksz = end - start;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1974
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1975
	/*
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1976
	 * Stackinfo pattern size is 8 bytes. Ensure proper 8 bytes
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1977
	 * alignement for start and end in stack area boundaries
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1978
	 * (protection against corrupt t_stkbase/t_stk data).
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1979
	 */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1980
	if ((((uintptr_t)start) & 0x7) != 0) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1981
		start = (caddr_t)((((uintptr_t)start) & (~0x7)) + 8);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1982
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1983
	end = (caddr_t)(((uintptr_t)end) & (~0x7));
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1984
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1985
	if ((end <= start) || (end - start) > (1024 * 1024)) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1986
		/* negative or stack size > 1 meg, assume bogus */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1987
		return;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1988
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1989
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1990
	/* search until no pattern in the stack */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1991
	if (t->t_stk > t->t_stkbase) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1992
		/* stack grows down */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1993
#if defined(__i386) || defined(__amd64)
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1994
		/*
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1995
		 * 6 longs are pushed on stack, see thread_load(). Skip
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1996
		 * them, so if kthread has never run, percent is zero.
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1997
		 * 8 bytes alignement is preserved for a 32 bit kernel,
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1998
		 * 6 x 4 = 24, 24 is a multiple of 8.
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  1999
		 *
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2000
		 */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2001
		end -= (6 * sizeof (long));
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2002
#endif
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2003
		ptr = (uint64_t *)((void *)start);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2004
		while (ptr < (uint64_t *)((void *)end)) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2005
			if (*ptr != KMEM_STKINFO_PATTERN) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2006
				percent = stkinfo_percent(end,
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2007
				    start, (caddr_t)ptr);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2008
				break;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2009
			}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2010
			ptr++;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2011
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2012
	} else {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2013
		/* stack grows up */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2014
		ptr = (uint64_t *)((void *)end);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2015
		ptr--;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2016
		while (ptr >= (uint64_t *)((void *)start)) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2017
			if (*ptr != KMEM_STKINFO_PATTERN) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2018
				percent = stkinfo_percent(start,
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2019
				    end, (caddr_t)ptr);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2020
				break;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2021
			}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2022
			ptr--;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2023
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2024
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2025
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2026
	DTRACE_PROBE3(stack__usage, kthread_t *, t,
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2027
	    size_t, stksz, size_t, percent);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2028
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2029
	if (percent == 0) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2030
		return;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2031
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2032
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2033
	mutex_enter(&kmem_stkinfo_lock);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2034
	if (full == KMEM_STKINFO_LOG_SIZE && percent < smallest_percent) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2035
		/*
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2036
		 * The log is full and already contains the highest values
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2037
		 */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2038
		mutex_exit(&kmem_stkinfo_lock);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2039
		return;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2040
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2041
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2042
	/* keep a log of the highest used stack */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2043
	for (i = 0; i < KMEM_STKINFO_LOG_SIZE; i++) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2044
		if (kmem_stkinfo_log[i].percent == 0) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2045
			index = i;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2046
			full++;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2047
			break;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2048
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2049
		if (smallest == 0) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2050
			smallest = kmem_stkinfo_log[i].percent;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2051
			index = i;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2052
			continue;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2053
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2054
		if (kmem_stkinfo_log[i].percent < smallest) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2055
			smallest = kmem_stkinfo_log[i].percent;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2056
			index = i;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2057
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2058
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2059
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2060
	if (percent >= kmem_stkinfo_log[index].percent) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2061
		kmem_stkinfo_log[index].kthread = (caddr_t)t;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2062
		kmem_stkinfo_log[index].t_startpc = (caddr_t)t->t_startpc;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2063
		kmem_stkinfo_log[index].start = start;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2064
		kmem_stkinfo_log[index].stksz = stksz;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2065
		kmem_stkinfo_log[index].percent = percent;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2066
		kmem_stkinfo_log[index].t_tid = t->t_tid;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2067
		kmem_stkinfo_log[index].cmd[0] = '\0';
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2068
		if (t->t_tid != 0) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2069
			stksz = strlen((t->t_procp)->p_user.u_comm);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2070
			if (stksz >= KMEM_STKINFO_STR_SIZE) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2071
				stksz = KMEM_STKINFO_STR_SIZE - 1;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2072
				kmem_stkinfo_log[index].cmd[stksz] = '\0';
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2073
			} else {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2074
				stksz += 1;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2075
			}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2076
			(void) memcpy(kmem_stkinfo_log[index].cmd,
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2077
			    (t->t_procp)->p_user.u_comm, stksz);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2078
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2079
		if (percent < smallest_percent) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2080
			smallest_percent = percent;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2081
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2082
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2083
	mutex_exit(&kmem_stkinfo_lock);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2084
}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2085
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2086
/*
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2087
 * Tunable kmem_stackinfo is set, compute stack utilization percentage.
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2088
 */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2089
static size_t
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2090
stkinfo_percent(caddr_t t_stk, caddr_t t_stkbase, caddr_t sp)
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2091
{
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2092
	size_t percent;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2093
	size_t s;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2094
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2095
	if (t_stk > t_stkbase) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2096
		/* stack grows down */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2097
		if (sp > t_stk) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2098
			return (0);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2099
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2100
		if (sp < t_stkbase) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2101
			return (100);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2102
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2103
		percent = t_stk - sp + 1;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2104
		s = t_stk - t_stkbase + 1;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2105
	} else {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2106
		/* stack grows up */
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2107
		if (sp < t_stk) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2108
			return (0);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2109
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2110
		if (sp > t_stkbase) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2111
			return (100);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2112
		}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2113
		percent = sp - t_stk + 1;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2114
		s = t_stkbase - t_stk + 1;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2115
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2116
	percent = ((100 * percent) / s) + 1;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2117
	if (percent > 100) {
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2118
		percent = 100;
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2119
	}
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2120
	return (percent);
2470b1cdadff 6626918 A new (k)mdb command ::stackinfo, kernel thread stack usage
Philippe Jung <Philippe.Jung@Sun.COM>
parents: 6298
diff changeset
  2121
}