1*1031c584SApple OSS Distributions /*
2*1031c584SApple OSS Distributions * Copyright (c) 2000-2021 Apple Inc. All rights reserved.
3*1031c584SApple OSS Distributions *
4*1031c584SApple OSS Distributions * @Apple_LICENSE_HEADER_START@
5*1031c584SApple OSS Distributions *
6*1031c584SApple OSS Distributions * The contents of this file constitute Original Code as defined in and
7*1031c584SApple OSS Distributions * are subject to the Apple Public Source License Version 1.1 (the
8*1031c584SApple OSS Distributions * "License"). You may not use this file except in compliance with the
9*1031c584SApple OSS Distributions * License. Please obtain a copy of the License at
10*1031c584SApple OSS Distributions * http://www.apple.com/publicsource and read it before using this file.
11*1031c584SApple OSS Distributions *
12*1031c584SApple OSS Distributions * This Original Code and all software distributed under the License are
13*1031c584SApple OSS Distributions * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14*1031c584SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15*1031c584SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16*1031c584SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17*1031c584SApple OSS Distributions * License for the specific language governing rights and limitations
18*1031c584SApple OSS Distributions * under the License.
19*1031c584SApple OSS Distributions *
20*1031c584SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
21*1031c584SApple OSS Distributions */
22*1031c584SApple OSS Distributions
23*1031c584SApple OSS Distributions #include <sys/kdebug_common.h>
24*1031c584SApple OSS Distributions
25*1031c584SApple OSS Distributions LCK_GRP_DECLARE(kdebug_lck_grp, "kdebug");
26*1031c584SApple OSS Distributions int kdbg_debug = 0;
27*1031c584SApple OSS Distributions
28*1031c584SApple OSS Distributions extern struct kd_control kd_control_trace, kd_control_triage;
29*1031c584SApple OSS Distributions
30*1031c584SApple OSS Distributions int
kdebug_storage_lock(struct kd_control * kd_ctrl_page)31*1031c584SApple OSS Distributions kdebug_storage_lock(struct kd_control *kd_ctrl_page)
32*1031c584SApple OSS Distributions {
33*1031c584SApple OSS Distributions int intrs_en = ml_set_interrupts_enabled(false);
34*1031c584SApple OSS Distributions lck_spin_lock_grp(&kd_ctrl_page->kdc_storage_lock, &kdebug_lck_grp);
35*1031c584SApple OSS Distributions return intrs_en;
36*1031c584SApple OSS Distributions }
37*1031c584SApple OSS Distributions
38*1031c584SApple OSS Distributions void
kdebug_storage_unlock(struct kd_control * kd_ctrl_page,int intrs_en)39*1031c584SApple OSS Distributions kdebug_storage_unlock(struct kd_control *kd_ctrl_page, int intrs_en)
40*1031c584SApple OSS Distributions {
41*1031c584SApple OSS Distributions lck_spin_unlock(&kd_ctrl_page->kdc_storage_lock);
42*1031c584SApple OSS Distributions ml_set_interrupts_enabled(intrs_en);
43*1031c584SApple OSS Distributions }
44*1031c584SApple OSS Distributions
45*1031c584SApple OSS Distributions // Turn on boot tracing and set the number of events.
46*1031c584SApple OSS Distributions static TUNABLE(unsigned int, new_nkdbufs, "trace", 0);
47*1031c584SApple OSS Distributions // Enable wrapping during boot tracing.
48*1031c584SApple OSS Distributions TUNABLE(unsigned int, trace_wrap, "trace_wrap", 0);
49*1031c584SApple OSS Distributions // The filter description to apply to boot tracing.
50*1031c584SApple OSS Distributions static TUNABLE_STR(trace_typefilter, 256, "trace_typefilter", "");
51*1031c584SApple OSS Distributions
52*1031c584SApple OSS Distributions // Turn on wake tracing and set the number of events.
53*1031c584SApple OSS Distributions TUNABLE(unsigned int, wake_nkdbufs, "trace_wake", 0);
54*1031c584SApple OSS Distributions // Write trace events to a file in the event of a panic.
55*1031c584SApple OSS Distributions TUNABLE(unsigned int, write_trace_on_panic, "trace_panic", 0);
56*1031c584SApple OSS Distributions
57*1031c584SApple OSS Distributions // Obsolete leak logging system.
58*1031c584SApple OSS Distributions TUNABLE(int, log_leaks, "-l", 0);
59*1031c584SApple OSS Distributions
60*1031c584SApple OSS Distributions void
kdebug_startup(void)61*1031c584SApple OSS Distributions kdebug_startup(void)
62*1031c584SApple OSS Distributions {
63*1031c584SApple OSS Distributions lck_spin_init(&kd_control_trace.kdc_storage_lock, &kdebug_lck_grp, LCK_ATTR_NULL);
64*1031c584SApple OSS Distributions lck_spin_init(&kd_control_triage.kdc_storage_lock, &kdebug_lck_grp, LCK_ATTR_NULL);
65*1031c584SApple OSS Distributions kdebug_init(new_nkdbufs, trace_typefilter,
66*1031c584SApple OSS Distributions (trace_wrap ? KDOPT_WRAPPING : 0) | KDOPT_ATBOOT);
67*1031c584SApple OSS Distributions create_buffers_triage();
68*1031c584SApple OSS Distributions }
69*1031c584SApple OSS Distributions
70*1031c584SApple OSS Distributions uint32_t
kdbg_cpu_count(void)71*1031c584SApple OSS Distributions kdbg_cpu_count(void)
72*1031c584SApple OSS Distributions {
73*1031c584SApple OSS Distributions #if defined(__x86_64__)
74*1031c584SApple OSS Distributions return ml_early_cpu_max_number() + 1;
75*1031c584SApple OSS Distributions #else // defined(__x86_64__)
76*1031c584SApple OSS Distributions return ml_get_cpu_count();
77*1031c584SApple OSS Distributions #endif // !defined(__x86_64__)
78*1031c584SApple OSS Distributions }
79*1031c584SApple OSS Distributions
80*1031c584SApple OSS Distributions /*
81*1031c584SApple OSS Distributions * Both kdebug_timestamp and kdebug_using_continuous_time are known
82*1031c584SApple OSS Distributions * to kexts. And going forward we always want to use mach_continuous_time().
83*1031c584SApple OSS Distributions * So we keep these 2 routines as-is to keep the TRACE mode use outside
84*1031c584SApple OSS Distributions * the kernel intact. TRIAGE mode will explicitly only use mach_continuous_time()
85*1031c584SApple OSS Distributions * for its timestamp.
86*1031c584SApple OSS Distributions */
87*1031c584SApple OSS Distributions bool
kdebug_using_continuous_time(void)88*1031c584SApple OSS Distributions kdebug_using_continuous_time(void)
89*1031c584SApple OSS Distributions {
90*1031c584SApple OSS Distributions return kd_control_trace.kdc_flags & KDBG_CONTINUOUS_TIME;
91*1031c584SApple OSS Distributions }
92*1031c584SApple OSS Distributions
93*1031c584SApple OSS Distributions uint64_t
kdebug_timestamp(void)94*1031c584SApple OSS Distributions kdebug_timestamp(void)
95*1031c584SApple OSS Distributions {
96*1031c584SApple OSS Distributions if (kdebug_using_continuous_time()) {
97*1031c584SApple OSS Distributions return mach_continuous_time();
98*1031c584SApple OSS Distributions } else {
99*1031c584SApple OSS Distributions return mach_absolute_time();
100*1031c584SApple OSS Distributions }
101*1031c584SApple OSS Distributions }
102*1031c584SApple OSS Distributions
103*1031c584SApple OSS Distributions int
create_buffers(struct kd_control * kd_ctrl_page,struct kd_buffer * kd_data_page,vm_tag_t tag)104*1031c584SApple OSS Distributions create_buffers(
105*1031c584SApple OSS Distributions struct kd_control *kd_ctrl_page,
106*1031c584SApple OSS Distributions struct kd_buffer *kd_data_page,
107*1031c584SApple OSS Distributions vm_tag_t tag)
108*1031c584SApple OSS Distributions {
109*1031c584SApple OSS Distributions unsigned int i;
110*1031c584SApple OSS Distributions unsigned int p_buffer_size;
111*1031c584SApple OSS Distributions unsigned int f_buffer_size;
112*1031c584SApple OSS Distributions unsigned int f_buffers;
113*1031c584SApple OSS Distributions int error = 0;
114*1031c584SApple OSS Distributions int ncpus, count_storage_units = 0;
115*1031c584SApple OSS Distributions
116*1031c584SApple OSS Distributions struct kd_bufinfo *kdbip = NULL;
117*1031c584SApple OSS Distributions struct kd_region *kd_bufs = NULL;
118*1031c584SApple OSS Distributions int kdb_storage_count = kd_data_page->kdb_storage_count;
119*1031c584SApple OSS Distributions
120*1031c584SApple OSS Distributions ncpus = kd_ctrl_page->alloc_cpus;
121*1031c584SApple OSS Distributions
122*1031c584SApple OSS Distributions kdbip = kalloc_type_tag(struct kd_bufinfo, ncpus, Z_WAITOK | Z_ZERO, tag);
123*1031c584SApple OSS Distributions if (kdbip == NULL) {
124*1031c584SApple OSS Distributions error = ENOSPC;
125*1031c584SApple OSS Distributions goto out;
126*1031c584SApple OSS Distributions }
127*1031c584SApple OSS Distributions kd_data_page->kdb_info = kdbip;
128*1031c584SApple OSS Distributions
129*1031c584SApple OSS Distributions f_buffers = kdb_storage_count / N_STORAGE_UNITS_PER_BUFFER;
130*1031c584SApple OSS Distributions kd_data_page->kdb_region_count = f_buffers;
131*1031c584SApple OSS Distributions
132*1031c584SApple OSS Distributions f_buffer_size = N_STORAGE_UNITS_PER_BUFFER * sizeof(struct kd_storage);
133*1031c584SApple OSS Distributions p_buffer_size = (kdb_storage_count % N_STORAGE_UNITS_PER_BUFFER) * sizeof(struct kd_storage);
134*1031c584SApple OSS Distributions
135*1031c584SApple OSS Distributions if (p_buffer_size) {
136*1031c584SApple OSS Distributions kd_data_page->kdb_region_count++;
137*1031c584SApple OSS Distributions }
138*1031c584SApple OSS Distributions
139*1031c584SApple OSS Distributions if (kd_data_page->kdcopybuf == 0) {
140*1031c584SApple OSS Distributions if (kmem_alloc(kernel_map, (vm_offset_t *)&kd_data_page->kdcopybuf,
141*1031c584SApple OSS Distributions (vm_size_t) kd_ctrl_page->kdebug_kdcopybuf_size,
142*1031c584SApple OSS Distributions KMA_DATA | KMA_ZERO, tag) != KERN_SUCCESS) {
143*1031c584SApple OSS Distributions error = ENOSPC;
144*1031c584SApple OSS Distributions goto out;
145*1031c584SApple OSS Distributions }
146*1031c584SApple OSS Distributions }
147*1031c584SApple OSS Distributions
148*1031c584SApple OSS Distributions kd_bufs = kalloc_type_tag(struct kd_region, kd_data_page->kdb_region_count,
149*1031c584SApple OSS Distributions Z_WAITOK | Z_ZERO, tag);
150*1031c584SApple OSS Distributions if (kd_bufs == NULL) {
151*1031c584SApple OSS Distributions error = ENOSPC;
152*1031c584SApple OSS Distributions goto out;
153*1031c584SApple OSS Distributions }
154*1031c584SApple OSS Distributions kd_data_page->kd_bufs = kd_bufs;
155*1031c584SApple OSS Distributions
156*1031c584SApple OSS Distributions for (i = 0; i < f_buffers; i++) {
157*1031c584SApple OSS Distributions if (kmem_alloc(kernel_map, (vm_offset_t *)&kd_bufs[i].kdr_addr,
158*1031c584SApple OSS Distributions (vm_size_t)f_buffer_size, KMA_DATA | KMA_ZERO, tag) != KERN_SUCCESS) {
159*1031c584SApple OSS Distributions error = ENOSPC;
160*1031c584SApple OSS Distributions goto out;
161*1031c584SApple OSS Distributions }
162*1031c584SApple OSS Distributions
163*1031c584SApple OSS Distributions kd_bufs[i].kdr_size = f_buffer_size;
164*1031c584SApple OSS Distributions }
165*1031c584SApple OSS Distributions if (p_buffer_size) {
166*1031c584SApple OSS Distributions if (kmem_alloc(kernel_map, (vm_offset_t *)&kd_bufs[i].kdr_addr,
167*1031c584SApple OSS Distributions (vm_size_t)p_buffer_size, KMA_DATA | KMA_ZERO, tag) != KERN_SUCCESS) {
168*1031c584SApple OSS Distributions error = ENOSPC;
169*1031c584SApple OSS Distributions goto out;
170*1031c584SApple OSS Distributions }
171*1031c584SApple OSS Distributions
172*1031c584SApple OSS Distributions kd_bufs[i].kdr_size = p_buffer_size;
173*1031c584SApple OSS Distributions }
174*1031c584SApple OSS Distributions
175*1031c584SApple OSS Distributions count_storage_units = 0;
176*1031c584SApple OSS Distributions for (i = 0; i < kd_data_page->kdb_region_count; i++) {
177*1031c584SApple OSS Distributions struct kd_storage *kds;
178*1031c584SApple OSS Distributions uint16_t n_elements;
179*1031c584SApple OSS Distributions static_assert(N_STORAGE_UNITS_PER_BUFFER <= UINT16_MAX);
180*1031c584SApple OSS Distributions assert(kd_bufs[i].kdr_size <= N_STORAGE_UNITS_PER_BUFFER *
181*1031c584SApple OSS Distributions sizeof(struct kd_storage));
182*1031c584SApple OSS Distributions
183*1031c584SApple OSS Distributions n_elements = kd_bufs[i].kdr_size / sizeof(struct kd_storage);
184*1031c584SApple OSS Distributions kds = kd_bufs[i].kdr_addr;
185*1031c584SApple OSS Distributions
186*1031c584SApple OSS Distributions for (uint16_t n = 0; n < n_elements; n++) {
187*1031c584SApple OSS Distributions kds[n].kds_next.buffer_index = kd_ctrl_page->kds_free_list.buffer_index;
188*1031c584SApple OSS Distributions kds[n].kds_next.offset = kd_ctrl_page->kds_free_list.offset;
189*1031c584SApple OSS Distributions
190*1031c584SApple OSS Distributions kd_ctrl_page->kds_free_list.buffer_index = i;
191*1031c584SApple OSS Distributions kd_ctrl_page->kds_free_list.offset = n;
192*1031c584SApple OSS Distributions }
193*1031c584SApple OSS Distributions count_storage_units += n_elements;
194*1031c584SApple OSS Distributions }
195*1031c584SApple OSS Distributions
196*1031c584SApple OSS Distributions kd_data_page->kdb_storage_count = count_storage_units;
197*1031c584SApple OSS Distributions
198*1031c584SApple OSS Distributions for (i = 0; i < ncpus; i++) {
199*1031c584SApple OSS Distributions kdbip[i].kd_list_head.raw = KDS_PTR_NULL;
200*1031c584SApple OSS Distributions kdbip[i].kd_list_tail.raw = KDS_PTR_NULL;
201*1031c584SApple OSS Distributions kdbip[i].kd_lostevents = false;
202*1031c584SApple OSS Distributions kdbip[i].num_bufs = 0;
203*1031c584SApple OSS Distributions }
204*1031c584SApple OSS Distributions
205*1031c584SApple OSS Distributions kd_ctrl_page->kdc_flags |= KDBG_BUFINIT;
206*1031c584SApple OSS Distributions
207*1031c584SApple OSS Distributions kd_ctrl_page->kdc_storage_used = 0;
208*1031c584SApple OSS Distributions out:
209*1031c584SApple OSS Distributions if (error) {
210*1031c584SApple OSS Distributions delete_buffers(kd_ctrl_page, kd_data_page);
211*1031c584SApple OSS Distributions }
212*1031c584SApple OSS Distributions
213*1031c584SApple OSS Distributions return error;
214*1031c584SApple OSS Distributions }
215*1031c584SApple OSS Distributions
216*1031c584SApple OSS Distributions void
delete_buffers(struct kd_control * kd_ctrl_page,struct kd_buffer * kd_data_page)217*1031c584SApple OSS Distributions delete_buffers(struct kd_control *kd_ctrl_page,
218*1031c584SApple OSS Distributions struct kd_buffer *kd_data_page)
219*1031c584SApple OSS Distributions {
220*1031c584SApple OSS Distributions unsigned int i;
221*1031c584SApple OSS Distributions int kdb_region_count = kd_data_page->kdb_region_count;
222*1031c584SApple OSS Distributions
223*1031c584SApple OSS Distributions struct kd_bufinfo *kdbip = kd_data_page->kdb_info;
224*1031c584SApple OSS Distributions struct kd_region *kd_bufs = kd_data_page->kd_bufs;
225*1031c584SApple OSS Distributions
226*1031c584SApple OSS Distributions if (kd_bufs) {
227*1031c584SApple OSS Distributions for (i = 0; i < kdb_region_count; i++) {
228*1031c584SApple OSS Distributions if (kd_bufs[i].kdr_addr) {
229*1031c584SApple OSS Distributions kmem_free(kernel_map, (vm_offset_t)kd_bufs[i].kdr_addr, (vm_size_t)kd_bufs[i].kdr_size);
230*1031c584SApple OSS Distributions }
231*1031c584SApple OSS Distributions }
232*1031c584SApple OSS Distributions kfree_type(struct kd_region, kdb_region_count, kd_bufs);
233*1031c584SApple OSS Distributions
234*1031c584SApple OSS Distributions kd_data_page->kd_bufs = NULL;
235*1031c584SApple OSS Distributions kd_data_page->kdb_region_count = 0;
236*1031c584SApple OSS Distributions }
237*1031c584SApple OSS Distributions if (kd_data_page->kdcopybuf) {
238*1031c584SApple OSS Distributions kmem_free(kernel_map, (vm_offset_t)kd_data_page->kdcopybuf, kd_ctrl_page->kdebug_kdcopybuf_size);
239*1031c584SApple OSS Distributions
240*1031c584SApple OSS Distributions kd_data_page->kdcopybuf = NULL;
241*1031c584SApple OSS Distributions }
242*1031c584SApple OSS Distributions kd_ctrl_page->kds_free_list.raw = KDS_PTR_NULL;
243*1031c584SApple OSS Distributions
244*1031c584SApple OSS Distributions if (kdbip) {
245*1031c584SApple OSS Distributions kfree_type(struct kd_bufinfo, kd_ctrl_page->alloc_cpus, kdbip);
246*1031c584SApple OSS Distributions kd_data_page->kdb_info = NULL;
247*1031c584SApple OSS Distributions }
248*1031c584SApple OSS Distributions kd_ctrl_page->kdc_coprocs = NULL;
249*1031c584SApple OSS Distributions kd_ctrl_page->kdebug_cpus = 0;
250*1031c584SApple OSS Distributions kd_ctrl_page->alloc_cpus = 0;
251*1031c584SApple OSS Distributions kd_ctrl_page->kdc_flags &= ~KDBG_BUFINIT;
252*1031c584SApple OSS Distributions }
253*1031c584SApple OSS Distributions
254*1031c584SApple OSS Distributions static bool
allocate_storage_unit(struct kd_control * kd_ctrl_page,struct kd_buffer * kd_data_page,int cpu)255*1031c584SApple OSS Distributions allocate_storage_unit(struct kd_control *kd_ctrl_page,
256*1031c584SApple OSS Distributions struct kd_buffer *kd_data_page, int cpu)
257*1031c584SApple OSS Distributions {
258*1031c584SApple OSS Distributions union kds_ptr kdsp;
259*1031c584SApple OSS Distributions struct kd_storage *kdsp_actual, *kdsp_next_actual;
260*1031c584SApple OSS Distributions struct kd_bufinfo *kdbip, *kdbp, *kdbp_vict, *kdbp_try;
261*1031c584SApple OSS Distributions uint64_t oldest_ts, ts;
262*1031c584SApple OSS Distributions bool retval = true;
263*1031c584SApple OSS Distributions struct kd_region *kd_bufs;
264*1031c584SApple OSS Distributions
265*1031c584SApple OSS Distributions int intrs_en = kdebug_storage_lock(kd_ctrl_page);
266*1031c584SApple OSS Distributions
267*1031c584SApple OSS Distributions kdbp = &kd_data_page->kdb_info[cpu];
268*1031c584SApple OSS Distributions kd_bufs = kd_data_page->kd_bufs;
269*1031c584SApple OSS Distributions kdbip = kd_data_page->kdb_info;
270*1031c584SApple OSS Distributions
271*1031c584SApple OSS Distributions /* If someone beat us to the allocate, return success */
272*1031c584SApple OSS Distributions if (kdbp->kd_list_tail.raw != KDS_PTR_NULL) {
273*1031c584SApple OSS Distributions kdsp_actual = POINTER_FROM_KDS_PTR(kd_bufs, kdbp->kd_list_tail);
274*1031c584SApple OSS Distributions
275*1031c584SApple OSS Distributions if (kdsp_actual->kds_bufindx < kd_ctrl_page->kdebug_events_per_storage_unit) {
276*1031c584SApple OSS Distributions goto out;
277*1031c584SApple OSS Distributions }
278*1031c584SApple OSS Distributions }
279*1031c584SApple OSS Distributions
280*1031c584SApple OSS Distributions if ((kdsp = kd_ctrl_page->kds_free_list).raw != KDS_PTR_NULL) {
281*1031c584SApple OSS Distributions /*
282*1031c584SApple OSS Distributions * If there's a free page, grab it from the free list.
283*1031c584SApple OSS Distributions */
284*1031c584SApple OSS Distributions kdsp_actual = POINTER_FROM_KDS_PTR(kd_bufs, kdsp);
285*1031c584SApple OSS Distributions kd_ctrl_page->kds_free_list = kdsp_actual->kds_next;
286*1031c584SApple OSS Distributions
287*1031c584SApple OSS Distributions kd_ctrl_page->kdc_storage_used++;
288*1031c584SApple OSS Distributions } else {
289*1031c584SApple OSS Distributions /*
290*1031c584SApple OSS Distributions * Otherwise, we're going to lose events and repurpose the oldest
291*1031c584SApple OSS Distributions * storage unit we can find.
292*1031c584SApple OSS Distributions */
293*1031c584SApple OSS Distributions if (kd_ctrl_page->kdc_live_flags & KDBG_NOWRAP) {
294*1031c584SApple OSS Distributions kd_ctrl_page->kdc_emit = KDEMIT_DISABLE;
295*1031c584SApple OSS Distributions kd_ctrl_page->kdc_live_flags |= KDBG_WRAPPED;
296*1031c584SApple OSS Distributions kdebug_enable = 0;
297*1031c584SApple OSS Distributions kd_ctrl_page->enabled = 0;
298*1031c584SApple OSS Distributions commpage_update_kdebug_state();
299*1031c584SApple OSS Distributions kdbp->kd_lostevents = true;
300*1031c584SApple OSS Distributions retval = false;
301*1031c584SApple OSS Distributions goto out;
302*1031c584SApple OSS Distributions }
303*1031c584SApple OSS Distributions kdbp_vict = NULL;
304*1031c584SApple OSS Distributions oldest_ts = UINT64_MAX;
305*1031c584SApple OSS Distributions
306*1031c584SApple OSS Distributions for (kdbp_try = &kdbip[0]; kdbp_try < &kdbip[kd_ctrl_page->kdebug_cpus]; kdbp_try++) {
307*1031c584SApple OSS Distributions if (kdbp_try->kd_list_head.raw == KDS_PTR_NULL) {
308*1031c584SApple OSS Distributions /*
309*1031c584SApple OSS Distributions * no storage unit to steal
310*1031c584SApple OSS Distributions */
311*1031c584SApple OSS Distributions continue;
312*1031c584SApple OSS Distributions }
313*1031c584SApple OSS Distributions
314*1031c584SApple OSS Distributions kdsp_actual = POINTER_FROM_KDS_PTR(kd_bufs, kdbp_try->kd_list_head);
315*1031c584SApple OSS Distributions
316*1031c584SApple OSS Distributions if (kdsp_actual->kds_bufcnt < kd_ctrl_page->kdebug_events_per_storage_unit) {
317*1031c584SApple OSS Distributions /*
318*1031c584SApple OSS Distributions * make sure we don't steal the storage unit
319*1031c584SApple OSS Distributions * being actively recorded to... need to
320*1031c584SApple OSS Distributions * move on because we don't want an out-of-order
321*1031c584SApple OSS Distributions * set of events showing up later
322*1031c584SApple OSS Distributions */
323*1031c584SApple OSS Distributions continue;
324*1031c584SApple OSS Distributions }
325*1031c584SApple OSS Distributions
326*1031c584SApple OSS Distributions /*
327*1031c584SApple OSS Distributions * When wrapping, steal the storage unit with the
328*1031c584SApple OSS Distributions * earliest timestamp on its last event, instead of the
329*1031c584SApple OSS Distributions * earliest timestamp on the first event. This allows a
330*1031c584SApple OSS Distributions * storage unit with more recent events to be preserved,
331*1031c584SApple OSS Distributions * even if the storage unit contains events that are
332*1031c584SApple OSS Distributions * older than those found in other CPUs.
333*1031c584SApple OSS Distributions */
334*1031c584SApple OSS Distributions ts = kdbg_get_timestamp(&kdsp_actual->kds_records[kd_ctrl_page->kdebug_events_per_storage_unit - 1]);
335*1031c584SApple OSS Distributions if (ts < oldest_ts) {
336*1031c584SApple OSS Distributions oldest_ts = ts;
337*1031c584SApple OSS Distributions kdbp_vict = kdbp_try;
338*1031c584SApple OSS Distributions }
339*1031c584SApple OSS Distributions }
340*1031c584SApple OSS Distributions if (kdbp_vict == NULL && kd_ctrl_page->mode == KDEBUG_MODE_TRACE) {
341*1031c584SApple OSS Distributions kd_ctrl_page->kdc_emit = KDEMIT_DISABLE;
342*1031c584SApple OSS Distributions kdebug_enable = 0;
343*1031c584SApple OSS Distributions kd_ctrl_page->enabled = 0;
344*1031c584SApple OSS Distributions commpage_update_kdebug_state();
345*1031c584SApple OSS Distributions retval = false;
346*1031c584SApple OSS Distributions goto out;
347*1031c584SApple OSS Distributions }
348*1031c584SApple OSS Distributions kdsp = kdbp_vict->kd_list_head;
349*1031c584SApple OSS Distributions kdsp_actual = POINTER_FROM_KDS_PTR(kd_bufs, kdsp);
350*1031c584SApple OSS Distributions kdbp_vict->kd_list_head = kdsp_actual->kds_next;
351*1031c584SApple OSS Distributions
352*1031c584SApple OSS Distributions if (kdbp_vict->kd_list_head.raw != KDS_PTR_NULL) {
353*1031c584SApple OSS Distributions kdsp_next_actual = POINTER_FROM_KDS_PTR(kd_bufs, kdbp_vict->kd_list_head);
354*1031c584SApple OSS Distributions kdsp_next_actual->kds_lostevents = true;
355*1031c584SApple OSS Distributions } else {
356*1031c584SApple OSS Distributions kdbp_vict->kd_lostevents = true;
357*1031c584SApple OSS Distributions }
358*1031c584SApple OSS Distributions
359*1031c584SApple OSS Distributions if (kd_ctrl_page->kdc_oldest_time < oldest_ts) {
360*1031c584SApple OSS Distributions kd_ctrl_page->kdc_oldest_time = oldest_ts;
361*1031c584SApple OSS Distributions }
362*1031c584SApple OSS Distributions kd_ctrl_page->kdc_live_flags |= KDBG_WRAPPED;
363*1031c584SApple OSS Distributions }
364*1031c584SApple OSS Distributions
365*1031c584SApple OSS Distributions if (kd_ctrl_page->mode == KDEBUG_MODE_TRACE) {
366*1031c584SApple OSS Distributions kdsp_actual->kds_timestamp = kdebug_timestamp();
367*1031c584SApple OSS Distributions } else {
368*1031c584SApple OSS Distributions kdsp_actual->kds_timestamp = mach_continuous_time();
369*1031c584SApple OSS Distributions }
370*1031c584SApple OSS Distributions
371*1031c584SApple OSS Distributions kdsp_actual->kds_next.raw = KDS_PTR_NULL;
372*1031c584SApple OSS Distributions kdsp_actual->kds_bufcnt = 0;
373*1031c584SApple OSS Distributions kdsp_actual->kds_readlast = 0;
374*1031c584SApple OSS Distributions
375*1031c584SApple OSS Distributions kdsp_actual->kds_lostevents = kdbp->kd_lostevents;
376*1031c584SApple OSS Distributions kdbp->kd_lostevents = false;
377*1031c584SApple OSS Distributions kdsp_actual->kds_bufindx = 0;
378*1031c584SApple OSS Distributions
379*1031c584SApple OSS Distributions if (kdbp->kd_list_head.raw == KDS_PTR_NULL) {
380*1031c584SApple OSS Distributions kdbp->kd_list_head = kdsp;
381*1031c584SApple OSS Distributions } else {
382*1031c584SApple OSS Distributions POINTER_FROM_KDS_PTR(kd_bufs, kdbp->kd_list_tail)->kds_next = kdsp;
383*1031c584SApple OSS Distributions }
384*1031c584SApple OSS Distributions kdbp->kd_list_tail = kdsp;
385*1031c584SApple OSS Distributions out:
386*1031c584SApple OSS Distributions kdebug_storage_unlock(kd_ctrl_page, intrs_en);
387*1031c584SApple OSS Distributions
388*1031c584SApple OSS Distributions return retval;
389*1031c584SApple OSS Distributions }
390*1031c584SApple OSS Distributions
391*1031c584SApple OSS Distributions static void
release_storage_unit(struct kd_control * kd_ctrl_page,struct kd_buffer * kd_data_page,int cpu,uint32_t kdsp_raw)392*1031c584SApple OSS Distributions release_storage_unit(struct kd_control *kd_ctrl_page, struct kd_buffer *kd_data_page, int cpu, uint32_t kdsp_raw)
393*1031c584SApple OSS Distributions {
394*1031c584SApple OSS Distributions struct kd_storage *kdsp_actual;
395*1031c584SApple OSS Distributions struct kd_bufinfo *kdbp;
396*1031c584SApple OSS Distributions union kds_ptr kdsp;
397*1031c584SApple OSS Distributions
398*1031c584SApple OSS Distributions kdbp = &kd_data_page->kdb_info[cpu];
399*1031c584SApple OSS Distributions
400*1031c584SApple OSS Distributions kdsp.raw = kdsp_raw;
401*1031c584SApple OSS Distributions
402*1031c584SApple OSS Distributions int intrs_en = kdebug_storage_lock(kd_ctrl_page);
403*1031c584SApple OSS Distributions
404*1031c584SApple OSS Distributions if (kdsp.raw == kdbp->kd_list_head.raw) {
405*1031c584SApple OSS Distributions /*
406*1031c584SApple OSS Distributions * it's possible for the storage unit pointed to
407*1031c584SApple OSS Distributions * by kdsp to have already been stolen... so
408*1031c584SApple OSS Distributions * check to see if it's still the head of the list
409*1031c584SApple OSS Distributions * now that we're behind the lock that protects
410*1031c584SApple OSS Distributions * adding and removing from the queue...
411*1031c584SApple OSS Distributions * since we only ever release and steal units from
412*1031c584SApple OSS Distributions * that position, if it's no longer the head
413*1031c584SApple OSS Distributions * we having nothing to do in this context
414*1031c584SApple OSS Distributions */
415*1031c584SApple OSS Distributions kdsp_actual = POINTER_FROM_KDS_PTR(kd_data_page->kd_bufs, kdsp);
416*1031c584SApple OSS Distributions kdbp->kd_list_head = kdsp_actual->kds_next;
417*1031c584SApple OSS Distributions
418*1031c584SApple OSS Distributions kdsp_actual->kds_next = kd_ctrl_page->kds_free_list;
419*1031c584SApple OSS Distributions kd_ctrl_page->kds_free_list = kdsp;
420*1031c584SApple OSS Distributions
421*1031c584SApple OSS Distributions kd_ctrl_page->kdc_storage_used--;
422*1031c584SApple OSS Distributions }
423*1031c584SApple OSS Distributions
424*1031c584SApple OSS Distributions kdebug_storage_unlock(kd_ctrl_page, intrs_en);
425*1031c584SApple OSS Distributions }
426*1031c584SApple OSS Distributions
427*1031c584SApple OSS Distributions bool
kdebug_disable_wrap(struct kd_control * ctl,kdebug_emit_filter_t * old_emit,kdebug_live_flags_t * old_live)428*1031c584SApple OSS Distributions kdebug_disable_wrap(struct kd_control *ctl,
429*1031c584SApple OSS Distributions kdebug_emit_filter_t *old_emit, kdebug_live_flags_t *old_live)
430*1031c584SApple OSS Distributions {
431*1031c584SApple OSS Distributions int intrs_en = kdebug_storage_lock(ctl);
432*1031c584SApple OSS Distributions
433*1031c584SApple OSS Distributions *old_emit = ctl->kdc_emit;
434*1031c584SApple OSS Distributions *old_live = ctl->kdc_live_flags;
435*1031c584SApple OSS Distributions
436*1031c584SApple OSS Distributions bool wrapped = ctl->kdc_live_flags & KDBG_WRAPPED;
437*1031c584SApple OSS Distributions ctl->kdc_live_flags &= ~KDBG_WRAPPED;
438*1031c584SApple OSS Distributions ctl->kdc_live_flags |= KDBG_NOWRAP;
439*1031c584SApple OSS Distributions
440*1031c584SApple OSS Distributions kdebug_storage_unlock(ctl, intrs_en);
441*1031c584SApple OSS Distributions
442*1031c584SApple OSS Distributions return wrapped;
443*1031c584SApple OSS Distributions }
444*1031c584SApple OSS Distributions
445*1031c584SApple OSS Distributions static void
_enable_wrap(struct kd_control * kd_ctrl_page,kdebug_emit_filter_t emit)446*1031c584SApple OSS Distributions _enable_wrap(struct kd_control *kd_ctrl_page, kdebug_emit_filter_t emit)
447*1031c584SApple OSS Distributions {
448*1031c584SApple OSS Distributions int intrs_en = kdebug_storage_lock(kd_ctrl_page);
449*1031c584SApple OSS Distributions kd_ctrl_page->kdc_live_flags &= ~KDBG_NOWRAP;
450*1031c584SApple OSS Distributions if (emit) {
451*1031c584SApple OSS Distributions kd_ctrl_page->kdc_emit = emit;
452*1031c584SApple OSS Distributions }
453*1031c584SApple OSS Distributions kdebug_storage_unlock(kd_ctrl_page, intrs_en);
454*1031c584SApple OSS Distributions }
455*1031c584SApple OSS Distributions
456*1031c584SApple OSS Distributions __attribute__((always_inline))
457*1031c584SApple OSS Distributions void
kernel_debug_write(struct kd_control * kd_ctrl_page,struct kd_buffer * kd_data_page,struct kd_record kd_rec)458*1031c584SApple OSS Distributions kernel_debug_write(struct kd_control *kd_ctrl_page,
459*1031c584SApple OSS Distributions struct kd_buffer *kd_data_page,
460*1031c584SApple OSS Distributions struct kd_record kd_rec)
461*1031c584SApple OSS Distributions {
462*1031c584SApple OSS Distributions uint64_t now = 0;
463*1031c584SApple OSS Distributions uint32_t bindx;
464*1031c584SApple OSS Distributions kd_buf *kd;
465*1031c584SApple OSS Distributions int cpu;
466*1031c584SApple OSS Distributions struct kd_bufinfo *kdbp;
467*1031c584SApple OSS Distributions struct kd_storage *kdsp_actual;
468*1031c584SApple OSS Distributions union kds_ptr kds_raw;
469*1031c584SApple OSS Distributions
470*1031c584SApple OSS Distributions disable_preemption();
471*1031c584SApple OSS Distributions
472*1031c584SApple OSS Distributions if (kd_ctrl_page->enabled == 0) {
473*1031c584SApple OSS Distributions goto out;
474*1031c584SApple OSS Distributions }
475*1031c584SApple OSS Distributions
476*1031c584SApple OSS Distributions if (kd_rec.cpu == -1) {
477*1031c584SApple OSS Distributions cpu = cpu_number();
478*1031c584SApple OSS Distributions } else {
479*1031c584SApple OSS Distributions cpu = kd_rec.cpu;
480*1031c584SApple OSS Distributions }
481*1031c584SApple OSS Distributions
482*1031c584SApple OSS Distributions kdbp = &kd_data_page->kdb_info[cpu];
483*1031c584SApple OSS Distributions
484*1031c584SApple OSS Distributions bool timestamp_is_continuous = kdbp->continuous_timestamps;
485*1031c584SApple OSS Distributions
486*1031c584SApple OSS Distributions if (kd_rec.timestamp != -1) {
487*1031c584SApple OSS Distributions if (kdebug_using_continuous_time()) {
488*1031c584SApple OSS Distributions if (!timestamp_is_continuous) {
489*1031c584SApple OSS Distributions kd_rec.timestamp = absolutetime_to_continuoustime(kd_rec.timestamp);
490*1031c584SApple OSS Distributions }
491*1031c584SApple OSS Distributions } else {
492*1031c584SApple OSS Distributions if (timestamp_is_continuous) {
493*1031c584SApple OSS Distributions kd_rec.timestamp = continuoustime_to_absolutetime(kd_rec.timestamp);
494*1031c584SApple OSS Distributions }
495*1031c584SApple OSS Distributions }
496*1031c584SApple OSS Distributions kd_rec.timestamp &= KDBG_TIMESTAMP_MASK;
497*1031c584SApple OSS Distributions if (kd_rec.timestamp < kd_ctrl_page->kdc_oldest_time) {
498*1031c584SApple OSS Distributions if (kdbp->latest_past_event_timestamp < kd_rec.timestamp) {
499*1031c584SApple OSS Distributions kdbp->latest_past_event_timestamp = kd_rec.timestamp;
500*1031c584SApple OSS Distributions }
501*1031c584SApple OSS Distributions goto out;
502*1031c584SApple OSS Distributions }
503*1031c584SApple OSS Distributions }
504*1031c584SApple OSS Distributions
505*1031c584SApple OSS Distributions retry_q:
506*1031c584SApple OSS Distributions kds_raw = kdbp->kd_list_tail;
507*1031c584SApple OSS Distributions
508*1031c584SApple OSS Distributions if (kds_raw.raw != KDS_PTR_NULL) {
509*1031c584SApple OSS Distributions kdsp_actual = POINTER_FROM_KDS_PTR(kd_data_page->kd_bufs, kds_raw);
510*1031c584SApple OSS Distributions bindx = kdsp_actual->kds_bufindx;
511*1031c584SApple OSS Distributions } else {
512*1031c584SApple OSS Distributions kdsp_actual = NULL;
513*1031c584SApple OSS Distributions bindx = kd_ctrl_page->kdebug_events_per_storage_unit;
514*1031c584SApple OSS Distributions }
515*1031c584SApple OSS Distributions
516*1031c584SApple OSS Distributions if (kdsp_actual == NULL || bindx >= kd_ctrl_page->kdebug_events_per_storage_unit) {
517*1031c584SApple OSS Distributions if (allocate_storage_unit(kd_ctrl_page, kd_data_page, cpu) == false) {
518*1031c584SApple OSS Distributions /*
519*1031c584SApple OSS Distributions * this can only happen if wrapping
520*1031c584SApple OSS Distributions * has been disabled
521*1031c584SApple OSS Distributions */
522*1031c584SApple OSS Distributions goto out;
523*1031c584SApple OSS Distributions }
524*1031c584SApple OSS Distributions goto retry_q;
525*1031c584SApple OSS Distributions }
526*1031c584SApple OSS Distributions
527*1031c584SApple OSS Distributions if (kd_rec.timestamp != -1) {
528*1031c584SApple OSS Distributions /*
529*1031c584SApple OSS Distributions * IOP entries can be allocated before xnu allocates and inits the buffer
530*1031c584SApple OSS Distributions * And, Intel uses a special 0 value as a early tracing timestamp sentinel
531*1031c584SApple OSS Distributions * to set the start of trace-time-start-of-interest.
532*1031c584SApple OSS Distributions */
533*1031c584SApple OSS Distributions if (kd_rec.timestamp < kdsp_actual->kds_timestamp) {
534*1031c584SApple OSS Distributions kdsp_actual->kds_timestamp = kd_rec.timestamp;
535*1031c584SApple OSS Distributions }
536*1031c584SApple OSS Distributions now = kd_rec.timestamp;
537*1031c584SApple OSS Distributions } else {
538*1031c584SApple OSS Distributions if (kd_ctrl_page->mode == KDEBUG_MODE_TRACE) {
539*1031c584SApple OSS Distributions now = kdebug_timestamp() & KDBG_TIMESTAMP_MASK;
540*1031c584SApple OSS Distributions } else {
541*1031c584SApple OSS Distributions now = mach_continuous_time() & KDBG_TIMESTAMP_MASK;
542*1031c584SApple OSS Distributions }
543*1031c584SApple OSS Distributions }
544*1031c584SApple OSS Distributions
545*1031c584SApple OSS Distributions if (!OSCompareAndSwap(bindx, bindx + 1, &kdsp_actual->kds_bufindx)) {
546*1031c584SApple OSS Distributions goto retry_q;
547*1031c584SApple OSS Distributions }
548*1031c584SApple OSS Distributions
549*1031c584SApple OSS Distributions kd = &kdsp_actual->kds_records[bindx];
550*1031c584SApple OSS Distributions
551*1031c584SApple OSS Distributions if (kd_ctrl_page->kdc_flags & KDBG_DEBUGID_64) {
552*1031c584SApple OSS Distributions /*DebugID has been passed in arg 4*/
553*1031c584SApple OSS Distributions kd->debugid = 0;
554*1031c584SApple OSS Distributions } else {
555*1031c584SApple OSS Distributions kd->debugid = kd_rec.debugid;
556*1031c584SApple OSS Distributions }
557*1031c584SApple OSS Distributions
558*1031c584SApple OSS Distributions kd->arg1 = kd_rec.arg1;
559*1031c584SApple OSS Distributions kd->arg2 = kd_rec.arg2;
560*1031c584SApple OSS Distributions kd->arg3 = kd_rec.arg3;
561*1031c584SApple OSS Distributions kd->arg4 = kd_rec.arg4;
562*1031c584SApple OSS Distributions kd->arg5 = kd_rec.arg5;
563*1031c584SApple OSS Distributions
564*1031c584SApple OSS Distributions kdbg_set_timestamp_and_cpu(kd, now, cpu);
565*1031c584SApple OSS Distributions
566*1031c584SApple OSS Distributions OSAddAtomic(1, &kdsp_actual->kds_bufcnt);
567*1031c584SApple OSS Distributions
568*1031c584SApple OSS Distributions out:
569*1031c584SApple OSS Distributions enable_preemption();
570*1031c584SApple OSS Distributions }
571*1031c584SApple OSS Distributions
572*1031c584SApple OSS Distributions // Read events from kdebug storage units into a user space buffer or file.
573*1031c584SApple OSS Distributions //
574*1031c584SApple OSS Distributions // This code runs while events are emitted -- storage unit allocation and
575*1031c584SApple OSS Distributions // deallocation wll synchronize with the emitters. Only one reader per control
576*1031c584SApple OSS Distributions // structure is allowed.
577*1031c584SApple OSS Distributions int
kernel_debug_read(struct kd_control * kd_ctrl_page,struct kd_buffer * kd_data_page,user_addr_t buffer,size_t * number,vnode_t vp,vfs_context_t ctx,uint32_t file_version)578*1031c584SApple OSS Distributions kernel_debug_read(struct kd_control *kd_ctrl_page,
579*1031c584SApple OSS Distributions struct kd_buffer *kd_data_page, user_addr_t buffer, size_t *number,
580*1031c584SApple OSS Distributions vnode_t vp, vfs_context_t ctx, uint32_t file_version)
581*1031c584SApple OSS Distributions {
582*1031c584SApple OSS Distributions size_t count;
583*1031c584SApple OSS Distributions unsigned int cpu, min_cpu;
584*1031c584SApple OSS Distributions uint64_t barrier_min = 0, barrier_max = 0, t, earliest_time;
585*1031c584SApple OSS Distributions int error = 0;
586*1031c584SApple OSS Distributions kd_buf *tempbuf;
587*1031c584SApple OSS Distributions uint32_t rcursor;
588*1031c584SApple OSS Distributions kd_buf lostevent;
589*1031c584SApple OSS Distributions union kds_ptr kdsp;
590*1031c584SApple OSS Distributions bool traced_retrograde = false;
591*1031c584SApple OSS Distributions struct kd_storage *kdsp_actual;
592*1031c584SApple OSS Distributions struct kd_bufinfo *kdbp;
593*1031c584SApple OSS Distributions struct kd_bufinfo *min_kdbp;
594*1031c584SApple OSS Distributions size_t tempbuf_count;
595*1031c584SApple OSS Distributions uint32_t tempbuf_number;
596*1031c584SApple OSS Distributions kdebug_emit_filter_t old_emit;
597*1031c584SApple OSS Distributions uint32_t old_live_flags;
598*1031c584SApple OSS Distributions bool out_of_events = false;
599*1031c584SApple OSS Distributions bool wrapped = false;
600*1031c584SApple OSS Distributions bool set_preempt = true;
601*1031c584SApple OSS Distributions bool should_disable = false;
602*1031c584SApple OSS Distributions
603*1031c584SApple OSS Distributions struct kd_bufinfo *kdbip = kd_data_page->kdb_info;
604*1031c584SApple OSS Distributions struct kd_region *kd_bufs = kd_data_page->kd_bufs;
605*1031c584SApple OSS Distributions
606*1031c584SApple OSS Distributions assert(number != NULL);
607*1031c584SApple OSS Distributions count = *number / sizeof(kd_buf);
608*1031c584SApple OSS Distributions *number = 0;
609*1031c584SApple OSS Distributions
610*1031c584SApple OSS Distributions if (count == 0 || !(kd_ctrl_page->kdc_flags & KDBG_BUFINIT) || kd_data_page->kdcopybuf == 0) {
611*1031c584SApple OSS Distributions return EINVAL;
612*1031c584SApple OSS Distributions }
613*1031c584SApple OSS Distributions
614*1031c584SApple OSS Distributions if (kd_ctrl_page->mode == KDEBUG_MODE_TRIAGE) {
615*1031c584SApple OSS Distributions /*
616*1031c584SApple OSS Distributions * A corpse can be created due to 'TASK_HAS_TOO_MANY_THREADS'
617*1031c584SApple OSS Distributions * and that can be handled by a callout thread that already
618*1031c584SApple OSS Distributions * has the eager-preemption set.
619*1031c584SApple OSS Distributions * So check to see if we are dealing with one such thread.
620*1031c584SApple OSS Distributions */
621*1031c584SApple OSS Distributions set_preempt = !(thread_is_eager_preempt(current_thread()));
622*1031c584SApple OSS Distributions }
623*1031c584SApple OSS Distributions
624*1031c584SApple OSS Distributions if (set_preempt) {
625*1031c584SApple OSS Distributions thread_set_eager_preempt(current_thread());
626*1031c584SApple OSS Distributions }
627*1031c584SApple OSS Distributions
628*1031c584SApple OSS Distributions memset(&lostevent, 0, sizeof(lostevent));
629*1031c584SApple OSS Distributions lostevent.debugid = TRACE_LOST_EVENTS;
630*1031c584SApple OSS Distributions
631*1031c584SApple OSS Distributions /*
632*1031c584SApple OSS Distributions * Capture the current time. Only sort events that have occured
633*1031c584SApple OSS Distributions * before now. Since the IOPs are being flushed here, it is possible
634*1031c584SApple OSS Distributions * that events occur on the AP while running live tracing.
635*1031c584SApple OSS Distributions */
636*1031c584SApple OSS Distributions if (kd_ctrl_page->mode == KDEBUG_MODE_TRACE) {
637*1031c584SApple OSS Distributions barrier_max = kdebug_timestamp() & KDBG_TIMESTAMP_MASK;
638*1031c584SApple OSS Distributions } else {
639*1031c584SApple OSS Distributions barrier_max = mach_continuous_time() & KDBG_TIMESTAMP_MASK;
640*1031c584SApple OSS Distributions }
641*1031c584SApple OSS Distributions
642*1031c584SApple OSS Distributions /*
643*1031c584SApple OSS Distributions * Disable wrap so storage units cannot be stolen out from underneath us
644*1031c584SApple OSS Distributions * while merging events.
645*1031c584SApple OSS Distributions *
646*1031c584SApple OSS Distributions * Because we hold ktrace_lock, no other control threads can be playing
647*1031c584SApple OSS Distributions * with kdc_flags. The code that emits new events could be running,
648*1031c584SApple OSS Distributions * but it grabs kdc_storage_lock if it needs to acquire a new storage
649*1031c584SApple OSS Distributions * chunk, which is where it examines kdc_flags. If it is adding to
650*1031c584SApple OSS Distributions * the same chunk we're reading from, check for that below.
651*1031c584SApple OSS Distributions */
652*1031c584SApple OSS Distributions wrapped = kdebug_disable_wrap(kd_ctrl_page, &old_emit, &old_live_flags);
653*1031c584SApple OSS Distributions
654*1031c584SApple OSS Distributions if (count > kd_data_page->kdb_event_count) {
655*1031c584SApple OSS Distributions count = kd_data_page->kdb_event_count;
656*1031c584SApple OSS Distributions }
657*1031c584SApple OSS Distributions
658*1031c584SApple OSS Distributions if ((tempbuf_count = count) > kd_ctrl_page->kdebug_kdcopybuf_count) {
659*1031c584SApple OSS Distributions tempbuf_count = kd_ctrl_page->kdebug_kdcopybuf_count;
660*1031c584SApple OSS Distributions }
661*1031c584SApple OSS Distributions
662*1031c584SApple OSS Distributions /*
663*1031c584SApple OSS Distributions * If the buffers have wrapped, do not emit additional lost events for the
664*1031c584SApple OSS Distributions * oldest storage units.
665*1031c584SApple OSS Distributions */
666*1031c584SApple OSS Distributions if (wrapped) {
667*1031c584SApple OSS Distributions kd_ctrl_page->kdc_live_flags &= ~KDBG_WRAPPED;
668*1031c584SApple OSS Distributions
669*1031c584SApple OSS Distributions for (cpu = 0, kdbp = &kdbip[0]; cpu < kd_ctrl_page->kdebug_cpus; cpu++, kdbp++) {
670*1031c584SApple OSS Distributions if ((kdsp = kdbp->kd_list_head).raw == KDS_PTR_NULL) {
671*1031c584SApple OSS Distributions continue;
672*1031c584SApple OSS Distributions }
673*1031c584SApple OSS Distributions kdsp_actual = POINTER_FROM_KDS_PTR(kd_bufs, kdsp);
674*1031c584SApple OSS Distributions kdsp_actual->kds_lostevents = false;
675*1031c584SApple OSS Distributions }
676*1031c584SApple OSS Distributions }
677*1031c584SApple OSS Distributions
678*1031c584SApple OSS Distributions if (kd_ctrl_page->mode == KDEBUG_MODE_TRIAGE) {
679*1031c584SApple OSS Distributions /*
680*1031c584SApple OSS Distributions * In TRIAGE mode we want to extract all the current
681*1031c584SApple OSS Distributions * records regardless of where we stopped reading last
682*1031c584SApple OSS Distributions * time so that we have the best shot at getting older
683*1031c584SApple OSS Distributions * records for threads before the buffers are wrapped.
684*1031c584SApple OSS Distributions * So set:-
685*1031c584SApple OSS Distributions * a) kd_prev_timebase to 0 so we (re-)consider older records
686*1031c584SApple OSS Distributions * b) readlast to 0 to initiate the search from the
687*1031c584SApple OSS Distributions * 1st record.
688*1031c584SApple OSS Distributions */
689*1031c584SApple OSS Distributions for (cpu = 0, kdbp = &kdbip[0]; cpu < kd_ctrl_page->kdebug_cpus; cpu++, kdbp++) {
690*1031c584SApple OSS Distributions kdbp->kd_prev_timebase = 0;
691*1031c584SApple OSS Distributions if ((kdsp = kdbp->kd_list_head).raw == KDS_PTR_NULL) {
692*1031c584SApple OSS Distributions continue;
693*1031c584SApple OSS Distributions }
694*1031c584SApple OSS Distributions kdsp_actual = POINTER_FROM_KDS_PTR(kd_bufs, kdsp);
695*1031c584SApple OSS Distributions kdsp_actual->kds_readlast = 0;
696*1031c584SApple OSS Distributions }
697*1031c584SApple OSS Distributions }
698*1031c584SApple OSS Distributions
699*1031c584SApple OSS Distributions /*
700*1031c584SApple OSS Distributions * Capture the earliest time where there are events for all CPUs and don't
701*1031c584SApple OSS Distributions * emit events with timestamps prior.
702*1031c584SApple OSS Distributions */
703*1031c584SApple OSS Distributions barrier_min = kd_ctrl_page->kdc_oldest_time;
704*1031c584SApple OSS Distributions
705*1031c584SApple OSS Distributions while (count) {
706*1031c584SApple OSS Distributions tempbuf = kd_data_page->kdcopybuf;
707*1031c584SApple OSS Distributions tempbuf_number = 0;
708*1031c584SApple OSS Distributions
709*1031c584SApple OSS Distributions if (wrapped) {
710*1031c584SApple OSS Distributions /*
711*1031c584SApple OSS Distributions * Emit a lost events tracepoint to indicate that previous events
712*1031c584SApple OSS Distributions * were lost -- the thread map cannot be trusted. A new one must
713*1031c584SApple OSS Distributions * be taken so tools can analyze the trace in a backwards-facing
714*1031c584SApple OSS Distributions * fashion.
715*1031c584SApple OSS Distributions */
716*1031c584SApple OSS Distributions kdbg_set_timestamp_and_cpu(&lostevent, barrier_min, 0);
717*1031c584SApple OSS Distributions *tempbuf = lostevent;
718*1031c584SApple OSS Distributions wrapped = false;
719*1031c584SApple OSS Distributions goto nextevent;
720*1031c584SApple OSS Distributions }
721*1031c584SApple OSS Distributions
722*1031c584SApple OSS Distributions /* While space left in merged events scratch buffer. */
723*1031c584SApple OSS Distributions while (tempbuf_count) {
724*1031c584SApple OSS Distributions bool lostevents = false;
725*1031c584SApple OSS Distributions int lostcpu = 0;
726*1031c584SApple OSS Distributions earliest_time = UINT64_MAX;
727*1031c584SApple OSS Distributions min_kdbp = NULL;
728*1031c584SApple OSS Distributions min_cpu = 0;
729*1031c584SApple OSS Distributions
730*1031c584SApple OSS Distributions /* Check each CPU's buffers for the earliest event. */
731*1031c584SApple OSS Distributions for (cpu = 0, kdbp = &kdbip[0]; cpu < kd_ctrl_page->kdebug_cpus; cpu++, kdbp++) {
732*1031c584SApple OSS Distributions /* Skip CPUs without data in their oldest storage unit. */
733*1031c584SApple OSS Distributions if ((kdsp = kdbp->kd_list_head).raw == KDS_PTR_NULL) {
734*1031c584SApple OSS Distributions next_cpu:
735*1031c584SApple OSS Distributions continue;
736*1031c584SApple OSS Distributions }
737*1031c584SApple OSS Distributions /* From CPU data to buffer header to buffer. */
738*1031c584SApple OSS Distributions kdsp_actual = POINTER_FROM_KDS_PTR(kd_bufs, kdsp);
739*1031c584SApple OSS Distributions
740*1031c584SApple OSS Distributions next_event:
741*1031c584SApple OSS Distributions /* The next event to be read from this buffer. */
742*1031c584SApple OSS Distributions rcursor = kdsp_actual->kds_readlast;
743*1031c584SApple OSS Distributions
744*1031c584SApple OSS Distributions /* Skip this buffer if there are no events left. */
745*1031c584SApple OSS Distributions if (rcursor == kdsp_actual->kds_bufindx) {
746*1031c584SApple OSS Distributions continue;
747*1031c584SApple OSS Distributions }
748*1031c584SApple OSS Distributions
749*1031c584SApple OSS Distributions if (kd_ctrl_page->mode == KDEBUG_MODE_TRIAGE) {
750*1031c584SApple OSS Distributions /*
751*1031c584SApple OSS Distributions * TRIAGE mode record keeping doesn't (currently)
752*1031c584SApple OSS Distributions * use lostevent markers. It also doesn't want to
753*1031c584SApple OSS Distributions * call release_storage_unit() in this read call.
754*1031c584SApple OSS Distributions * It expects the buffers to wrap and records reclaimed
755*1031c584SApple OSS Distributions * in that way solely.
756*1031c584SApple OSS Distributions */
757*1031c584SApple OSS Distributions t = kdbg_get_timestamp(&kdsp_actual->kds_records[rcursor]);
758*1031c584SApple OSS Distributions goto skip_record_checks;
759*1031c584SApple OSS Distributions }
760*1031c584SApple OSS Distributions
761*1031c584SApple OSS Distributions /*
762*1031c584SApple OSS Distributions * Check that this storage unit wasn't stolen and events were
763*1031c584SApple OSS Distributions * lost. This must have happened while wrapping was disabled
764*1031c584SApple OSS Distributions * in this function.
765*1031c584SApple OSS Distributions */
766*1031c584SApple OSS Distributions if (kdsp_actual->kds_lostevents) {
767*1031c584SApple OSS Distributions lostevents = true;
768*1031c584SApple OSS Distributions kdsp_actual->kds_lostevents = false;
769*1031c584SApple OSS Distributions
770*1031c584SApple OSS Distributions /*
771*1031c584SApple OSS Distributions * The earliest event we can trust is the first one in this
772*1031c584SApple OSS Distributions * stolen storage unit.
773*1031c584SApple OSS Distributions */
774*1031c584SApple OSS Distributions uint64_t lost_time =
775*1031c584SApple OSS Distributions kdbg_get_timestamp(&kdsp_actual->kds_records[0]);
776*1031c584SApple OSS Distributions if (kd_ctrl_page->kdc_oldest_time < lost_time) {
777*1031c584SApple OSS Distributions /*
778*1031c584SApple OSS Distributions * If this is the first time we've seen lost events for
779*1031c584SApple OSS Distributions * this gap, record its timestamp as the oldest
780*1031c584SApple OSS Distributions * timestamp we're willing to merge for the lost events
781*1031c584SApple OSS Distributions * tracepoint.
782*1031c584SApple OSS Distributions */
783*1031c584SApple OSS Distributions kd_ctrl_page->kdc_oldest_time = barrier_min = lost_time;
784*1031c584SApple OSS Distributions lostcpu = cpu;
785*1031c584SApple OSS Distributions }
786*1031c584SApple OSS Distributions }
787*1031c584SApple OSS Distributions
788*1031c584SApple OSS Distributions t = kdbg_get_timestamp(&kdsp_actual->kds_records[rcursor]);
789*1031c584SApple OSS Distributions
790*1031c584SApple OSS Distributions if (t > barrier_max) {
791*1031c584SApple OSS Distributions goto next_cpu;
792*1031c584SApple OSS Distributions }
793*1031c584SApple OSS Distributions if (t < kdsp_actual->kds_timestamp) {
794*1031c584SApple OSS Distributions /*
795*1031c584SApple OSS Distributions * This indicates the event emitter hasn't completed
796*1031c584SApple OSS Distributions * filling in the event (becuase we're looking at the
797*1031c584SApple OSS Distributions * buffer that the record head is using). The max barrier
798*1031c584SApple OSS Distributions * timestamp should have saved us from seeing these kinds
799*1031c584SApple OSS Distributions * of things, but other CPUs might be slow on the up-take.
800*1031c584SApple OSS Distributions *
801*1031c584SApple OSS Distributions * Bail out so we don't get out-of-order events by
802*1031c584SApple OSS Distributions * continuing to read events from other CPUs' events.
803*1031c584SApple OSS Distributions */
804*1031c584SApple OSS Distributions out_of_events = true;
805*1031c584SApple OSS Distributions break;
806*1031c584SApple OSS Distributions }
807*1031c584SApple OSS Distributions
808*1031c584SApple OSS Distributions /*
809*1031c584SApple OSS Distributions * Ignore events that have aged out due to wrapping or storage
810*1031c584SApple OSS Distributions * unit exhaustion while merging events.
811*1031c584SApple OSS Distributions */
812*1031c584SApple OSS Distributions if (t < barrier_min) {
813*1031c584SApple OSS Distributions kdsp_actual->kds_readlast++;
814*1031c584SApple OSS Distributions if (kdsp_actual->kds_readlast >= kd_ctrl_page->kdebug_events_per_storage_unit) {
815*1031c584SApple OSS Distributions release_storage_unit(kd_ctrl_page, kd_data_page, cpu, kdsp.raw);
816*1031c584SApple OSS Distributions
817*1031c584SApple OSS Distributions if ((kdsp = kdbp->kd_list_head).raw == KDS_PTR_NULL) {
818*1031c584SApple OSS Distributions goto next_cpu;
819*1031c584SApple OSS Distributions }
820*1031c584SApple OSS Distributions kdsp_actual = POINTER_FROM_KDS_PTR(kd_bufs, kdsp);
821*1031c584SApple OSS Distributions }
822*1031c584SApple OSS Distributions goto next_event;
823*1031c584SApple OSS Distributions }
824*1031c584SApple OSS Distributions
825*1031c584SApple OSS Distributions /*
826*1031c584SApple OSS Distributions * Don't worry about merging any events -- just walk through
827*1031c584SApple OSS Distributions * the CPUs and find the latest timestamp of lost events.
828*1031c584SApple OSS Distributions */
829*1031c584SApple OSS Distributions if (lostevents) {
830*1031c584SApple OSS Distributions continue;
831*1031c584SApple OSS Distributions }
832*1031c584SApple OSS Distributions skip_record_checks:
833*1031c584SApple OSS Distributions if (t < earliest_time) {
834*1031c584SApple OSS Distributions earliest_time = t;
835*1031c584SApple OSS Distributions min_kdbp = kdbp;
836*1031c584SApple OSS Distributions min_cpu = cpu;
837*1031c584SApple OSS Distributions }
838*1031c584SApple OSS Distributions }
839*1031c584SApple OSS Distributions if (lostevents) {
840*1031c584SApple OSS Distributions /*
841*1031c584SApple OSS Distributions * If any lost events were hit in the buffers, emit an event
842*1031c584SApple OSS Distributions * with the latest timestamp.
843*1031c584SApple OSS Distributions */
844*1031c584SApple OSS Distributions kdbg_set_timestamp_and_cpu(&lostevent, barrier_min, lostcpu);
845*1031c584SApple OSS Distributions *tempbuf = lostevent;
846*1031c584SApple OSS Distributions tempbuf->arg1 = 1;
847*1031c584SApple OSS Distributions goto nextevent;
848*1031c584SApple OSS Distributions }
849*1031c584SApple OSS Distributions if (min_kdbp == NULL) {
850*1031c584SApple OSS Distributions /* All buffers ran empty. */
851*1031c584SApple OSS Distributions out_of_events = true;
852*1031c584SApple OSS Distributions }
853*1031c584SApple OSS Distributions if (out_of_events) {
854*1031c584SApple OSS Distributions break;
855*1031c584SApple OSS Distributions }
856*1031c584SApple OSS Distributions
857*1031c584SApple OSS Distributions kdsp = min_kdbp->kd_list_head;
858*1031c584SApple OSS Distributions kdsp_actual = POINTER_FROM_KDS_PTR(kd_bufs, kdsp);
859*1031c584SApple OSS Distributions
860*1031c584SApple OSS Distributions if (min_kdbp->latest_past_event_timestamp != 0) {
861*1031c584SApple OSS Distributions if (kdbg_debug) {
862*1031c584SApple OSS Distributions printf("kdebug: PAST EVENT: debugid %#8x: "
863*1031c584SApple OSS Distributions "time %lld from CPU %u "
864*1031c584SApple OSS Distributions "(barrier at time %lld)\n",
865*1031c584SApple OSS Distributions kdsp_actual->kds_records[rcursor].debugid,
866*1031c584SApple OSS Distributions t, cpu, barrier_min);
867*1031c584SApple OSS Distributions }
868*1031c584SApple OSS Distributions
869*1031c584SApple OSS Distributions kdbg_set_timestamp_and_cpu(tempbuf, earliest_time, min_cpu);
870*1031c584SApple OSS Distributions tempbuf->arg1 = (kd_buf_argtype)min_kdbp->latest_past_event_timestamp;
871*1031c584SApple OSS Distributions tempbuf->arg2 = 0;
872*1031c584SApple OSS Distributions tempbuf->arg3 = 0;
873*1031c584SApple OSS Distributions tempbuf->arg4 = 0;
874*1031c584SApple OSS Distributions tempbuf->debugid = TRACE_PAST_EVENTS;
875*1031c584SApple OSS Distributions min_kdbp->latest_past_event_timestamp = 0;
876*1031c584SApple OSS Distributions goto nextevent;
877*1031c584SApple OSS Distributions }
878*1031c584SApple OSS Distributions
879*1031c584SApple OSS Distributions /* Copy earliest event into merged events scratch buffer. */
880*1031c584SApple OSS Distributions *tempbuf = kdsp_actual->kds_records[kdsp_actual->kds_readlast++];
881*1031c584SApple OSS Distributions kd_buf *earliest_event = tempbuf;
882*1031c584SApple OSS Distributions if (kd_control_trace.kdc_flags & KDBG_MATCH_DISABLE) {
883*1031c584SApple OSS Distributions kd_event_matcher *match = &kd_control_trace.disable_event_match;
884*1031c584SApple OSS Distributions kd_event_matcher *mask = &kd_control_trace.disable_event_mask;
885*1031c584SApple OSS Distributions if ((earliest_event->debugid & mask->kem_debugid) == match->kem_debugid &&
886*1031c584SApple OSS Distributions (earliest_event->arg1 & mask->kem_args[0]) == match->kem_args[0] &&
887*1031c584SApple OSS Distributions (earliest_event->arg2 & mask->kem_args[1]) == match->kem_args[1] &&
888*1031c584SApple OSS Distributions (earliest_event->arg3 & mask->kem_args[2]) == match->kem_args[2] &&
889*1031c584SApple OSS Distributions (earliest_event->arg4 & mask->kem_args[3]) == match->kem_args[3]) {
890*1031c584SApple OSS Distributions should_disable = true;
891*1031c584SApple OSS Distributions }
892*1031c584SApple OSS Distributions }
893*1031c584SApple OSS Distributions
894*1031c584SApple OSS Distributions if (kd_ctrl_page->mode == KDEBUG_MODE_TRACE) {
895*1031c584SApple OSS Distributions if (kdsp_actual->kds_readlast == kd_ctrl_page->kdebug_events_per_storage_unit) {
896*1031c584SApple OSS Distributions release_storage_unit(kd_ctrl_page, kd_data_page, min_cpu, kdsp.raw);
897*1031c584SApple OSS Distributions }
898*1031c584SApple OSS Distributions }
899*1031c584SApple OSS Distributions
900*1031c584SApple OSS Distributions /*
901*1031c584SApple OSS Distributions * Watch for out of order timestamps (from IOPs).
902*1031c584SApple OSS Distributions */
903*1031c584SApple OSS Distributions if (earliest_time < min_kdbp->kd_prev_timebase) {
904*1031c584SApple OSS Distributions /*
905*1031c584SApple OSS Distributions * If we haven't already, emit a retrograde events event.
906*1031c584SApple OSS Distributions * Otherwise, ignore this event.
907*1031c584SApple OSS Distributions */
908*1031c584SApple OSS Distributions if (traced_retrograde) {
909*1031c584SApple OSS Distributions continue;
910*1031c584SApple OSS Distributions }
911*1031c584SApple OSS Distributions if (kdbg_debug) {
912*1031c584SApple OSS Distributions printf("kdebug: RETRO EVENT: debugid %#8x: "
913*1031c584SApple OSS Distributions "time %lld from CPU %u "
914*1031c584SApple OSS Distributions "(barrier at time %lld)\n",
915*1031c584SApple OSS Distributions kdsp_actual->kds_records[rcursor].debugid,
916*1031c584SApple OSS Distributions t, cpu, barrier_min);
917*1031c584SApple OSS Distributions }
918*1031c584SApple OSS Distributions
919*1031c584SApple OSS Distributions kdbg_set_timestamp_and_cpu(tempbuf, min_kdbp->kd_prev_timebase,
920*1031c584SApple OSS Distributions kdbg_get_cpu(tempbuf));
921*1031c584SApple OSS Distributions tempbuf->arg1 = tempbuf->debugid;
922*1031c584SApple OSS Distributions tempbuf->arg2 = (kd_buf_argtype)earliest_time;
923*1031c584SApple OSS Distributions tempbuf->arg3 = 0;
924*1031c584SApple OSS Distributions tempbuf->arg4 = 0;
925*1031c584SApple OSS Distributions tempbuf->debugid = TRACE_RETROGRADE_EVENTS;
926*1031c584SApple OSS Distributions traced_retrograde = true;
927*1031c584SApple OSS Distributions } else {
928*1031c584SApple OSS Distributions min_kdbp->kd_prev_timebase = earliest_time;
929*1031c584SApple OSS Distributions }
930*1031c584SApple OSS Distributions nextevent:
931*1031c584SApple OSS Distributions tempbuf_count--;
932*1031c584SApple OSS Distributions tempbuf_number++;
933*1031c584SApple OSS Distributions tempbuf++;
934*1031c584SApple OSS Distributions
935*1031c584SApple OSS Distributions if (kd_ctrl_page->mode == KDEBUG_MODE_TRACE &&
936*1031c584SApple OSS Distributions (RAW_file_written += sizeof(kd_buf)) >= RAW_FLUSH_SIZE) {
937*1031c584SApple OSS Distributions break;
938*1031c584SApple OSS Distributions }
939*1031c584SApple OSS Distributions }
940*1031c584SApple OSS Distributions
941*1031c584SApple OSS Distributions if (tempbuf_number) {
942*1031c584SApple OSS Distributions /*
943*1031c584SApple OSS Distributions * Remember the latest timestamp of events that we've merged so we
944*1031c584SApple OSS Distributions * don't think we've lost events later.
945*1031c584SApple OSS Distributions */
946*1031c584SApple OSS Distributions uint64_t latest_time = kdbg_get_timestamp(tempbuf - 1);
947*1031c584SApple OSS Distributions if (kd_ctrl_page->kdc_oldest_time < latest_time) {
948*1031c584SApple OSS Distributions kd_ctrl_page->kdc_oldest_time = latest_time;
949*1031c584SApple OSS Distributions }
950*1031c584SApple OSS Distributions
951*1031c584SApple OSS Distributions if (kd_ctrl_page->mode == KDEBUG_MODE_TRACE) {
952*1031c584SApple OSS Distributions extern int kernel_debug_trace_write_to_file(user_addr_t *buffer,
953*1031c584SApple OSS Distributions size_t *number, size_t *count, size_t tempbuf_number,
954*1031c584SApple OSS Distributions vnode_t vp, vfs_context_t ctx, uint32_t file_version);
955*1031c584SApple OSS Distributions error = kernel_debug_trace_write_to_file(&buffer, number,
956*1031c584SApple OSS Distributions &count, tempbuf_number, vp, ctx, file_version);
957*1031c584SApple OSS Distributions } else if (kd_ctrl_page->mode == KDEBUG_MODE_TRIAGE) {
958*1031c584SApple OSS Distributions memcpy((void*)buffer, kd_data_page->kdcopybuf,
959*1031c584SApple OSS Distributions tempbuf_number * sizeof(kd_buf));
960*1031c584SApple OSS Distributions buffer += tempbuf_number * sizeof(kd_buf);
961*1031c584SApple OSS Distributions } else {
962*1031c584SApple OSS Distributions panic("kdebug: invalid kdebug mode %d", kd_ctrl_page->mode);
963*1031c584SApple OSS Distributions }
964*1031c584SApple OSS Distributions if (error) {
965*1031c584SApple OSS Distributions *number = 0;
966*1031c584SApple OSS Distributions error = EINVAL;
967*1031c584SApple OSS Distributions break;
968*1031c584SApple OSS Distributions }
969*1031c584SApple OSS Distributions count -= tempbuf_number;
970*1031c584SApple OSS Distributions *number += tempbuf_number;
971*1031c584SApple OSS Distributions }
972*1031c584SApple OSS Distributions if (out_of_events) {
973*1031c584SApple OSS Distributions break;
974*1031c584SApple OSS Distributions }
975*1031c584SApple OSS Distributions
976*1031c584SApple OSS Distributions if ((tempbuf_count = count) > kd_ctrl_page->kdebug_kdcopybuf_count) {
977*1031c584SApple OSS Distributions tempbuf_count = kd_ctrl_page->kdebug_kdcopybuf_count;
978*1031c584SApple OSS Distributions }
979*1031c584SApple OSS Distributions }
980*1031c584SApple OSS Distributions if ((old_live_flags & KDBG_NOWRAP) == 0) {
981*1031c584SApple OSS Distributions _enable_wrap(kd_ctrl_page, old_emit);
982*1031c584SApple OSS Distributions }
983*1031c584SApple OSS Distributions
984*1031c584SApple OSS Distributions if (set_preempt) {
985*1031c584SApple OSS Distributions thread_clear_eager_preempt(current_thread());
986*1031c584SApple OSS Distributions }
987*1031c584SApple OSS Distributions
988*1031c584SApple OSS Distributions if (should_disable) {
989*1031c584SApple OSS Distributions kernel_debug_disable();
990*1031c584SApple OSS Distributions }
991*1031c584SApple OSS Distributions
992*1031c584SApple OSS Distributions return error;
993*1031c584SApple OSS Distributions }
994