Mercurial > illumos > illumos-gate
annotate usr/src/uts/common/os/kcpc.c @ 13082:87f89233b883
6964154 Missing unlock in set_all_zone_usr_proc_sys()
6964159 Missing unlock in immu_quiesce() and immu_unquiesce()
6964162 Pointer dereferenced before NULL check in kcpc_reqs_add()
6964446 Uninitialized variable used in rootnex_coredma_bindhdl()
6965638 Potential memory leak in configure_ffc()
6965642 Freeing variable that may be NULL in kmem_free()
author | Ethindra Ramamurthy <Ethindra.Ramamurthy@Sun.COM> |
---|---|
date | Wed, 11 Aug 2010 12:52:19 -0400 |
parents | dd00b884e84f |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
3156 | 5 * Common Development and Distribution License (the "License"). |
6 * You may not use this file except in compliance with the License. | |
0 | 7 * |
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 * or http://www.opensolaris.org/os/licensing. | |
10 * See the License for the specific language governing permissions | |
11 * and limitations under the License. | |
12 * | |
13 * When distributing Covered Code, include this CDDL HEADER in each | |
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 * If applicable, add the following below this CDDL HEADER, with the | |
16 * fields enclosed by brackets "[]" replaced with your own identifying | |
17 * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 * | |
19 * CDDL HEADER END | |
20 */ | |
1414
b4126407ac5b
PSARC 2006/020 FMA for Athlon 64 and Opteron Processors
cindi
parents:
0
diff
changeset
|
21 |
0 | 22 /* |
13082
87f89233b883
6964154 Missing unlock in set_all_zone_usr_proc_sys()
Ethindra Ramamurthy <Ethindra.Ramamurthy@Sun.COM>
parents:
11389
diff
changeset
|
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 24 */ |
25 | |
26 #include <sys/param.h> | |
27 #include <sys/thread.h> | |
28 #include <sys/cpuvar.h> | |
29 #include <sys/inttypes.h> | |
30 #include <sys/cmn_err.h> | |
31 #include <sys/time.h> | |
6275 | 32 #include <sys/ksynch.h> |
0 | 33 #include <sys/systm.h> |
34 #include <sys/kcpc.h> | |
35 #include <sys/cpc_impl.h> | |
36 #include <sys/cpc_pcbe.h> | |
37 #include <sys/atomic.h> | |
38 #include <sys/sunddi.h> | |
39 #include <sys/modctl.h> | |
40 #include <sys/sdt.h> | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
41 #include <sys/archsystm.h> |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
42 #include <sys/promif.h> |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
43 #include <sys/x_call.h> |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
44 #include <sys/cap_util.h> |
0 | 45 #if defined(__x86) |
46 #include <asm/clock.h> | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
47 #include <sys/xc_levels.h> |
0 | 48 #endif |
49 | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
50 static kmutex_t kcpc_ctx_llock[CPC_HASH_BUCKETS]; /* protects ctx_list */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
51 static kcpc_ctx_t *kcpc_ctx_list[CPC_HASH_BUCKETS]; /* head of list */ |
0 | 52 |
53 | |
54 krwlock_t kcpc_cpuctx_lock; /* lock for 'kcpc_cpuctx' below */ | |
55 int kcpc_cpuctx; /* number of cpu-specific contexts */ | |
56 | |
57 int kcpc_counts_include_idle = 1; /* Project Private /etc/system variable */ | |
58 | |
59 /* | |
60 * These are set when a PCBE module is loaded. | |
61 */ | |
62 uint_t cpc_ncounters = 0; | |
63 pcbe_ops_t *pcbe_ops = NULL; | |
64 | |
65 /* | |
66 * Statistics on (mis)behavior | |
67 */ | |
68 static uint32_t kcpc_intrctx_count; /* # overflows in an interrupt handler */ | |
69 static uint32_t kcpc_nullctx_count; /* # overflows in a thread with no ctx */ | |
70 | |
71 /* | |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
72 * By setting 'kcpc_nullctx_panic' to 1, any overflow interrupts in a thread |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
73 * with no valid context will result in a panic. |
0 | 74 */ |
75 static int kcpc_nullctx_panic = 0; | |
76 | |
77 static void kcpc_lwp_create(kthread_t *t, kthread_t *ct); | |
78 static void kcpc_restore(kcpc_ctx_t *ctx); | |
79 static void kcpc_save(kcpc_ctx_t *ctx); | |
80 static void kcpc_ctx_clone(kcpc_ctx_t *ctx, kcpc_ctx_t *cctx); | |
81 static int kcpc_tryassign(kcpc_set_t *set, int starting_req, int *scratch); | |
82 static kcpc_set_t *kcpc_dup_set(kcpc_set_t *set); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
83 static kcpc_set_t *kcpc_set_create(kcpc_request_t *reqs, int nreqs, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
84 int set_flags, int kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
85 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
86 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
87 * Macros to manipulate context flags. All flag updates should use one of these |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
88 * two macros |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
89 * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
90 * Flags should be always be updated atomically since some of the updates are |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
91 * not protected by locks. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
92 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
93 #define KCPC_CTX_FLAG_SET(ctx, flag) atomic_or_uint(&(ctx)->kc_flags, (flag)) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
94 #define KCPC_CTX_FLAG_CLR(ctx, flag) atomic_and_uint(&(ctx)->kc_flags, ~(flag)) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
95 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
96 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
97 * The IS_HIPIL() macro verifies that the code is executed either from a |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
98 * cross-call or from high-PIL interrupt |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
99 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
100 #ifdef DEBUG |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
101 #define IS_HIPIL() (getpil() >= XCALL_PIL) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
102 #else |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
103 #define IS_HIPIL() |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
104 #endif /* DEBUG */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
105 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
106 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
107 extern int kcpc_hw_load_pcbe(void); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
108 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
109 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
110 * Return value from kcpc_hw_load_pcbe() |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
111 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
112 static int kcpc_pcbe_error = 0; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
113 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
114 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
115 * Perform one-time initialization of kcpc framework. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
116 * This function performs the initialization only the first time it is called. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
117 * It is safe to call it multiple times. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
118 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
119 int |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
120 kcpc_init(void) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
121 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
122 long hash; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
123 static uint32_t kcpc_initialized = 0; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
124 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
125 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
126 * We already tried loading platform pcbe module and failed |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
127 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
128 if (kcpc_pcbe_error != 0) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
129 return (-1); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
130 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
131 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
132 * The kcpc framework should be initialized at most once |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
133 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
134 if (atomic_cas_32(&kcpc_initialized, 0, 1) != 0) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
135 return (0); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
136 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
137 rw_init(&kcpc_cpuctx_lock, NULL, RW_DEFAULT, NULL); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
138 for (hash = 0; hash < CPC_HASH_BUCKETS; hash++) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
139 mutex_init(&kcpc_ctx_llock[hash], |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
140 NULL, MUTEX_DRIVER, (void *)(uintptr_t)15); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
141 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
142 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
143 * Load platform-specific pcbe module |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
144 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
145 kcpc_pcbe_error = kcpc_hw_load_pcbe(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
146 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
147 return (kcpc_pcbe_error == 0 ? 0 : -1); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
148 } |
0 | 149 |
150 void | |
151 kcpc_register_pcbe(pcbe_ops_t *ops) | |
152 { | |
153 pcbe_ops = ops; | |
154 cpc_ncounters = pcbe_ops->pcbe_ncounters(); | |
155 } | |
156 | |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
157 void |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
158 kcpc_register_dcpc(void (*func)(uint64_t)) |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
159 { |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
160 dtrace_cpc_fire = func; |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
161 } |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
162 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
163 void |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
164 kcpc_unregister_dcpc(void) |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
165 { |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
166 dtrace_cpc_fire = NULL; |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
167 } |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
168 |
0 | 169 int |
170 kcpc_bind_cpu(kcpc_set_t *set, processorid_t cpuid, int *subcode) | |
171 { | |
172 cpu_t *cp; | |
173 kcpc_ctx_t *ctx; | |
174 int error; | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
175 int save_spl; |
0 | 176 |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
177 ctx = kcpc_ctx_alloc(KM_SLEEP); |
0 | 178 |
179 if (kcpc_assign_reqs(set, ctx) != 0) { | |
180 kcpc_ctx_free(ctx); | |
181 *subcode = CPC_RESOURCE_UNAVAIL; | |
182 return (EINVAL); | |
183 } | |
184 | |
185 ctx->kc_cpuid = cpuid; | |
186 ctx->kc_thread = curthread; | |
187 | |
188 set->ks_data = kmem_zalloc(set->ks_nreqs * sizeof (uint64_t), KM_SLEEP); | |
189 | |
190 if ((error = kcpc_configure_reqs(ctx, set, subcode)) != 0) { | |
191 kmem_free(set->ks_data, set->ks_nreqs * sizeof (uint64_t)); | |
192 kcpc_ctx_free(ctx); | |
193 return (error); | |
194 } | |
195 | |
196 set->ks_ctx = ctx; | |
197 ctx->kc_set = set; | |
198 | |
199 /* | |
200 * We must hold cpu_lock to prevent DR, offlining, or unbinding while | |
201 * we are manipulating the cpu_t and programming the hardware, else the | |
202 * the cpu_t could go away while we're looking at it. | |
203 */ | |
204 mutex_enter(&cpu_lock); | |
205 cp = cpu_get(cpuid); | |
206 | |
207 if (cp == NULL) | |
208 /* | |
209 * The CPU could have been DRd out while we were getting set up. | |
210 */ | |
211 goto unbound; | |
212 | |
213 mutex_enter(&cp->cpu_cpc_ctxlock); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
214 kpreempt_disable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
215 save_spl = spl_xcall(); |
0 | 216 |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
217 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
218 * Check to see whether counters for CPU already being used by someone |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
219 * other than kernel for capacity and utilization (since kernel will |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
220 * let go of counters for user in kcpc_program() below) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
221 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
222 if (cp->cpu_cpc_ctx != NULL && !CU_CPC_ON(cp)) { |
0 | 223 /* |
224 * If this CPU already has a bound set, return an error. | |
225 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
226 splx(save_spl); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
227 kpreempt_enable(); |
0 | 228 mutex_exit(&cp->cpu_cpc_ctxlock); |
229 goto unbound; | |
230 } | |
231 | |
232 if (curthread->t_bind_cpu != cpuid) { | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
233 splx(save_spl); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
234 kpreempt_enable(); |
0 | 235 mutex_exit(&cp->cpu_cpc_ctxlock); |
236 goto unbound; | |
237 } | |
238 | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
239 kcpc_program(ctx, B_FALSE, B_TRUE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
240 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
241 splx(save_spl); |
0 | 242 kpreempt_enable(); |
243 | |
244 mutex_exit(&cp->cpu_cpc_ctxlock); | |
245 mutex_exit(&cpu_lock); | |
246 | |
6275 | 247 mutex_enter(&set->ks_lock); |
248 set->ks_state |= KCPC_SET_BOUND; | |
249 cv_signal(&set->ks_condv); | |
250 mutex_exit(&set->ks_lock); | |
251 | |
0 | 252 return (0); |
253 | |
254 unbound: | |
255 mutex_exit(&cpu_lock); | |
256 set->ks_ctx = NULL; | |
257 kmem_free(set->ks_data, set->ks_nreqs * sizeof (uint64_t)); | |
258 kcpc_ctx_free(ctx); | |
259 return (EAGAIN); | |
260 } | |
261 | |
262 int | |
263 kcpc_bind_thread(kcpc_set_t *set, kthread_t *t, int *subcode) | |
264 { | |
265 kcpc_ctx_t *ctx; | |
266 int error; | |
267 | |
268 /* | |
269 * Only one set is allowed per context, so ensure there is no | |
270 * existing context. | |
271 */ | |
272 | |
273 if (t->t_cpc_ctx != NULL) | |
274 return (EEXIST); | |
275 | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
276 ctx = kcpc_ctx_alloc(KM_SLEEP); |
0 | 277 |
278 /* | |
279 * The context must begin life frozen until it has been properly | |
280 * programmed onto the hardware. This prevents the context ops from | |
281 * worrying about it until we're ready. | |
282 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
283 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_FREEZE); |
0 | 284 ctx->kc_hrtime = gethrtime(); |
285 | |
286 if (kcpc_assign_reqs(set, ctx) != 0) { | |
287 kcpc_ctx_free(ctx); | |
288 *subcode = CPC_RESOURCE_UNAVAIL; | |
289 return (EINVAL); | |
290 } | |
291 | |
292 ctx->kc_cpuid = -1; | |
293 if (set->ks_flags & CPC_BIND_LWP_INHERIT) | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
294 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_LWPINHERIT); |
0 | 295 ctx->kc_thread = t; |
296 t->t_cpc_ctx = ctx; | |
297 /* | |
298 * Permit threads to look at their own hardware counters from userland. | |
299 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
300 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_NONPRIV); |
0 | 301 |
302 /* | |
303 * Create the data store for this set. | |
304 */ | |
305 set->ks_data = kmem_alloc(set->ks_nreqs * sizeof (uint64_t), KM_SLEEP); | |
306 | |
307 if ((error = kcpc_configure_reqs(ctx, set, subcode)) != 0) { | |
308 kmem_free(set->ks_data, set->ks_nreqs * sizeof (uint64_t)); | |
309 kcpc_ctx_free(ctx); | |
310 t->t_cpc_ctx = NULL; | |
311 return (error); | |
312 } | |
313 | |
314 set->ks_ctx = ctx; | |
315 ctx->kc_set = set; | |
316 | |
317 /* | |
318 * Add a device context to the subject thread. | |
319 */ | |
320 installctx(t, ctx, kcpc_save, kcpc_restore, NULL, | |
321 kcpc_lwp_create, NULL, kcpc_free); | |
322 | |
323 /* | |
324 * Ask the backend to program the hardware. | |
325 */ | |
326 if (t == curthread) { | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
327 int save_spl; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
328 |
0 | 329 kpreempt_disable(); |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
330 save_spl = spl_xcall(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
331 kcpc_program(ctx, B_TRUE, B_TRUE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
332 splx(save_spl); |
0 | 333 kpreempt_enable(); |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
334 } else { |
0 | 335 /* |
336 * Since we are the agent LWP, we know the victim LWP is stopped | |
337 * until we're done here; no need to worry about preemption or | |
338 * migration here. We still use an atomic op to clear the flag | |
339 * to ensure the flags are always self-consistent; they can | |
340 * still be accessed from, for instance, another CPU doing a | |
341 * kcpc_invalidate_all(). | |
342 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
343 KCPC_CTX_FLAG_CLR(ctx, KCPC_CTX_FREEZE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
344 } |
0 | 345 |
6275 | 346 mutex_enter(&set->ks_lock); |
347 set->ks_state |= KCPC_SET_BOUND; | |
348 cv_signal(&set->ks_condv); | |
349 mutex_exit(&set->ks_lock); | |
0 | 350 |
351 return (0); | |
352 } | |
353 | |
354 /* | |
355 * Walk through each request in the set and ask the PCBE to configure a | |
356 * corresponding counter. | |
357 */ | |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
358 int |
0 | 359 kcpc_configure_reqs(kcpc_ctx_t *ctx, kcpc_set_t *set, int *subcode) |
360 { | |
361 int i; | |
362 int ret; | |
363 kcpc_request_t *rp; | |
364 | |
365 for (i = 0; i < set->ks_nreqs; i++) { | |
366 int n; | |
367 rp = &set->ks_req[i]; | |
368 | |
369 n = rp->kr_picnum; | |
370 | |
371 ASSERT(n >= 0 && n < cpc_ncounters); | |
372 | |
373 ASSERT(ctx->kc_pics[n].kp_req == NULL); | |
374 | |
375 if (rp->kr_flags & CPC_OVF_NOTIFY_EMT) { | |
376 if ((pcbe_ops->pcbe_caps & CPC_CAP_OVERFLOW_INTERRUPT) | |
377 == 0) { | |
378 *subcode = -1; | |
379 return (ENOTSUP); | |
380 } | |
381 /* | |
382 * If any of the counters have requested overflow | |
383 * notification, we flag the context as being one that | |
384 * cares about overflow. | |
385 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
386 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_SIGOVF); |
0 | 387 } |
388 | |
389 rp->kr_config = NULL; | |
390 if ((ret = pcbe_ops->pcbe_configure(n, rp->kr_event, | |
391 rp->kr_preset, rp->kr_flags, rp->kr_nattrs, rp->kr_attr, | |
392 &(rp->kr_config), (void *)ctx)) != 0) { | |
393 kcpc_free_configs(set); | |
394 *subcode = ret; | |
3732 | 395 switch (ret) { |
396 case CPC_ATTR_REQUIRES_PRIVILEGE: | |
397 case CPC_HV_NO_ACCESS: | |
0 | 398 return (EACCES); |
3732 | 399 default: |
400 return (EINVAL); | |
401 } | |
0 | 402 } |
403 | |
404 ctx->kc_pics[n].kp_req = rp; | |
405 rp->kr_picp = &ctx->kc_pics[n]; | |
406 rp->kr_data = set->ks_data + rp->kr_index; | |
407 *rp->kr_data = rp->kr_preset; | |
408 } | |
409 | |
410 return (0); | |
411 } | |
412 | |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
413 void |
0 | 414 kcpc_free_configs(kcpc_set_t *set) |
415 { | |
416 int i; | |
417 | |
418 for (i = 0; i < set->ks_nreqs; i++) | |
419 if (set->ks_req[i].kr_config != NULL) | |
420 pcbe_ops->pcbe_free(set->ks_req[i].kr_config); | |
421 } | |
422 | |
423 /* | |
424 * buf points to a user address and the data should be copied out to that | |
425 * address in the current process. | |
426 */ | |
427 int | |
428 kcpc_sample(kcpc_set_t *set, uint64_t *buf, hrtime_t *hrtime, uint64_t *tick) | |
429 { | |
430 kcpc_ctx_t *ctx = set->ks_ctx; | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
431 int save_spl; |
0 | 432 |
6275 | 433 mutex_enter(&set->ks_lock); |
434 if ((set->ks_state & KCPC_SET_BOUND) == 0) { | |
435 mutex_exit(&set->ks_lock); | |
0 | 436 return (EINVAL); |
6275 | 437 } |
438 mutex_exit(&set->ks_lock); | |
439 | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
440 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
441 * Kernel preemption must be disabled while reading the hardware regs, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
442 * and if this is a CPU-bound context, while checking the CPU binding of |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
443 * the current thread. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
444 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
445 kpreempt_disable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
446 save_spl = spl_xcall(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
447 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
448 if (ctx->kc_flags & KCPC_CTX_INVALID) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
449 splx(save_spl); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
450 kpreempt_enable(); |
0 | 451 return (EAGAIN); |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
452 } |
0 | 453 |
454 if ((ctx->kc_flags & KCPC_CTX_FREEZE) == 0) { | |
455 if (ctx->kc_cpuid != -1) { | |
456 if (curthread->t_bind_cpu != ctx->kc_cpuid) { | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
457 splx(save_spl); |
0 | 458 kpreempt_enable(); |
459 return (EAGAIN); | |
460 } | |
461 } | |
462 | |
463 if (ctx->kc_thread == curthread) { | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
464 uint64_t curtick = KCPC_GET_TICK(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
465 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
466 ctx->kc_hrtime = gethrtime_waitfree(); |
0 | 467 pcbe_ops->pcbe_sample(ctx); |
468 ctx->kc_vtick += curtick - ctx->kc_rawtick; | |
469 ctx->kc_rawtick = curtick; | |
470 } | |
471 | |
3732 | 472 /* |
473 * The config may have been invalidated by | |
474 * the pcbe_sample op. | |
475 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
476 if (ctx->kc_flags & KCPC_CTX_INVALID) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
477 splx(save_spl); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
478 kpreempt_enable(); |
3732 | 479 return (EAGAIN); |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
480 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
481 |
0 | 482 } |
483 | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
484 splx(save_spl); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
485 kpreempt_enable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
486 |
0 | 487 if (copyout(set->ks_data, buf, |
488 set->ks_nreqs * sizeof (uint64_t)) == -1) | |
489 return (EFAULT); | |
490 if (copyout(&ctx->kc_hrtime, hrtime, sizeof (uint64_t)) == -1) | |
491 return (EFAULT); | |
492 if (copyout(&ctx->kc_vtick, tick, sizeof (uint64_t)) == -1) | |
493 return (EFAULT); | |
494 | |
495 return (0); | |
496 } | |
497 | |
498 /* | |
499 * Stop the counters on the CPU this context is bound to. | |
500 */ | |
501 static void | |
502 kcpc_stop_hw(kcpc_ctx_t *ctx) | |
503 { | |
504 cpu_t *cp; | |
505 | |
506 kpreempt_disable(); | |
507 | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
508 if (ctx->kc_cpuid == CPU->cpu_id) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
509 cp = CPU; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
510 } else { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
511 cp = cpu_get(ctx->kc_cpuid); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
512 } |
0 | 513 |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
514 ASSERT(cp != NULL && cp->cpu_cpc_ctx == ctx); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
515 kcpc_cpu_stop(cp, B_FALSE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
516 |
0 | 517 kpreempt_enable(); |
518 } | |
519 | |
520 int | |
521 kcpc_unbind(kcpc_set_t *set) | |
522 { | |
6275 | 523 kcpc_ctx_t *ctx; |
0 | 524 kthread_t *t; |
525 | |
6275 | 526 /* |
527 * We could be racing with the process's agent thread as it | |
528 * binds the set; we must wait for the set to finish binding | |
529 * before attempting to tear it down. | |
530 */ | |
531 mutex_enter(&set->ks_lock); | |
532 while ((set->ks_state & KCPC_SET_BOUND) == 0) | |
533 cv_wait(&set->ks_condv, &set->ks_lock); | |
534 mutex_exit(&set->ks_lock); | |
0 | 535 |
6275 | 536 ctx = set->ks_ctx; |
537 | |
538 /* | |
539 * Use kc_lock to synchronize with kcpc_restore(). | |
540 */ | |
541 mutex_enter(&ctx->kc_lock); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
542 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_INVALID); |
6275 | 543 mutex_exit(&ctx->kc_lock); |
0 | 544 |
545 if (ctx->kc_cpuid == -1) { | |
546 t = ctx->kc_thread; | |
547 /* | |
548 * The context is thread-bound and therefore has a device | |
549 * context. It will be freed via removectx() calling | |
550 * freectx() calling kcpc_free(). | |
551 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
552 if (t == curthread) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
553 int save_spl; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
554 |
0 | 555 kpreempt_disable(); |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
556 save_spl = spl_xcall(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
557 if (!(ctx->kc_flags & KCPC_CTX_INVALID_STOPPED)) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
558 kcpc_unprogram(ctx, B_TRUE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
559 splx(save_spl); |
0 | 560 kpreempt_enable(); |
561 } | |
562 #ifdef DEBUG | |
563 if (removectx(t, ctx, kcpc_save, kcpc_restore, NULL, | |
564 kcpc_lwp_create, NULL, kcpc_free) == 0) | |
565 panic("kcpc_unbind: context %p not preset on thread %p", | |
7632
91aa3d8541b5
6733185 Further cleanup of SUN Studio 12 lint warnings in ON source.
Nick Todd <Nick.Todd@Sun.COM>
parents:
6275
diff
changeset
|
566 (void *)ctx, (void *)t); |
0 | 567 #else |
568 (void) removectx(t, ctx, kcpc_save, kcpc_restore, NULL, | |
569 kcpc_lwp_create, NULL, kcpc_free); | |
570 #endif /* DEBUG */ | |
571 t->t_cpc_set = NULL; | |
572 t->t_cpc_ctx = NULL; | |
573 } else { | |
574 /* | |
575 * If we are unbinding a CPU-bound set from a remote CPU, the | |
576 * native CPU's idle thread could be in the midst of programming | |
577 * this context onto the CPU. We grab the context's lock here to | |
578 * ensure that the idle thread is done with it. When we release | |
579 * the lock, the CPU no longer has a context and the idle thread | |
580 * will move on. | |
581 * | |
582 * cpu_lock must be held to prevent the CPU from being DR'd out | |
583 * while we disassociate the context from the cpu_t. | |
584 */ | |
585 cpu_t *cp; | |
586 mutex_enter(&cpu_lock); | |
587 cp = cpu_get(ctx->kc_cpuid); | |
588 if (cp != NULL) { | |
589 /* | |
590 * The CPU may have been DR'd out of the system. | |
591 */ | |
592 mutex_enter(&cp->cpu_cpc_ctxlock); | |
593 if ((ctx->kc_flags & KCPC_CTX_INVALID_STOPPED) == 0) | |
594 kcpc_stop_hw(ctx); | |
595 ASSERT(ctx->kc_flags & KCPC_CTX_INVALID_STOPPED); | |
596 mutex_exit(&cp->cpu_cpc_ctxlock); | |
597 } | |
598 mutex_exit(&cpu_lock); | |
599 if (ctx->kc_thread == curthread) { | |
600 kcpc_free(ctx, 0); | |
601 curthread->t_cpc_set = NULL; | |
602 } | |
603 } | |
604 | |
605 return (0); | |
606 } | |
607 | |
608 int | |
609 kcpc_preset(kcpc_set_t *set, int index, uint64_t preset) | |
610 { | |
611 int i; | |
612 | |
613 ASSERT(set != NULL); | |
6275 | 614 ASSERT(set->ks_state & KCPC_SET_BOUND); |
0 | 615 ASSERT(set->ks_ctx->kc_thread == curthread); |
616 ASSERT(set->ks_ctx->kc_cpuid == -1); | |
617 | |
618 if (index < 0 || index >= set->ks_nreqs) | |
619 return (EINVAL); | |
620 | |
621 for (i = 0; i < set->ks_nreqs; i++) | |
622 if (set->ks_req[i].kr_index == index) | |
623 break; | |
624 ASSERT(i != set->ks_nreqs); | |
625 | |
626 set->ks_req[i].kr_preset = preset; | |
627 return (0); | |
628 } | |
629 | |
630 int | |
631 kcpc_restart(kcpc_set_t *set) | |
632 { | |
633 kcpc_ctx_t *ctx = set->ks_ctx; | |
634 int i; | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
635 int save_spl; |
0 | 636 |
6275 | 637 ASSERT(set->ks_state & KCPC_SET_BOUND); |
0 | 638 ASSERT(ctx->kc_thread == curthread); |
639 ASSERT(ctx->kc_cpuid == -1); | |
640 | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
641 for (i = 0; i < set->ks_nreqs; i++) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
642 *(set->ks_req[i].kr_data) = set->ks_req[i].kr_preset; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
643 pcbe_ops->pcbe_configure(0, NULL, set->ks_req[i].kr_preset, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
644 0, 0, NULL, &set->ks_req[i].kr_config, NULL); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
645 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
646 |
0 | 647 kpreempt_disable(); |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
648 save_spl = spl_xcall(); |
0 | 649 |
650 /* | |
651 * If the user is doing this on a running set, make sure the counters | |
652 * are stopped first. | |
653 */ | |
654 if ((ctx->kc_flags & KCPC_CTX_FREEZE) == 0) | |
655 pcbe_ops->pcbe_allstop(); | |
656 | |
657 /* | |
658 * Ask the backend to program the hardware. | |
659 */ | |
660 ctx->kc_rawtick = KCPC_GET_TICK(); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
661 KCPC_CTX_FLAG_CLR(ctx, KCPC_CTX_FREEZE); |
0 | 662 pcbe_ops->pcbe_program(ctx); |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
663 splx(save_spl); |
0 | 664 kpreempt_enable(); |
665 | |
666 return (0); | |
667 } | |
668 | |
669 /* | |
670 * Caller must hold kcpc_cpuctx_lock. | |
671 */ | |
672 int | |
673 kcpc_enable(kthread_t *t, int cmd, int enable) | |
674 { | |
675 kcpc_ctx_t *ctx = t->t_cpc_ctx; | |
676 kcpc_set_t *set = t->t_cpc_set; | |
677 kcpc_set_t *newset; | |
678 int i; | |
679 int flag; | |
680 int err; | |
681 | |
682 ASSERT(RW_READ_HELD(&kcpc_cpuctx_lock)); | |
683 | |
684 if (ctx == NULL) { | |
685 /* | |
686 * This thread has a set but no context; it must be a | |
687 * CPU-bound set. | |
688 */ | |
689 ASSERT(t->t_cpc_set != NULL); | |
690 ASSERT(t->t_cpc_set->ks_ctx->kc_cpuid != -1); | |
691 return (EINVAL); | |
692 } else if (ctx->kc_flags & KCPC_CTX_INVALID) | |
693 return (EAGAIN); | |
694 | |
695 if (cmd == CPC_ENABLE) { | |
696 if ((ctx->kc_flags & KCPC_CTX_FREEZE) == 0) | |
697 return (EINVAL); | |
698 kpreempt_disable(); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
699 KCPC_CTX_FLAG_CLR(ctx, KCPC_CTX_FREEZE); |
0 | 700 kcpc_restore(ctx); |
701 kpreempt_enable(); | |
702 } else if (cmd == CPC_DISABLE) { | |
703 if (ctx->kc_flags & KCPC_CTX_FREEZE) | |
704 return (EINVAL); | |
705 kpreempt_disable(); | |
706 kcpc_save(ctx); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
707 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_FREEZE); |
0 | 708 kpreempt_enable(); |
709 } else if (cmd == CPC_USR_EVENTS || cmd == CPC_SYS_EVENTS) { | |
710 /* | |
711 * Strategy for usr/sys: stop counters and update set's presets | |
712 * with current counter values, unbind, update requests with | |
713 * new config, then re-bind. | |
714 */ | |
715 flag = (cmd == CPC_USR_EVENTS) ? | |
716 CPC_COUNT_USER: CPC_COUNT_SYSTEM; | |
717 | |
718 kpreempt_disable(); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
719 KCPC_CTX_FLAG_SET(ctx, |
0 | 720 KCPC_CTX_INVALID | KCPC_CTX_INVALID_STOPPED); |
721 pcbe_ops->pcbe_allstop(); | |
722 kpreempt_enable(); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
723 |
0 | 724 for (i = 0; i < set->ks_nreqs; i++) { |
725 set->ks_req[i].kr_preset = *(set->ks_req[i].kr_data); | |
726 if (enable) | |
727 set->ks_req[i].kr_flags |= flag; | |
728 else | |
729 set->ks_req[i].kr_flags &= ~flag; | |
730 } | |
731 newset = kcpc_dup_set(set); | |
732 if (kcpc_unbind(set) != 0) | |
733 return (EINVAL); | |
734 t->t_cpc_set = newset; | |
735 if (kcpc_bind_thread(newset, t, &err) != 0) { | |
736 t->t_cpc_set = NULL; | |
737 kcpc_free_set(newset); | |
738 return (EINVAL); | |
739 } | |
740 } else | |
741 return (EINVAL); | |
742 | |
743 return (0); | |
744 } | |
745 | |
746 /* | |
747 * Provide PCBEs with a way of obtaining the configs of every counter which will | |
748 * be programmed together. | |
749 * | |
750 * If current is NULL, provide the first config. | |
751 * | |
752 * If data != NULL, caller wants to know where the data store associated with | |
753 * the config we return is located. | |
754 */ | |
755 void * | |
756 kcpc_next_config(void *token, void *current, uint64_t **data) | |
757 { | |
758 int i; | |
759 kcpc_pic_t *pic; | |
760 kcpc_ctx_t *ctx = (kcpc_ctx_t *)token; | |
761 | |
762 if (current == NULL) { | |
763 /* | |
764 * Client would like the first config, which may not be in | |
765 * counter 0; we need to search through the counters for the | |
766 * first config. | |
767 */ | |
768 for (i = 0; i < cpc_ncounters; i++) | |
769 if (ctx->kc_pics[i].kp_req != NULL) | |
770 break; | |
771 /* | |
772 * There are no counters configured for the given context. | |
773 */ | |
774 if (i == cpc_ncounters) | |
775 return (NULL); | |
776 } else { | |
777 /* | |
778 * There surely is a faster way to do this. | |
779 */ | |
780 for (i = 0; i < cpc_ncounters; i++) { | |
781 pic = &ctx->kc_pics[i]; | |
782 | |
783 if (pic->kp_req != NULL && | |
784 current == pic->kp_req->kr_config) | |
785 break; | |
786 } | |
787 | |
788 /* | |
789 * We found the current config at picnum i. Now search for the | |
790 * next configured PIC. | |
791 */ | |
792 for (i++; i < cpc_ncounters; i++) { | |
793 pic = &ctx->kc_pics[i]; | |
794 if (pic->kp_req != NULL) | |
795 break; | |
796 } | |
797 | |
798 if (i == cpc_ncounters) | |
799 return (NULL); | |
800 } | |
801 | |
802 if (data != NULL) { | |
803 *data = ctx->kc_pics[i].kp_req->kr_data; | |
804 } | |
805 | |
806 return (ctx->kc_pics[i].kp_req->kr_config); | |
807 } | |
808 | |
809 | |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
810 kcpc_ctx_t * |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
811 kcpc_ctx_alloc(int kmem_flags) |
0 | 812 { |
813 kcpc_ctx_t *ctx; | |
814 long hash; | |
815 | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
816 ctx = (kcpc_ctx_t *)kmem_zalloc(sizeof (kcpc_ctx_t), kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
817 if (ctx == NULL) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
818 return (NULL); |
0 | 819 |
820 hash = CPC_HASH_CTX(ctx); | |
821 mutex_enter(&kcpc_ctx_llock[hash]); | |
822 ctx->kc_next = kcpc_ctx_list[hash]; | |
823 kcpc_ctx_list[hash] = ctx; | |
824 mutex_exit(&kcpc_ctx_llock[hash]); | |
825 | |
826 ctx->kc_pics = (kcpc_pic_t *)kmem_zalloc(sizeof (kcpc_pic_t) * | |
827 cpc_ncounters, KM_SLEEP); | |
828 | |
829 ctx->kc_cpuid = -1; | |
830 | |
831 return (ctx); | |
832 } | |
833 | |
834 /* | |
835 * Copy set from ctx to the child context, cctx, if it has CPC_BIND_LWP_INHERIT | |
836 * in the flags. | |
837 */ | |
838 static void | |
839 kcpc_ctx_clone(kcpc_ctx_t *ctx, kcpc_ctx_t *cctx) | |
840 { | |
841 kcpc_set_t *ks = ctx->kc_set, *cks; | |
842 int i, j; | |
843 int code; | |
844 | |
845 ASSERT(ks != NULL); | |
846 | |
847 if ((ks->ks_flags & CPC_BIND_LWP_INHERIT) == 0) | |
848 return; | |
849 | |
6275 | 850 cks = kmem_zalloc(sizeof (*cks), KM_SLEEP); |
851 cks->ks_state &= ~KCPC_SET_BOUND; | |
0 | 852 cctx->kc_set = cks; |
853 cks->ks_flags = ks->ks_flags; | |
854 cks->ks_nreqs = ks->ks_nreqs; | |
855 cks->ks_req = kmem_alloc(cks->ks_nreqs * | |
856 sizeof (kcpc_request_t), KM_SLEEP); | |
857 cks->ks_data = kmem_alloc(cks->ks_nreqs * sizeof (uint64_t), | |
858 KM_SLEEP); | |
859 cks->ks_ctx = cctx; | |
860 | |
861 for (i = 0; i < cks->ks_nreqs; i++) { | |
862 cks->ks_req[i].kr_index = ks->ks_req[i].kr_index; | |
863 cks->ks_req[i].kr_picnum = ks->ks_req[i].kr_picnum; | |
864 (void) strncpy(cks->ks_req[i].kr_event, | |
865 ks->ks_req[i].kr_event, CPC_MAX_EVENT_LEN); | |
866 cks->ks_req[i].kr_preset = ks->ks_req[i].kr_preset; | |
867 cks->ks_req[i].kr_flags = ks->ks_req[i].kr_flags; | |
868 cks->ks_req[i].kr_nattrs = ks->ks_req[i].kr_nattrs; | |
869 if (ks->ks_req[i].kr_nattrs > 0) { | |
870 cks->ks_req[i].kr_attr = | |
871 kmem_alloc(ks->ks_req[i].kr_nattrs * | |
5254
38162db71c7d
PSARC 2007/591 Generic x86 Machine Check Architecture
gavinm
parents:
3884
diff
changeset
|
872 sizeof (kcpc_attr_t), KM_SLEEP); |
0 | 873 } |
874 for (j = 0; j < ks->ks_req[i].kr_nattrs; j++) { | |
875 (void) strncpy(cks->ks_req[i].kr_attr[j].ka_name, | |
876 ks->ks_req[i].kr_attr[j].ka_name, | |
877 CPC_MAX_ATTR_LEN); | |
878 cks->ks_req[i].kr_attr[j].ka_val = | |
879 ks->ks_req[i].kr_attr[j].ka_val; | |
880 } | |
881 } | |
882 if (kcpc_configure_reqs(cctx, cks, &code) != 0) | |
3732 | 883 kcpc_invalidate_config(cctx); |
6275 | 884 |
885 mutex_enter(&cks->ks_lock); | |
886 cks->ks_state |= KCPC_SET_BOUND; | |
887 cv_signal(&cks->ks_condv); | |
888 mutex_exit(&cks->ks_lock); | |
0 | 889 } |
890 | |
891 | |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
892 void |
0 | 893 kcpc_ctx_free(kcpc_ctx_t *ctx) |
894 { | |
895 kcpc_ctx_t **loc; | |
896 long hash = CPC_HASH_CTX(ctx); | |
897 | |
898 mutex_enter(&kcpc_ctx_llock[hash]); | |
899 loc = &kcpc_ctx_list[hash]; | |
900 ASSERT(*loc != NULL); | |
901 while (*loc != ctx) | |
902 loc = &(*loc)->kc_next; | |
903 *loc = ctx->kc_next; | |
904 mutex_exit(&kcpc_ctx_llock[hash]); | |
905 | |
906 kmem_free(ctx->kc_pics, cpc_ncounters * sizeof (kcpc_pic_t)); | |
6275 | 907 cv_destroy(&ctx->kc_condv); |
908 mutex_destroy(&ctx->kc_lock); | |
0 | 909 kmem_free(ctx, sizeof (*ctx)); |
910 } | |
911 | |
912 /* | |
913 * Generic interrupt handler used on hardware that generates | |
914 * overflow interrupts. | |
915 * | |
916 * Note: executed at high-level interrupt context! | |
917 */ | |
918 /*ARGSUSED*/ | |
919 kcpc_ctx_t * | |
920 kcpc_overflow_intr(caddr_t arg, uint64_t bitmap) | |
921 { | |
922 kcpc_ctx_t *ctx; | |
923 kthread_t *t = curthread; | |
924 int i; | |
925 | |
926 /* | |
927 * On both x86 and UltraSPARC, we may deliver the high-level | |
928 * interrupt in kernel mode, just after we've started to run an | |
929 * interrupt thread. (That's because the hardware helpfully | |
930 * delivers the overflow interrupt some random number of cycles | |
931 * after the instruction that caused the overflow by which time | |
932 * we're in some part of the kernel, not necessarily running on | |
933 * the right thread). | |
934 * | |
935 * Check for this case here -- find the pinned thread | |
936 * that was running when the interrupt went off. | |
937 */ | |
938 if (t->t_flag & T_INTR_THREAD) { | |
939 klwp_t *lwp; | |
940 | |
941 atomic_add_32(&kcpc_intrctx_count, 1); | |
942 | |
943 /* | |
944 * Note that t_lwp is always set to point at the underlying | |
945 * thread, thus this will work in the presence of nested | |
946 * interrupts. | |
947 */ | |
948 ctx = NULL; | |
949 if ((lwp = t->t_lwp) != NULL) { | |
950 t = lwptot(lwp); | |
951 ctx = t->t_cpc_ctx; | |
952 } | |
953 } else | |
954 ctx = t->t_cpc_ctx; | |
955 | |
956 if (ctx == NULL) { | |
957 /* | |
958 * This can easily happen if we're using the counters in | |
959 * "shared" mode, for example, and an overflow interrupt | |
960 * occurs while we are running cpustat. In that case, the | |
961 * bound thread that has the context that belongs to this | |
962 * CPU is almost certainly sleeping (if it was running on | |
963 * the CPU we'd have found it above), and the actual | |
964 * interrupted thread has no knowledge of performance counters! | |
965 */ | |
966 ctx = curthread->t_cpu->cpu_cpc_ctx; | |
967 if (ctx != NULL) { | |
968 /* | |
969 * Return the bound context for this CPU to | |
970 * the interrupt handler so that it can synchronously | |
971 * sample the hardware counters and restart them. | |
972 */ | |
973 return (ctx); | |
974 } | |
975 | |
976 /* | |
977 * As long as the overflow interrupt really is delivered early | |
978 * enough after trapping into the kernel to avoid switching | |
979 * threads, we must always be able to find the cpc context, | |
980 * or something went terribly wrong i.e. we ended up | |
981 * running a passivated interrupt thread, a kernel | |
982 * thread or we interrupted idle, all of which are Very Bad. | |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
983 * |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
984 * We also could end up here owing to an incredibly unlikely |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
985 * race condition that exists on x86 based architectures when |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
986 * the cpc provider is in use; overflow interrupts are directed |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
987 * to the cpc provider if the 'dtrace_cpc_in_use' variable is |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
988 * set when we enter the handler. This variable is unset after |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
989 * overflow interrupts have been disabled on all CPUs and all |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
990 * contexts have been torn down. To stop interrupts, the cpc |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
991 * provider issues a xcall to the remote CPU before it tears |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
992 * down that CPUs context. As high priority xcalls, on an x86 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
993 * architecture, execute at a higher PIL than this handler, it |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
994 * is possible (though extremely unlikely) that the xcall could |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
995 * interrupt the overflow handler before the handler has |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
996 * checked the 'dtrace_cpc_in_use' variable, stop the counters, |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
997 * return to the cpc provider which could then rip down |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
998 * contexts and unset 'dtrace_cpc_in_use' *before* the CPUs |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
999 * overflow handler has had a chance to check the variable. In |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1000 * that case, the handler would direct the overflow into this |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1001 * code and no valid context will be found. The default behavior |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1002 * when no valid context is found is now to shout a warning to |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1003 * the console and bump the 'kcpc_nullctx_count' variable. |
0 | 1004 */ |
1005 if (kcpc_nullctx_panic) | |
1006 panic("null cpc context, thread %p", (void *)t); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1007 #ifdef DEBUG |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1008 cmn_err(CE_NOTE, |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1009 "null cpc context found in overflow handler!\n"); |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1010 #endif |
0 | 1011 atomic_add_32(&kcpc_nullctx_count, 1); |
1012 } else if ((ctx->kc_flags & KCPC_CTX_INVALID) == 0) { | |
1013 /* | |
1014 * Schedule an ast to sample the counters, which will | |
1015 * propagate any overflow into the virtualized performance | |
1016 * counter(s), and may deliver a signal. | |
1017 */ | |
1018 ttolwp(t)->lwp_pcb.pcb_flags |= CPC_OVERFLOW; | |
1019 /* | |
1020 * If a counter has overflowed which was counting on behalf of | |
1021 * a request which specified CPC_OVF_NOTIFY_EMT, send the | |
1022 * process a signal. | |
1023 */ | |
1024 for (i = 0; i < cpc_ncounters; i++) { | |
1025 if (ctx->kc_pics[i].kp_req != NULL && | |
1026 bitmap & (1 << i) && | |
1027 ctx->kc_pics[i].kp_req->kr_flags & | |
1028 CPC_OVF_NOTIFY_EMT) { | |
1029 /* | |
1030 * A signal has been requested for this PIC, so | |
1031 * so freeze the context. The interrupt handler | |
1032 * has already stopped the counter hardware. | |
1033 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1034 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_FREEZE); |
0 | 1035 atomic_or_uint(&ctx->kc_pics[i].kp_flags, |
1036 KCPC_PIC_OVERFLOWED); | |
1037 } | |
1038 } | |
1039 aston(t); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1040 } else if (ctx->kc_flags & KCPC_CTX_INVALID_STOPPED) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1041 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1042 * Thread context is no longer valid, but here may be a valid |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1043 * CPU context. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1044 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1045 return (curthread->t_cpu->cpu_cpc_ctx); |
0 | 1046 } |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1047 |
0 | 1048 return (NULL); |
1049 } | |
1050 | |
1051 /* | |
1052 * The current thread context had an overflow interrupt; we're | |
1053 * executing here in high-level interrupt context. | |
1054 */ | |
1055 /*ARGSUSED*/ | |
1056 uint_t | |
1057 kcpc_hw_overflow_intr(caddr_t arg1, caddr_t arg2) | |
1058 { | |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1059 kcpc_ctx_t *ctx; |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1060 uint64_t bitmap; |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1061 uint8_t *state; |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1062 int save_spl; |
0 | 1063 |
1064 if (pcbe_ops == NULL || | |
1065 (bitmap = pcbe_ops->pcbe_overflow_bitmap()) == 0) | |
1066 return (DDI_INTR_UNCLAIMED); | |
3884 | 1067 |
0 | 1068 /* |
1069 * Prevent any further interrupts. | |
1070 */ | |
1071 pcbe_ops->pcbe_allstop(); | |
1072 | |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1073 if (dtrace_cpc_in_use) { |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1074 state = &cpu_core[CPU->cpu_id].cpuc_dcpc_intr_state; |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1075 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1076 /* |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1077 * Set the per-CPU state bit to indicate that we are currently |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1078 * processing an interrupt if it is currently free. Drop the |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1079 * interrupt if the state isn't free (i.e. a configuration |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1080 * event is taking place). |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1081 */ |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1082 if (atomic_cas_8(state, DCPC_INTR_FREE, |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1083 DCPC_INTR_PROCESSING) == DCPC_INTR_FREE) { |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1084 int i; |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1085 kcpc_request_t req; |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1086 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1087 ASSERT(dtrace_cpc_fire != NULL); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1088 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1089 (*dtrace_cpc_fire)(bitmap); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1090 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1091 ctx = curthread->t_cpu->cpu_cpc_ctx; |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1092 if (ctx == NULL) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1093 #ifdef DEBUG |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1094 cmn_err(CE_NOTE, "null cpc context in" |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1095 "hardware overflow handler!\n"); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1096 #endif |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1097 return (DDI_INTR_CLAIMED); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1098 } |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1099 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1100 /* Reset any counters that have overflowed */ |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1101 for (i = 0; i < ctx->kc_set->ks_nreqs; i++) { |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1102 req = ctx->kc_set->ks_req[i]; |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1103 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1104 if (bitmap & (1 << req.kr_picnum)) { |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1105 pcbe_ops->pcbe_configure(req.kr_picnum, |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1106 req.kr_event, req.kr_preset, |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1107 req.kr_flags, req.kr_nattrs, |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1108 req.kr_attr, &(req.kr_config), |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1109 (void *)ctx); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1110 } |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1111 } |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1112 pcbe_ops->pcbe_program(ctx); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1113 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1114 /* |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1115 * We've finished processing the interrupt so set |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1116 * the state back to free. |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1117 */ |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1118 cpu_core[CPU->cpu_id].cpuc_dcpc_intr_state = |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1119 DCPC_INTR_FREE; |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1120 membar_producer(); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1121 } |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1122 return (DDI_INTR_CLAIMED); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1123 } |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1124 |
0 | 1125 /* |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1126 * DTrace isn't involved so pass on accordingly. |
0 | 1127 * |
1128 * If the interrupt has occurred in the context of an lwp owning | |
1129 * the counters, then the handler posts an AST to the lwp to | |
1130 * trigger the actual sampling, and optionally deliver a signal or | |
1131 * restart the counters, on the way out of the kernel using | |
1132 * kcpc_hw_overflow_ast() (see below). | |
1133 * | |
1134 * On the other hand, if the handler returns the context to us | |
1135 * directly, then it means that there are no other threads in | |
1136 * the middle of updating it, no AST has been posted, and so we | |
1137 * should sample the counters here, and restart them with no | |
1138 * further fuss. | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1139 * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1140 * The CPU's CPC context may disappear as a result of cross-call which |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1141 * has higher PIL on x86, so protect the context by raising PIL to the |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1142 * cross-call level. |
0 | 1143 */ |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1144 save_spl = spl_xcall(); |
0 | 1145 if ((ctx = kcpc_overflow_intr(arg1, bitmap)) != NULL) { |
1146 uint64_t curtick = KCPC_GET_TICK(); | |
1147 | |
1148 ctx->kc_hrtime = gethrtime_waitfree(); | |
1149 ctx->kc_vtick += curtick - ctx->kc_rawtick; | |
1150 ctx->kc_rawtick = curtick; | |
1151 pcbe_ops->pcbe_sample(ctx); | |
1152 pcbe_ops->pcbe_program(ctx); | |
1153 } | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1154 splx(save_spl); |
0 | 1155 |
1156 return (DDI_INTR_CLAIMED); | |
1157 } | |
1158 | |
1159 /* | |
1160 * Called from trap() when processing the ast posted by the high-level | |
1161 * interrupt handler. | |
1162 */ | |
1163 int | |
1164 kcpc_overflow_ast() | |
1165 { | |
1166 kcpc_ctx_t *ctx = curthread->t_cpc_ctx; | |
1167 int i; | |
1168 int found = 0; | |
1169 uint64_t curtick = KCPC_GET_TICK(); | |
1170 | |
1171 ASSERT(ctx != NULL); /* Beware of interrupt skid. */ | |
1172 | |
1173 /* | |
1174 * An overflow happened: sample the context to ensure that | |
1175 * the overflow is propagated into the upper bits of the | |
1176 * virtualized 64-bit counter(s). | |
1177 */ | |
1178 kpreempt_disable(); | |
1179 ctx->kc_hrtime = gethrtime_waitfree(); | |
1180 pcbe_ops->pcbe_sample(ctx); | |
1181 kpreempt_enable(); | |
1182 | |
1183 ctx->kc_vtick += curtick - ctx->kc_rawtick; | |
1184 | |
1185 /* | |
1186 * The interrupt handler has marked any pics with KCPC_PIC_OVERFLOWED | |
1187 * if that pic generated an overflow and if the request it was counting | |
1188 * on behalf of had CPC_OVERFLOW_REQUEST specified. We go through all | |
1189 * pics in the context and clear the KCPC_PIC_OVERFLOWED flags. If we | |
1190 * found any overflowed pics, keep the context frozen and return true | |
1191 * (thus causing a signal to be sent). | |
1192 */ | |
1193 for (i = 0; i < cpc_ncounters; i++) { | |
1194 if (ctx->kc_pics[i].kp_flags & KCPC_PIC_OVERFLOWED) { | |
1195 atomic_and_uint(&ctx->kc_pics[i].kp_flags, | |
1196 ~KCPC_PIC_OVERFLOWED); | |
1197 found = 1; | |
1198 } | |
1199 } | |
1200 if (found) | |
1201 return (1); | |
1202 | |
1203 /* | |
1204 * Otherwise, re-enable the counters and continue life as before. | |
1205 */ | |
1206 kpreempt_disable(); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1207 KCPC_CTX_FLAG_CLR(ctx, KCPC_CTX_FREEZE); |
0 | 1208 pcbe_ops->pcbe_program(ctx); |
1209 kpreempt_enable(); | |
1210 return (0); | |
1211 } | |
1212 | |
1213 /* | |
1214 * Called when switching away from current thread. | |
1215 */ | |
1216 static void | |
1217 kcpc_save(kcpc_ctx_t *ctx) | |
1218 { | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1219 int err; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1220 int save_spl; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1221 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1222 kpreempt_disable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1223 save_spl = spl_xcall(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1224 |
0 | 1225 if (ctx->kc_flags & KCPC_CTX_INVALID) { |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1226 if (ctx->kc_flags & KCPC_CTX_INVALID_STOPPED) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1227 splx(save_spl); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1228 kpreempt_enable(); |
0 | 1229 return; |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1230 } |
0 | 1231 /* |
1232 * This context has been invalidated but the counters have not | |
1233 * been stopped. Stop them here and mark the context stopped. | |
1234 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1235 kcpc_unprogram(ctx, B_TRUE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1236 splx(save_spl); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1237 kpreempt_enable(); |
0 | 1238 return; |
1239 } | |
1240 | |
1241 pcbe_ops->pcbe_allstop(); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1242 if (ctx->kc_flags & KCPC_CTX_FREEZE) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1243 splx(save_spl); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1244 kpreempt_enable(); |
0 | 1245 return; |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1246 } |
0 | 1247 |
1248 /* | |
1249 * Need to sample for all reqs into each req's current mpic. | |
1250 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1251 ctx->kc_hrtime = gethrtime_waitfree(); |
0 | 1252 ctx->kc_vtick += KCPC_GET_TICK() - ctx->kc_rawtick; |
1253 pcbe_ops->pcbe_sample(ctx); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1254 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1255 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1256 * Program counter for measuring capacity and utilization since user |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1257 * thread isn't using counter anymore |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1258 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1259 ASSERT(ctx->kc_cpuid == -1); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1260 cu_cpc_program(CPU, &err); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1261 splx(save_spl); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1262 kpreempt_enable(); |
0 | 1263 } |
1264 | |
1265 static void | |
1266 kcpc_restore(kcpc_ctx_t *ctx) | |
1267 { | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1268 int save_spl; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1269 |
6275 | 1270 mutex_enter(&ctx->kc_lock); |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1271 |
0 | 1272 if ((ctx->kc_flags & (KCPC_CTX_INVALID | KCPC_CTX_INVALID_STOPPED)) == |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1273 KCPC_CTX_INVALID) { |
0 | 1274 /* |
1275 * The context is invalidated but has not been marked stopped. | |
1276 * We mark it as such here because we will not start the | |
1277 * counters during this context switch. | |
1278 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1279 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_INVALID_STOPPED); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1280 } |
0 | 1281 |
6275 | 1282 if (ctx->kc_flags & (KCPC_CTX_INVALID | KCPC_CTX_FREEZE)) { |
1283 mutex_exit(&ctx->kc_lock); | |
0 | 1284 return; |
6275 | 1285 } |
1286 | |
1287 /* | |
1288 * Set kc_flags to show that a kcpc_restore() is in progress to avoid | |
1289 * ctx & set related memory objects being freed without us knowing. | |
1290 * This can happen if an agent thread is executing a kcpc_unbind(), | |
1291 * with this thread as the target, whilst we're concurrently doing a | |
1292 * restorectx() during, for example, a proc_exit(). Effectively, by | |
1293 * doing this, we're asking kcpc_free() to cv_wait() until | |
1294 * kcpc_restore() has completed. | |
1295 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1296 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_RESTORE); |
6275 | 1297 mutex_exit(&ctx->kc_lock); |
0 | 1298 |
1299 /* | |
1300 * While programming the hardware, the counters should be stopped. We | |
1301 * don't do an explicit pcbe_allstop() here because they should have | |
1302 * been stopped already by the last consumer. | |
1303 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1304 kpreempt_disable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1305 save_spl = spl_xcall(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1306 kcpc_program(ctx, B_TRUE, B_TRUE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1307 splx(save_spl); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1308 kpreempt_enable(); |
6275 | 1309 |
1310 /* | |
1311 * Wake the agent thread if it's waiting in kcpc_free(). | |
1312 */ | |
1313 mutex_enter(&ctx->kc_lock); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1314 KCPC_CTX_FLAG_CLR(ctx, KCPC_CTX_RESTORE); |
6275 | 1315 cv_signal(&ctx->kc_condv); |
1316 mutex_exit(&ctx->kc_lock); | |
0 | 1317 } |
1318 | |
1319 /* | |
1320 * If kcpc_counts_include_idle is set to 0 by the sys admin, we add the the | |
1321 * following context operators to the idle thread on each CPU. They stop the | |
1322 * counters when the idle thread is switched on, and they start them again when | |
1323 * it is switched off. | |
1324 */ | |
1325 /*ARGSUSED*/ | |
1326 void | |
1327 kcpc_idle_save(struct cpu *cp) | |
1328 { | |
1329 /* | |
1330 * The idle thread shouldn't be run anywhere else. | |
1331 */ | |
1332 ASSERT(CPU == cp); | |
1333 | |
1334 /* | |
1335 * We must hold the CPU's context lock to ensure the context isn't freed | |
1336 * while we're looking at it. | |
1337 */ | |
1338 mutex_enter(&cp->cpu_cpc_ctxlock); | |
1339 | |
1340 if ((cp->cpu_cpc_ctx == NULL) || | |
1341 (cp->cpu_cpc_ctx->kc_flags & KCPC_CTX_INVALID)) { | |
1342 mutex_exit(&cp->cpu_cpc_ctxlock); | |
1343 return; | |
1344 } | |
1345 | |
1346 pcbe_ops->pcbe_program(cp->cpu_cpc_ctx); | |
1347 mutex_exit(&cp->cpu_cpc_ctxlock); | |
1348 } | |
1349 | |
1350 void | |
1351 kcpc_idle_restore(struct cpu *cp) | |
1352 { | |
1353 /* | |
1354 * The idle thread shouldn't be run anywhere else. | |
1355 */ | |
1356 ASSERT(CPU == cp); | |
1357 | |
1358 /* | |
1359 * We must hold the CPU's context lock to ensure the context isn't freed | |
1360 * while we're looking at it. | |
1361 */ | |
1362 mutex_enter(&cp->cpu_cpc_ctxlock); | |
1363 | |
1364 if ((cp->cpu_cpc_ctx == NULL) || | |
1365 (cp->cpu_cpc_ctx->kc_flags & KCPC_CTX_INVALID)) { | |
1366 mutex_exit(&cp->cpu_cpc_ctxlock); | |
1367 return; | |
1368 } | |
1369 | |
1370 pcbe_ops->pcbe_allstop(); | |
1371 mutex_exit(&cp->cpu_cpc_ctxlock); | |
1372 } | |
1373 | |
1374 /*ARGSUSED*/ | |
1375 static void | |
1376 kcpc_lwp_create(kthread_t *t, kthread_t *ct) | |
1377 { | |
1378 kcpc_ctx_t *ctx = t->t_cpc_ctx, *cctx; | |
1379 int i; | |
1380 | |
1381 if (ctx == NULL || (ctx->kc_flags & KCPC_CTX_LWPINHERIT) == 0) | |
1382 return; | |
1383 | |
1384 rw_enter(&kcpc_cpuctx_lock, RW_READER); | |
1385 if (ctx->kc_flags & KCPC_CTX_INVALID) { | |
1386 rw_exit(&kcpc_cpuctx_lock); | |
1387 return; | |
1388 } | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1389 cctx = kcpc_ctx_alloc(KM_SLEEP); |
0 | 1390 kcpc_ctx_clone(ctx, cctx); |
1391 rw_exit(&kcpc_cpuctx_lock); | |
1392 | |
3732 | 1393 /* |
1394 * Copy the parent context's kc_flags field, but don't overwrite | |
1395 * the child's in case it was modified during kcpc_ctx_clone. | |
1396 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1397 KCPC_CTX_FLAG_SET(cctx, ctx->kc_flags); |
0 | 1398 cctx->kc_thread = ct; |
1399 cctx->kc_cpuid = -1; | |
1400 ct->t_cpc_set = cctx->kc_set; | |
1401 ct->t_cpc_ctx = cctx; | |
1402 | |
1403 if (cctx->kc_flags & KCPC_CTX_SIGOVF) { | |
1404 kcpc_set_t *ks = cctx->kc_set; | |
1405 /* | |
1406 * Our contract with the user requires us to immediately send an | |
1407 * overflow signal to all children if we have the LWPINHERIT | |
1408 * and SIGOVF flags set. In addition, all counters should be | |
1409 * set to UINT64_MAX, and their pic's overflow flag turned on | |
1410 * so that our trap() processing knows to send a signal. | |
1411 */ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1412 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_FREEZE); |
0 | 1413 for (i = 0; i < ks->ks_nreqs; i++) { |
1414 kcpc_request_t *kr = &ks->ks_req[i]; | |
1415 | |
1416 if (kr->kr_flags & CPC_OVF_NOTIFY_EMT) { | |
1417 *(kr->kr_data) = UINT64_MAX; | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1418 atomic_or_uint(&kr->kr_picp->kp_flags, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1419 KCPC_PIC_OVERFLOWED); |
0 | 1420 } |
1421 } | |
1422 ttolwp(ct)->lwp_pcb.pcb_flags |= CPC_OVERFLOW; | |
1423 aston(ct); | |
1424 } | |
1425 | |
1426 installctx(ct, cctx, kcpc_save, kcpc_restore, | |
1427 NULL, kcpc_lwp_create, NULL, kcpc_free); | |
1428 } | |
1429 | |
1430 /* | |
1431 * Counter Stoppage Theory | |
1432 * | |
1433 * The counters may need to be stopped properly at the following occasions: | |
1434 * | |
1435 * 1) An LWP exits. | |
1436 * 2) A thread exits. | |
1437 * 3) An LWP performs an exec(). | |
1438 * 4) A bound set is unbound. | |
1439 * | |
1440 * In addition to stopping the counters, the CPC context (a kcpc_ctx_t) may need | |
1441 * to be freed as well. | |
1442 * | |
1443 * Case 1: kcpc_passivate(), called via lwp_exit(), stops the counters. Later on | |
1444 * when the thread is freed, kcpc_free(), called by freectx(), frees the | |
1445 * context. | |
1446 * | |
1447 * Case 2: same as case 1 except kcpc_passivate is called from thread_exit(). | |
1448 * | |
1449 * Case 3: kcpc_free(), called via freectx() via exec(), recognizes that it has | |
1450 * been called from exec. It stops the counters _and_ frees the context. | |
1451 * | |
1452 * Case 4: kcpc_unbind() stops the hardware _and_ frees the context. | |
1453 * | |
1454 * CPU-bound counters are always stopped via kcpc_unbind(). | |
1455 */ | |
1456 | |
1457 /* | |
1458 * We're being called to delete the context; we ensure that all associated data | |
1459 * structures are freed, and that the hardware is passivated if this is an exec. | |
1460 */ | |
1461 | |
1462 /*ARGSUSED*/ | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1463 void |
0 | 1464 kcpc_free(kcpc_ctx_t *ctx, int isexec) |
1465 { | |
1466 int i; | |
1467 kcpc_set_t *set = ctx->kc_set; | |
1468 | |
1469 ASSERT(set != NULL); | |
1470 | |
6275 | 1471 /* |
1472 * Wait for kcpc_restore() to finish before we tear things down. | |
1473 */ | |
1474 mutex_enter(&ctx->kc_lock); | |
1475 while (ctx->kc_flags & KCPC_CTX_RESTORE) | |
1476 cv_wait(&ctx->kc_condv, &ctx->kc_lock); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1477 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_INVALID); |
6275 | 1478 mutex_exit(&ctx->kc_lock); |
0 | 1479 |
1480 if (isexec) { | |
1481 /* | |
1482 * This thread is execing, and after the exec it should not have | |
1483 * any performance counter context. Stop the counters properly | |
1484 * here so the system isn't surprised by an overflow interrupt | |
1485 * later. | |
1486 */ | |
1487 if (ctx->kc_cpuid != -1) { | |
1488 cpu_t *cp; | |
1489 /* | |
1490 * CPU-bound context; stop the appropriate CPU's ctrs. | |
1491 * Hold cpu_lock while examining the CPU to ensure it | |
1492 * doesn't go away. | |
1493 */ | |
1494 mutex_enter(&cpu_lock); | |
1495 cp = cpu_get(ctx->kc_cpuid); | |
1496 /* | |
1497 * The CPU could have been DR'd out, so only stop the | |
1498 * CPU and clear its context pointer if the CPU still | |
1499 * exists. | |
1500 */ | |
1501 if (cp != NULL) { | |
1502 mutex_enter(&cp->cpu_cpc_ctxlock); | |
1503 kcpc_stop_hw(ctx); | |
1504 mutex_exit(&cp->cpu_cpc_ctxlock); | |
1505 } | |
1506 mutex_exit(&cpu_lock); | |
1507 ASSERT(curthread->t_cpc_ctx == NULL); | |
1508 } else { | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1509 int save_spl; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1510 |
0 | 1511 /* |
1512 * Thread-bound context; stop _this_ CPU's counters. | |
1513 */ | |
1514 kpreempt_disable(); | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1515 save_spl = spl_xcall(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1516 kcpc_unprogram(ctx, B_TRUE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1517 curthread->t_cpc_ctx = NULL; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1518 splx(save_spl); |
0 | 1519 kpreempt_enable(); |
1520 } | |
1521 | |
1522 /* | |
1523 * Since we are being called from an exec and we know that | |
1524 * exec is not permitted via the agent thread, we should clean | |
1525 * up this thread's CPC state completely, and not leave dangling | |
1526 * CPC pointers behind. | |
1527 */ | |
1528 ASSERT(ctx->kc_thread == curthread); | |
1529 curthread->t_cpc_set = NULL; | |
1530 } | |
1531 | |
1532 /* | |
1533 * Walk through each request in this context's set and free the PCBE's | |
1534 * configuration if it exists. | |
1535 */ | |
1536 for (i = 0; i < set->ks_nreqs; i++) { | |
1537 if (set->ks_req[i].kr_config != NULL) | |
1538 pcbe_ops->pcbe_free(set->ks_req[i].kr_config); | |
1539 } | |
1540 | |
1541 kmem_free(set->ks_data, set->ks_nreqs * sizeof (uint64_t)); | |
1542 kcpc_ctx_free(ctx); | |
1543 kcpc_free_set(set); | |
1544 } | |
1545 | |
1546 /* | |
1547 * Free the memory associated with a request set. | |
1548 */ | |
1549 void | |
1550 kcpc_free_set(kcpc_set_t *set) | |
1551 { | |
1552 int i; | |
1553 kcpc_request_t *req; | |
1554 | |
1555 ASSERT(set->ks_req != NULL); | |
1556 | |
1557 for (i = 0; i < set->ks_nreqs; i++) { | |
1558 req = &set->ks_req[i]; | |
1559 | |
1560 if (req->kr_nattrs != 0) { | |
1561 kmem_free(req->kr_attr, | |
1562 req->kr_nattrs * sizeof (kcpc_attr_t)); | |
1563 } | |
1564 } | |
1565 | |
1566 kmem_free(set->ks_req, sizeof (kcpc_request_t) * set->ks_nreqs); | |
6275 | 1567 cv_destroy(&set->ks_condv); |
1568 mutex_destroy(&set->ks_lock); | |
0 | 1569 kmem_free(set, sizeof (kcpc_set_t)); |
1570 } | |
1571 | |
1572 /* | |
1573 * Grab every existing context and mark it as invalid. | |
1574 */ | |
1575 void | |
1576 kcpc_invalidate_all(void) | |
1577 { | |
1578 kcpc_ctx_t *ctx; | |
1579 long hash; | |
1580 | |
1581 for (hash = 0; hash < CPC_HASH_BUCKETS; hash++) { | |
1582 mutex_enter(&kcpc_ctx_llock[hash]); | |
1583 for (ctx = kcpc_ctx_list[hash]; ctx; ctx = ctx->kc_next) | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1584 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_INVALID); |
0 | 1585 mutex_exit(&kcpc_ctx_llock[hash]); |
1586 } | |
1587 } | |
1588 | |
1589 /* | |
3732 | 1590 * Interface for PCBEs to signal that an existing configuration has suddenly |
1591 * become invalid. | |
1592 */ | |
1593 void | |
1594 kcpc_invalidate_config(void *token) | |
1595 { | |
1596 kcpc_ctx_t *ctx = token; | |
1597 | |
1598 ASSERT(ctx != NULL); | |
1599 | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1600 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_INVALID); |
3732 | 1601 } |
1602 | |
1603 /* | |
0 | 1604 * Called from lwp_exit() and thread_exit() |
1605 */ | |
1606 void | |
1607 kcpc_passivate(void) | |
1608 { | |
1609 kcpc_ctx_t *ctx = curthread->t_cpc_ctx; | |
1610 kcpc_set_t *set = curthread->t_cpc_set; | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1611 int save_spl; |
0 | 1612 |
1613 if (set == NULL) | |
1614 return; | |
1615 | |
1616 if (ctx == NULL) { | |
1617 /* | |
1618 * This thread has a set but no context; it must be a CPU-bound | |
1619 * set. The hardware will be stopped via kcpc_unbind() when the | |
1620 * process exits and closes its file descriptors with | |
1621 * kcpc_close(). Our only job here is to clean up this thread's | |
1622 * state; the set will be freed with the unbind(). | |
1623 */ | |
1624 (void) kcpc_unbind(set); | |
1625 /* | |
1626 * Unbinding a set belonging to the current thread should clear | |
1627 * its set pointer. | |
1628 */ | |
1629 ASSERT(curthread->t_cpc_set == NULL); | |
1630 return; | |
1631 } | |
1632 | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1633 kpreempt_disable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1634 save_spl = spl_xcall(); |
0 | 1635 curthread->t_cpc_set = NULL; |
1636 | |
1637 /* | |
1638 * This thread/LWP is exiting but context switches will continue to | |
1639 * happen for a bit as the exit proceeds. Kernel preemption must be | |
1640 * disabled here to prevent a race between checking or setting the | |
1641 * INVALID_STOPPED flag here and kcpc_restore() setting the flag during | |
1642 * a context switch. | |
1643 */ | |
1644 if ((ctx->kc_flags & KCPC_CTX_INVALID_STOPPED) == 0) { | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1645 kcpc_unprogram(ctx, B_TRUE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1646 KCPC_CTX_FLAG_SET(ctx, |
0 | 1647 KCPC_CTX_INVALID | KCPC_CTX_INVALID_STOPPED); |
1648 } | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1649 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1650 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1651 * We're cleaning up after this thread; ensure there are no dangling |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1652 * CPC pointers left behind. The context and set will be freed by |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1653 * freectx(). |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1654 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1655 curthread->t_cpc_ctx = NULL; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1656 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1657 splx(save_spl); |
0 | 1658 kpreempt_enable(); |
1659 } | |
1660 | |
1661 /* | |
1662 * Assign the requests in the given set to the PICs in the context. | |
1663 * Returns 0 if successful, -1 on failure. | |
1664 */ | |
1665 /*ARGSUSED*/ | |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1666 int |
0 | 1667 kcpc_assign_reqs(kcpc_set_t *set, kcpc_ctx_t *ctx) |
1668 { | |
1669 int i; | |
1670 int *picnum_save; | |
1671 | |
1672 ASSERT(set->ks_nreqs <= cpc_ncounters); | |
1673 | |
1674 /* | |
1675 * Provide kcpc_tryassign() with scratch space to avoid doing an | |
1676 * alloc/free with every invocation. | |
1677 */ | |
1678 picnum_save = kmem_alloc(set->ks_nreqs * sizeof (int), KM_SLEEP); | |
1679 /* | |
1680 * kcpc_tryassign() blindly walks through each request in the set, | |
1681 * seeing if a counter can count its event. If yes, it assigns that | |
1682 * counter. However, that counter may have been the only capable counter | |
1683 * for _another_ request's event. The solution is to try every possible | |
1684 * request first. Note that this does not cover all solutions, as | |
1685 * that would require all unique orderings of requests, an n^n operation | |
1686 * which would be unacceptable for architectures with many counters. | |
1687 */ | |
1688 for (i = 0; i < set->ks_nreqs; i++) | |
1689 if (kcpc_tryassign(set, i, picnum_save) == 0) | |
1690 break; | |
1691 | |
1692 kmem_free(picnum_save, set->ks_nreqs * sizeof (int)); | |
1693 if (i == set->ks_nreqs) | |
1694 return (-1); | |
1695 return (0); | |
1696 } | |
1697 | |
1698 static int | |
1699 kcpc_tryassign(kcpc_set_t *set, int starting_req, int *scratch) | |
1700 { | |
1701 int i; | |
1702 int j; | |
1703 uint64_t bitmap = 0, resmap = 0; | |
1704 uint64_t ctrmap; | |
1705 | |
1706 /* | |
1707 * We are attempting to assign the reqs to pics, but we may fail. If we | |
1708 * fail, we need to restore the state of the requests to what it was | |
1709 * when we found it, as some reqs may have been explicitly assigned to | |
1710 * a specific PIC beforehand. We do this by snapshotting the assignments | |
1711 * now and restoring from it later if we fail. | |
1712 * | |
1713 * Also we note here which counters have already been claimed by | |
1714 * requests with explicit counter assignments. | |
1715 */ | |
1716 for (i = 0; i < set->ks_nreqs; i++) { | |
1717 scratch[i] = set->ks_req[i].kr_picnum; | |
1718 if (set->ks_req[i].kr_picnum != -1) | |
1719 resmap |= (1 << set->ks_req[i].kr_picnum); | |
1720 } | |
1721 | |
1722 /* | |
1723 * Walk through requests assigning them to the first PIC that is | |
1724 * capable. | |
1725 */ | |
1726 i = starting_req; | |
1727 do { | |
1728 if (set->ks_req[i].kr_picnum != -1) { | |
1729 ASSERT((bitmap & (1 << set->ks_req[i].kr_picnum)) == 0); | |
1730 bitmap |= (1 << set->ks_req[i].kr_picnum); | |
1731 if (++i == set->ks_nreqs) | |
1732 i = 0; | |
1733 continue; | |
1734 } | |
1735 | |
1736 ctrmap = pcbe_ops->pcbe_event_coverage(set->ks_req[i].kr_event); | |
1737 for (j = 0; j < cpc_ncounters; j++) { | |
1738 if (ctrmap & (1 << j) && (bitmap & (1 << j)) == 0 && | |
1739 (resmap & (1 << j)) == 0) { | |
1740 /* | |
1741 * We can assign this counter because: | |
1742 * | |
1743 * 1. It can count the event (ctrmap) | |
1744 * 2. It hasn't been assigned yet (bitmap) | |
1745 * 3. It wasn't reserved by a request (resmap) | |
1746 */ | |
1747 bitmap |= (1 << j); | |
1748 break; | |
1749 } | |
1750 } | |
1751 if (j == cpc_ncounters) { | |
1752 for (i = 0; i < set->ks_nreqs; i++) | |
1753 set->ks_req[i].kr_picnum = scratch[i]; | |
1754 return (-1); | |
1755 } | |
1756 set->ks_req[i].kr_picnum = j; | |
1757 | |
1758 if (++i == set->ks_nreqs) | |
1759 i = 0; | |
1760 } while (i != starting_req); | |
1761 | |
1762 return (0); | |
1763 } | |
1764 | |
1765 kcpc_set_t * | |
1766 kcpc_dup_set(kcpc_set_t *set) | |
1767 { | |
1768 kcpc_set_t *new; | |
1769 int i; | |
1770 int j; | |
1771 | |
6275 | 1772 new = kmem_zalloc(sizeof (*new), KM_SLEEP); |
1773 new->ks_state &= ~KCPC_SET_BOUND; | |
0 | 1774 new->ks_flags = set->ks_flags; |
1775 new->ks_nreqs = set->ks_nreqs; | |
1776 new->ks_req = kmem_alloc(set->ks_nreqs * sizeof (kcpc_request_t), | |
1777 KM_SLEEP); | |
1778 new->ks_data = NULL; | |
1779 new->ks_ctx = NULL; | |
1780 | |
1781 for (i = 0; i < new->ks_nreqs; i++) { | |
1782 new->ks_req[i].kr_config = NULL; | |
1783 new->ks_req[i].kr_index = set->ks_req[i].kr_index; | |
1784 new->ks_req[i].kr_picnum = set->ks_req[i].kr_picnum; | |
1785 new->ks_req[i].kr_picp = NULL; | |
1786 new->ks_req[i].kr_data = NULL; | |
1787 (void) strncpy(new->ks_req[i].kr_event, set->ks_req[i].kr_event, | |
1788 CPC_MAX_EVENT_LEN); | |
1789 new->ks_req[i].kr_preset = set->ks_req[i].kr_preset; | |
1790 new->ks_req[i].kr_flags = set->ks_req[i].kr_flags; | |
1791 new->ks_req[i].kr_nattrs = set->ks_req[i].kr_nattrs; | |
1792 new->ks_req[i].kr_attr = kmem_alloc(new->ks_req[i].kr_nattrs * | |
1793 sizeof (kcpc_attr_t), KM_SLEEP); | |
1794 for (j = 0; j < new->ks_req[i].kr_nattrs; j++) { | |
1795 new->ks_req[i].kr_attr[j].ka_val = | |
1796 set->ks_req[i].kr_attr[j].ka_val; | |
1797 (void) strncpy(new->ks_req[i].kr_attr[j].ka_name, | |
1798 set->ks_req[i].kr_attr[j].ka_name, | |
1799 CPC_MAX_ATTR_LEN); | |
1800 } | |
1801 } | |
1802 | |
1803 return (new); | |
1804 } | |
1805 | |
1806 int | |
1807 kcpc_allow_nonpriv(void *token) | |
1808 { | |
1809 return (((kcpc_ctx_t *)token)->kc_flags & KCPC_CTX_NONPRIV); | |
1810 } | |
1811 | |
1812 void | |
1813 kcpc_invalidate(kthread_t *t) | |
1814 { | |
1815 kcpc_ctx_t *ctx = t->t_cpc_ctx; | |
1816 | |
1817 if (ctx != NULL) | |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1818 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_INVALID); |
0 | 1819 } |
1820 | |
1821 /* | |
1822 * Given a PCBE ID, attempt to load a matching PCBE module. The strings given | |
1823 * are used to construct PCBE names, starting with the most specific, | |
1824 * "pcbe.first.second.third.fourth" and ending with the least specific, | |
1825 * "pcbe.first". | |
1826 * | |
1827 * Returns 0 if a PCBE was successfully loaded and -1 upon error. | |
1828 */ | |
1829 int | |
1830 kcpc_pcbe_tryload(const char *prefix, uint_t first, uint_t second, uint_t third) | |
1831 { | |
1414
b4126407ac5b
PSARC 2006/020 FMA for Athlon 64 and Opteron Processors
cindi
parents:
0
diff
changeset
|
1832 uint_t s[3]; |
0 | 1833 |
1414
b4126407ac5b
PSARC 2006/020 FMA for Athlon 64 and Opteron Processors
cindi
parents:
0
diff
changeset
|
1834 s[0] = first; |
b4126407ac5b
PSARC 2006/020 FMA for Athlon 64 and Opteron Processors
cindi
parents:
0
diff
changeset
|
1835 s[1] = second; |
b4126407ac5b
PSARC 2006/020 FMA for Athlon 64 and Opteron Processors
cindi
parents:
0
diff
changeset
|
1836 s[2] = third; |
0 | 1837 |
1414
b4126407ac5b
PSARC 2006/020 FMA for Athlon 64 and Opteron Processors
cindi
parents:
0
diff
changeset
|
1838 return (modload_qualified("pcbe", |
5254
38162db71c7d
PSARC 2007/591 Generic x86 Machine Check Architecture
gavinm
parents:
3884
diff
changeset
|
1839 "pcbe", prefix, ".", s, 3, NULL) < 0 ? -1 : 0); |
0 | 1840 } |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
1841 |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1842 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1843 * Create one or more CPC context for given CPU with specified counter event |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1844 * requests |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1845 * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1846 * If number of requested counter events is less than or equal number of |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1847 * hardware counters on a CPU and can all be assigned to the counters on a CPU |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1848 * at the same time, then make one CPC context. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1849 * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1850 * Otherwise, multiple CPC contexts are created to allow multiplexing more |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1851 * counter events than existing counters onto the counters by iterating through |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1852 * all of the CPC contexts, programming the counters with each CPC context one |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1853 * at a time and measuring the resulting counter values. Each of the resulting |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1854 * CPC contexts contains some number of requested counter events less than or |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1855 * equal the number of counters on a CPU depending on whether all the counter |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1856 * events can be programmed on all the counters at the same time or not. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1857 * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1858 * Flags to kmem_{,z}alloc() are passed in as an argument to allow specifying |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1859 * whether memory allocation should be non-blocking or not. The code will try |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1860 * to allocate *whole* CPC contexts if possible. If there is any memory |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1861 * allocation failure during the allocations needed for a given CPC context, it |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1862 * will skip allocating that CPC context because it cannot allocate the whole |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1863 * thing. Thus, the only time that it will end up allocating none (ie. no CPC |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1864 * contexts whatsoever) is when it cannot even allocate *one* whole CPC context |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1865 * without a memory allocation failure occurring. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1866 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1867 int |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1868 kcpc_cpu_ctx_create(cpu_t *cp, kcpc_request_list_t *req_list, int kmem_flags, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1869 kcpc_ctx_t ***ctx_ptr_array, size_t *ctx_ptr_array_sz) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1870 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1871 kcpc_ctx_t **ctx_ptrs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1872 int nctx; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1873 int nctx_ptrs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1874 int nreqs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1875 kcpc_request_t *reqs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1876 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1877 if (cp == NULL || ctx_ptr_array == NULL || ctx_ptr_array_sz == NULL || |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1878 req_list == NULL || req_list->krl_cnt < 1) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1879 return (-1); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1880 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1881 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1882 * Allocate number of sets assuming that each set contains one and only |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1883 * one counter event request for each counter on a CPU |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1884 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1885 nreqs = req_list->krl_cnt; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1886 nctx_ptrs = (nreqs + cpc_ncounters - 1) / cpc_ncounters; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1887 ctx_ptrs = kmem_zalloc(nctx_ptrs * sizeof (kcpc_ctx_t *), kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1888 if (ctx_ptrs == NULL) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1889 return (-2); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1890 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1891 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1892 * Fill in sets of requests |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1893 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1894 nctx = 0; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1895 reqs = req_list->krl_list; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1896 while (nreqs > 0) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1897 kcpc_ctx_t *ctx; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1898 kcpc_set_t *set; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1899 int subcode; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1900 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1901 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1902 * Allocate CPC context and set for requested counter events |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1903 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1904 ctx = kcpc_ctx_alloc(kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1905 set = kcpc_set_create(reqs, nreqs, 0, kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1906 if (set == NULL) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1907 kcpc_ctx_free(ctx); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1908 break; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1909 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1910 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1911 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1912 * Determine assignment of requested counter events to specific |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1913 * counters |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1914 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1915 if (kcpc_assign_reqs(set, ctx) != 0) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1916 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1917 * May not be able to assign requested counter events |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1918 * to all counters since all counters may not be able |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1919 * to do all events, so only do one counter event in |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1920 * set of counter requests when this happens since at |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1921 * least one of the counters must be able to do the |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1922 * event. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1923 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1924 kcpc_free_set(set); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1925 set = kcpc_set_create(reqs, 1, 0, kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1926 if (set == NULL) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1927 kcpc_ctx_free(ctx); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1928 break; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1929 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1930 if (kcpc_assign_reqs(set, ctx) != 0) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1931 #ifdef DEBUG |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1932 cmn_err(CE_NOTE, "!kcpc_cpu_ctx_create: can't " |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1933 "assign counter event %s!\n", |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1934 set->ks_req->kr_event); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1935 #endif |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1936 kcpc_free_set(set); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1937 kcpc_ctx_free(ctx); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1938 reqs++; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1939 nreqs--; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1940 continue; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1941 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1942 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1943 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1944 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1945 * Allocate memory needed to hold requested counter event data |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1946 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1947 set->ks_data = kmem_zalloc(set->ks_nreqs * sizeof (uint64_t), |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1948 kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1949 if (set->ks_data == NULL) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1950 kcpc_free_set(set); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1951 kcpc_ctx_free(ctx); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1952 break; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1953 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1954 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1955 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1956 * Configure requested counter events |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1957 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1958 if (kcpc_configure_reqs(ctx, set, &subcode) != 0) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1959 #ifdef DEBUG |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1960 cmn_err(CE_NOTE, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1961 "!kcpc_cpu_ctx_create: can't configure " |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1962 "set of counter event requests!\n"); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1963 #endif |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1964 reqs += set->ks_nreqs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1965 nreqs -= set->ks_nreqs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1966 kmem_free(set->ks_data, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1967 set->ks_nreqs * sizeof (uint64_t)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1968 kcpc_free_set(set); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1969 kcpc_ctx_free(ctx); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1970 continue; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1971 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1972 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1973 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1974 * Point set of counter event requests at this context and fill |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1975 * in CPC context |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1976 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1977 set->ks_ctx = ctx; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1978 ctx->kc_set = set; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1979 ctx->kc_cpuid = cp->cpu_id; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1980 ctx->kc_thread = curthread; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1981 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1982 ctx_ptrs[nctx] = ctx; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1983 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1984 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1985 * Update requests and how many are left to be assigned to sets |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1986 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1987 reqs += set->ks_nreqs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1988 nreqs -= set->ks_nreqs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1989 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1990 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1991 * Increment number of CPC contexts and allocate bigger array |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1992 * for context pointers as needed |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1993 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1994 nctx++; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1995 if (nctx >= nctx_ptrs) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1996 kcpc_ctx_t **new; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1997 int new_cnt; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1998 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
1999 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2000 * Allocate more CPC contexts based on how many |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2001 * contexts allocated so far and how many counter |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2002 * requests left to assign |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2003 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2004 new_cnt = nctx_ptrs + |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2005 ((nreqs + cpc_ncounters - 1) / cpc_ncounters); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2006 new = kmem_zalloc(new_cnt * sizeof (kcpc_ctx_t *), |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2007 kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2008 if (new == NULL) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2009 break; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2010 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2011 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2012 * Copy contents of old sets into new ones |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2013 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2014 bcopy(ctx_ptrs, new, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2015 nctx_ptrs * sizeof (kcpc_ctx_t *)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2016 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2017 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2018 * Free old array of context pointers and use newly |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2019 * allocated one instead now |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2020 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2021 kmem_free(ctx_ptrs, nctx_ptrs * sizeof (kcpc_ctx_t *)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2022 ctx_ptrs = new; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2023 nctx_ptrs = new_cnt; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2024 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2025 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2026 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2027 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2028 * Return NULL if no CPC contexts filled in |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2029 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2030 if (nctx == 0) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2031 kmem_free(ctx_ptrs, nctx_ptrs * sizeof (kcpc_ctx_t *)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2032 *ctx_ptr_array = NULL; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2033 *ctx_ptr_array_sz = 0; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2034 return (-2); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2035 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2036 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2037 *ctx_ptr_array = ctx_ptrs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2038 *ctx_ptr_array_sz = nctx_ptrs * sizeof (kcpc_ctx_t *); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2039 return (nctx); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2040 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2041 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2042 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2043 * Return whether PCBE supports given counter event |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2044 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2045 boolean_t |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2046 kcpc_event_supported(char *event) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2047 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2048 if (pcbe_ops == NULL || pcbe_ops->pcbe_event_coverage(event) == 0) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2049 return (B_FALSE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2050 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2051 return (B_TRUE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2052 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2053 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2054 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2055 * Program counters on current CPU with given CPC context |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2056 * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2057 * If kernel is interposing on counters to measure hardware capacity and |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2058 * utilization, then unprogram counters for kernel *before* programming them |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2059 * with specified CPC context. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2060 * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2061 * kcpc_{program,unprogram}() may be called either directly by a thread running |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2062 * on the target CPU or from a cross-call from another CPU. To protect |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2063 * programming and unprogramming from being interrupted by cross-calls, callers |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2064 * who execute kcpc_{program,unprogram} should raise PIL to the level used by |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2065 * cross-calls. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2066 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2067 void |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2068 kcpc_program(kcpc_ctx_t *ctx, boolean_t for_thread, boolean_t cu_interpose) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2069 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2070 int error; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2071 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2072 ASSERT(IS_HIPIL()); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2073 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2074 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2075 * CPC context shouldn't be NULL, its CPU field should specify current |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2076 * CPU or be -1 to specify any CPU when the context is bound to a |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2077 * thread, and preemption should be disabled |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2078 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2079 ASSERT(ctx != NULL && (ctx->kc_cpuid == CPU->cpu_id || |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2080 ctx->kc_cpuid == -1) && curthread->t_preempt > 0); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2081 if (ctx == NULL || (ctx->kc_cpuid != CPU->cpu_id && |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2082 ctx->kc_cpuid != -1) || curthread->t_preempt < 1) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2083 return; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2084 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2085 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2086 * Unprogram counters for kernel measuring hardware capacity and |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2087 * utilization |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2088 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2089 if (cu_interpose == B_TRUE) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2090 cu_cpc_unprogram(CPU, &error); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2091 } else { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2092 kcpc_set_t *set = ctx->kc_set; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2093 int i; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2094 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2095 ASSERT(set != NULL); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2096 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2097 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2098 * Since cu_interpose is false, we are programming CU context. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2099 * In general, PCBE can continue from the state saved in the |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2100 * set, but it is not very reliable, so we start again from the |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2101 * preset value. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2102 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2103 for (i = 0; i < set->ks_nreqs; i++) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2104 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2105 * Reset the virtual counter value to the preset value. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2106 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2107 *(set->ks_req[i].kr_data) = set->ks_req[i].kr_preset; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2108 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2109 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2110 * Reset PCBE to the preset value. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2111 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2112 pcbe_ops->pcbe_configure(0, NULL, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2113 set->ks_req[i].kr_preset, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2114 0, 0, NULL, &set->ks_req[i].kr_config, NULL); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2115 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2116 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2117 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2118 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2119 * Program counters with specified CPC context |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2120 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2121 ctx->kc_rawtick = KCPC_GET_TICK(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2122 pcbe_ops->pcbe_program(ctx); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2123 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2124 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2125 * Denote that counters programmed for thread or CPU CPC context |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2126 * differently |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2127 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2128 if (for_thread == B_TRUE) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2129 KCPC_CTX_FLAG_CLR(ctx, KCPC_CTX_FREEZE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2130 else |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2131 CPU->cpu_cpc_ctx = ctx; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2132 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2133 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2134 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2135 * Unprogram counters with given CPC context on current CPU |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2136 * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2137 * If kernel is interposing on counters to measure hardware capacity and |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2138 * utilization, then program counters for the kernel capacity and utilization |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2139 * *after* unprogramming them for given CPC context. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2140 * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2141 * See the comment for kcpc_program regarding the synchronization with |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2142 * cross-calls. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2143 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2144 void |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2145 kcpc_unprogram(kcpc_ctx_t *ctx, boolean_t cu_interpose) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2146 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2147 int error; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2148 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2149 ASSERT(IS_HIPIL()); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2150 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2151 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2152 * CPC context shouldn't be NULL, its CPU field should specify current |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2153 * CPU or be -1 to specify any CPU when the context is bound to a |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2154 * thread, and preemption should be disabled |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2155 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2156 ASSERT(ctx != NULL && (ctx->kc_cpuid == CPU->cpu_id || |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2157 ctx->kc_cpuid == -1) && curthread->t_preempt > 0); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2158 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2159 if (ctx == NULL || (ctx->kc_cpuid != CPU->cpu_id && |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2160 ctx->kc_cpuid != -1) || curthread->t_preempt < 1 || |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2161 (ctx->kc_flags & KCPC_CTX_INVALID_STOPPED) != 0) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2162 return; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2163 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2164 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2165 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2166 * Specified CPC context to be unprogrammed should be bound to current |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2167 * CPU or thread |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2168 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2169 ASSERT(CPU->cpu_cpc_ctx == ctx || curthread->t_cpc_ctx == ctx); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2170 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2171 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2172 * Stop counters |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2173 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2174 pcbe_ops->pcbe_allstop(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2175 KCPC_CTX_FLAG_SET(ctx, KCPC_CTX_INVALID_STOPPED); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2176 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2177 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2178 * Allow kernel to interpose on counters and program them for its own |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2179 * use to measure hardware capacity and utilization if cu_interpose |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2180 * argument is true |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2181 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2182 if (cu_interpose == B_TRUE) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2183 cu_cpc_program(CPU, &error); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2184 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2185 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2186 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2187 * Read CPU Performance Counter (CPC) on current CPU and call specified update |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2188 * routine with data for each counter event currently programmed on CPU |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2189 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2190 int |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2191 kcpc_read(kcpc_update_func_t update_func) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2192 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2193 kcpc_ctx_t *ctx; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2194 int i; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2195 kcpc_request_t *req; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2196 int retval; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2197 kcpc_set_t *set; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2198 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2199 ASSERT(IS_HIPIL()); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2200 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2201 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2202 * Can't grab locks or block because may be called inside dispatcher |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2203 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2204 kpreempt_disable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2205 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2206 ctx = CPU->cpu_cpc_ctx; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2207 if (ctx == NULL) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2208 kpreempt_enable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2209 return (0); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2210 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2211 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2212 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2213 * Read counter data from current CPU |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2214 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2215 pcbe_ops->pcbe_sample(ctx); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2216 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2217 set = ctx->kc_set; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2218 if (set == NULL || set->ks_req == NULL) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2219 kpreempt_enable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2220 return (0); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2221 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2222 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2223 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2224 * Call update function with preset pointer and data for each CPC event |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2225 * request currently programmed on current CPU |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2226 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2227 req = set->ks_req; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2228 retval = 0; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2229 for (i = 0; i < set->ks_nreqs; i++) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2230 int ret; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2231 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2232 if (req[i].kr_data == NULL) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2233 break; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2234 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2235 ret = update_func(req[i].kr_ptr, *req[i].kr_data); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2236 if (ret < 0) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2237 retval = ret; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2238 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2239 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2240 kpreempt_enable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2241 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2242 return (retval); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2243 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2244 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2245 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2246 * Initialize list of counter event requests |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2247 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2248 kcpc_request_list_t * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2249 kcpc_reqs_init(int nreqs, int kmem_flags) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2250 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2251 kcpc_request_list_t *req_list; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2252 kcpc_request_t *reqs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2253 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2254 if (nreqs < 1) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2255 return (NULL); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2256 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2257 req_list = kmem_zalloc(sizeof (kcpc_request_list_t), kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2258 if (req_list == NULL) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2259 return (NULL); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2260 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2261 reqs = kmem_zalloc(nreqs * sizeof (kcpc_request_t), kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2262 if (reqs == NULL) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2263 kmem_free(req_list, sizeof (kcpc_request_list_t)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2264 return (NULL); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2265 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2266 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2267 req_list->krl_list = reqs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2268 req_list->krl_cnt = 0; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2269 req_list->krl_max = nreqs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2270 return (req_list); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2271 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2272 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2273 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2274 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2275 * Add counter event request to given list of counter event requests |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2276 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2277 int |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2278 kcpc_reqs_add(kcpc_request_list_t *req_list, char *event, uint64_t preset, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2279 uint_t flags, uint_t nattrs, kcpc_attr_t *attr, void *ptr, int kmem_flags) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2280 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2281 kcpc_request_t *req; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2282 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2283 if (req_list == NULL || req_list->krl_list == NULL) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2284 return (-1); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2285 |
13082
87f89233b883
6964154 Missing unlock in set_all_zone_usr_proc_sys()
Ethindra Ramamurthy <Ethindra.Ramamurthy@Sun.COM>
parents:
11389
diff
changeset
|
2286 ASSERT(req_list->krl_max != 0); |
87f89233b883
6964154 Missing unlock in set_all_zone_usr_proc_sys()
Ethindra Ramamurthy <Ethindra.Ramamurthy@Sun.COM>
parents:
11389
diff
changeset
|
2287 |
11389
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2288 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2289 * Allocate more space (if needed) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2290 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2291 if (req_list->krl_cnt > req_list->krl_max) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2292 kcpc_request_t *new; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2293 kcpc_request_t *old; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2294 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2295 old = req_list->krl_list; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2296 new = kmem_zalloc((req_list->krl_max + |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2297 cpc_ncounters) * sizeof (kcpc_request_t), kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2298 if (new == NULL) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2299 return (-2); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2300 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2301 req_list->krl_list = new; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2302 bcopy(old, req_list->krl_list, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2303 req_list->krl_cnt * sizeof (kcpc_request_t)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2304 kmem_free(old, req_list->krl_max * sizeof (kcpc_request_t)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2305 req_list->krl_cnt = 0; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2306 req_list->krl_max += cpc_ncounters; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2307 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2308 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2309 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2310 * Fill in request as much as possible now, but some fields will need |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2311 * to be set when request is assigned to a set. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2312 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2313 req = &req_list->krl_list[req_list->krl_cnt]; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2314 req->kr_config = NULL; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2315 req->kr_picnum = -1; /* have CPC pick this */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2316 req->kr_index = -1; /* set when assigning request to set */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2317 req->kr_data = NULL; /* set when configuring request */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2318 (void) strcpy(req->kr_event, event); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2319 req->kr_preset = preset; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2320 req->kr_flags = flags; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2321 req->kr_nattrs = nattrs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2322 req->kr_attr = attr; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2323 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2324 * Keep pointer given by caller to give to update function when this |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2325 * counter event is sampled/read |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2326 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2327 req->kr_ptr = ptr; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2328 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2329 req_list->krl_cnt++; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2330 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2331 return (0); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2332 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2333 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2334 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2335 * Reset list of CPC event requests so its space can be used for another set |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2336 * of requests |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2337 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2338 int |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2339 kcpc_reqs_reset(kcpc_request_list_t *req_list) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2340 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2341 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2342 * Return when pointer to request list structure or request is NULL or |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2343 * when max requests is less than or equal to 0 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2344 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2345 if (req_list == NULL || req_list->krl_list == NULL || |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2346 req_list->krl_max <= 0) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2347 return (-1); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2348 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2349 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2350 * Zero out requests and number of requests used |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2351 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2352 bzero(req_list->krl_list, req_list->krl_max * sizeof (kcpc_request_t)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2353 req_list->krl_cnt = 0; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2354 return (0); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2355 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2356 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2357 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2358 * Free given list of counter event requests |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2359 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2360 int |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2361 kcpc_reqs_fini(kcpc_request_list_t *req_list) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2362 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2363 kmem_free(req_list->krl_list, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2364 req_list->krl_max * sizeof (kcpc_request_t)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2365 kmem_free(req_list, sizeof (kcpc_request_list_t)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2366 return (0); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2367 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2368 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2369 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2370 * Create set of given counter event requests |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2371 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2372 static kcpc_set_t * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2373 kcpc_set_create(kcpc_request_t *reqs, int nreqs, int set_flags, int kmem_flags) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2374 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2375 int i; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2376 kcpc_set_t *set; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2377 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2378 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2379 * Allocate set and assign number of requests in set and flags |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2380 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2381 set = kmem_zalloc(sizeof (kcpc_set_t), kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2382 if (set == NULL) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2383 return (NULL); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2384 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2385 if (nreqs < cpc_ncounters) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2386 set->ks_nreqs = nreqs; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2387 else |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2388 set->ks_nreqs = cpc_ncounters; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2389 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2390 set->ks_flags = set_flags; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2391 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2392 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2393 * Allocate requests needed, copy requests into set, and set index into |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2394 * data for each request (which may change when we assign requested |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2395 * counter events to counters) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2396 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2397 set->ks_req = (kcpc_request_t *)kmem_zalloc(sizeof (kcpc_request_t) * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2398 set->ks_nreqs, kmem_flags); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2399 if (set->ks_req == NULL) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2400 kmem_free(set, sizeof (kcpc_set_t)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2401 return (NULL); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2402 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2403 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2404 bcopy(reqs, set->ks_req, sizeof (kcpc_request_t) * set->ks_nreqs); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2405 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2406 for (i = 0; i < set->ks_nreqs; i++) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2407 set->ks_req[i].kr_index = i; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2408 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2409 return (set); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2410 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2411 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2412 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2413 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2414 * Stop counters on current CPU. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2415 * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2416 * If preserve_context is true, the caller is interested in the CPU's CPC |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2417 * context and wants it to be preserved. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2418 * |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2419 * If preserve_context is false, the caller does not need the CPU's CPC context |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2420 * to be preserved, so it is set to NULL. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2421 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2422 static void |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2423 kcpc_cpustop_func(boolean_t preserve_context) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2424 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2425 kpreempt_disable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2426 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2427 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2428 * Someone already stopped this context before us, so there is nothing |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2429 * to do. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2430 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2431 if (CPU->cpu_cpc_ctx == NULL) { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2432 kpreempt_enable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2433 return; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2434 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2435 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2436 kcpc_unprogram(CPU->cpu_cpc_ctx, B_TRUE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2437 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2438 * If CU does not use counters, then clear the CPU's CPC context |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2439 * If the caller requested to preserve context it should disable CU |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2440 * first, so there should be no CU context now. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2441 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2442 ASSERT(!preserve_context || !CU_CPC_ON(CPU)); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2443 if (!preserve_context && CPU->cpu_cpc_ctx != NULL && !CU_CPC_ON(CPU)) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2444 CPU->cpu_cpc_ctx = NULL; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2445 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2446 kpreempt_enable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2447 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2448 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2449 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2450 * Stop counters on given CPU and set its CPC context to NULL unless |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2451 * preserve_context is true. |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2452 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2453 void |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2454 kcpc_cpu_stop(cpu_t *cp, boolean_t preserve_context) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2455 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2456 cpu_call(cp, (cpu_call_func_t)kcpc_cpustop_func, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2457 preserve_context, 0); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2458 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2459 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2460 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2461 * Program the context on the current CPU |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2462 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2463 static void |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2464 kcpc_remoteprogram_func(kcpc_ctx_t *ctx, uintptr_t arg) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2465 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2466 boolean_t for_thread = (boolean_t)arg; |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2467 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2468 ASSERT(ctx != NULL); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2469 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2470 kpreempt_disable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2471 kcpc_program(ctx, for_thread, B_TRUE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2472 kpreempt_enable(); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2473 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2474 |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2475 /* |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2476 * Program counters on given CPU |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2477 */ |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2478 void |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2479 kcpc_cpu_program(cpu_t *cp, kcpc_ctx_t *ctx) |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2480 { |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2481 cpu_call(cp, (cpu_call_func_t)kcpc_remoteprogram_func, (uintptr_t)ctx, |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2482 (uintptr_t)B_FALSE); |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2483 } |
dd00b884e84f
6764832 Provide user-level processor groups observability
Alexander Kolbasov <Alexander.Kolbasov@Sun.COM>
parents:
8803
diff
changeset
|
2484 |
8803
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2485 char * |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2486 kcpc_list_attrs(void) |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2487 { |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2488 ASSERT(pcbe_ops != NULL); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2489 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2490 return (pcbe_ops->pcbe_list_attrs()); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2491 } |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2492 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2493 char * |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2494 kcpc_list_events(uint_t pic) |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2495 { |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2496 ASSERT(pcbe_ops != NULL); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2497 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2498 return (pcbe_ops->pcbe_list_events(pic)); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2499 } |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2500 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2501 uint_t |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2502 kcpc_pcbe_capabilities(void) |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2503 { |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2504 ASSERT(pcbe_ops != NULL); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2505 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2506 return (pcbe_ops->pcbe_caps); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2507 } |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2508 |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2509 int |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2510 kcpc_pcbe_loaded(void) |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2511 { |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2512 return (pcbe_ops == NULL ? -1 : 0); |
8c01b39012c9
PSARC 2008/480 DTrace CPC Provider
Jonathan Haslam <Jonathan.Haslam@Sun.COM>
parents:
7632
diff
changeset
|
2513 } |