]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kperf/kperfbsd.c
xnu-3247.1.106.tar.gz
[apple/xnu.git] / osfmk / kperf / kperfbsd.c
CommitLineData
316670eb
A
1/*
2 * Copyright (c) 2011 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29/* sysctl interface for paramters from user-land */
30
31#include <sys/param.h>
32#include <sys/mman.h>
33#include <sys/stat.h>
34#include <sys/sysctl.h>
39236c6e 35#include <sys/kauth.h>
316670eb 36#include <libkern/libkern.h>
39236c6e
A
37#include <kern/debug.h>
38#include <pexpert/pexpert.h>
316670eb
A
39
40#include <kperf/context.h>
41#include <kperf/action.h>
42#include <kperf/timetrigger.h>
43#include <kperf/pet.h>
316670eb
A
44#include <kperf/kperfbsd.h>
45#include <kperf/kperf.h>
46
39236c6e
A
47
48/* a pid which is allowed to control kperf without requiring root access */
49static pid_t blessed_pid = -1;
50static boolean_t blessed_preempt = FALSE;
51
52/* IDs for dispatch from SYSCTL macros */
316670eb
A
53#define REQ_SAMPLING (1)
54#define REQ_ACTION_COUNT (2)
55#define REQ_ACTION_SAMPLERS (3)
56#define REQ_TIMER_COUNT (4)
57#define REQ_TIMER_PERIOD (5)
58#define REQ_TIMER_PET (6)
39236c6e
A
59#define REQ_TIMER_ACTION (7)
60#define REQ_BLESS (8)
61#define REQ_ACTION_USERDATA (9)
62#define REQ_ACTION_FILTER_BY_TASK (10)
63#define REQ_ACTION_FILTER_BY_PID (11)
64#define REQ_KDBG_CALLSTACKS (12)
65#define REQ_PET_IDLE_RATE (13)
66#define REQ_BLESS_PREEMPT (14)
3e170ce0
A
67#define REQ_KDBG_CSWITCH (15)
68#define REQ_CSWITCH_ACTION (16)
69#define REQ_SIGNPOST_ACTION (17)
39236c6e
A
70
71/* simple state variables */
72int kperf_debug_level = 0;
73
74static lck_grp_attr_t *kperf_cfg_lckgrp_attr = NULL;
75static lck_grp_t *kperf_cfg_lckgrp = NULL;
76static lck_mtx_t kperf_cfg_lock;
77static boolean_t kperf_cfg_initted = FALSE;
78
fe8ab488
A
79void kdbg_swap_global_state_pid(pid_t old_pid, pid_t new_pid); /* bsd/kern/kdebug.c */
80
39236c6e
A
81/***************************
82 *
83 * lock init
84 *
85 ***************************/
86
87void
88kperf_bootstrap(void)
89{
90 kperf_cfg_lckgrp_attr = lck_grp_attr_alloc_init();
91 kperf_cfg_lckgrp = lck_grp_alloc_init("kperf cfg",
92 kperf_cfg_lckgrp_attr);
93 lck_mtx_init(&kperf_cfg_lock, kperf_cfg_lckgrp, LCK_ATTR_NULL);
94
95 kperf_cfg_initted = TRUE;
96}
316670eb 97
39236c6e
A
98/***************************
99 *
100 * sysctl handlers
101 *
102 ***************************/
316670eb
A
103
104static int
105sysctl_timer_period( __unused struct sysctl_oid *oidp, struct sysctl_req *req )
106{
107 int error = 0;
108 uint64_t inputs[2], retval;
109 unsigned timer, set = 0;
110
111 /* get 2x 64-bit words */
112 error = SYSCTL_IN( req, inputs, 2*sizeof(inputs[0]) );
113 if(error)
316670eb 114 return (error);
316670eb
A
115
116 /* setup inputs */
117 timer = (unsigned) inputs[0];
118 if( inputs[1] != ~0ULL )
119 set = 1;
120
316670eb
A
121 if( set )
122 {
316670eb
A
123 error = kperf_timer_set_period( timer, inputs[1] );
124 if( error )
125 return error;
126 }
127
128 error = kperf_timer_get_period(timer, &retval);
129 if(error)
316670eb 130 return (error);
316670eb
A
131
132 inputs[1] = retval;
133
134 if( error == 0 )
316670eb 135 error = SYSCTL_OUT( req, inputs, 2*sizeof(inputs[0]) );
39236c6e
A
136
137 return error;
138}
139
140static int
141sysctl_timer_action( __unused struct sysctl_oid *oidp, struct sysctl_req *req )
142{
143 int error = 0;
144 uint64_t inputs[2];
145 uint32_t retval;
146 unsigned timer, set = 0;
147
148 /* get 2x 64-bit words */
149 error = SYSCTL_IN( req, inputs, 2*sizeof(inputs[0]) );
150 if(error)
151 return (error);
152
153 /* setup inputs */
154 timer = (unsigned) inputs[0];
155 if( inputs[1] != ~0ULL )
156 set = 1;
157
158 if( set )
159 {
160 error = kperf_timer_set_action( timer, inputs[1] );
316670eb 161 if( error )
39236c6e 162 return error;
316670eb
A
163 }
164
39236c6e
A
165 error = kperf_timer_get_action(timer, &retval);
166 if(error)
167 return (error);
168
169 inputs[1] = retval;
170
171 if( error == 0 )
172 error = SYSCTL_OUT( req, inputs, 2*sizeof(inputs[0]) );
173
316670eb
A
174 return error;
175}
176
177static int
178sysctl_action_samplers( __unused struct sysctl_oid *oidp,
179 struct sysctl_req *req )
180{
181 int error = 0;
182 uint64_t inputs[3];
183 uint32_t retval;
184 unsigned actionid, set = 0;
185
186 /* get 3x 64-bit words */
187 error = SYSCTL_IN( req, inputs, 3*sizeof(inputs[0]) );
188 if(error)
316670eb 189 return (error);
316670eb
A
190
191 /* setup inputs */
192 set = (unsigned) inputs[0];
193 actionid = (unsigned) inputs[1];
194
195 if( set )
196 {
197 error = kperf_action_set_samplers( actionid, inputs[2] );
198 if( error )
199 return error;
200 }
201
316670eb
A
202 error = kperf_action_get_samplers(actionid, &retval);
203 if(error)
316670eb 204 return (error);
316670eb
A
205
206 inputs[2] = retval;
207
208 if( error == 0 )
39236c6e
A
209 error = SYSCTL_OUT( req, inputs, 3*sizeof(inputs[0]) );
210
211 return error;
212}
213
214static int
215sysctl_action_userdata( __unused struct sysctl_oid *oidp,
216 struct sysctl_req *req )
217{
218 int error = 0;
219 uint64_t inputs[3];
220 uint32_t retval;
221 unsigned actionid, set = 0;
222
223 /* get 3x 64-bit words */
224 error = SYSCTL_IN( req, inputs, 3*sizeof(inputs[0]) );
225 if(error)
226 return (error);
227
228 /* setup inputs */
229 set = (unsigned) inputs[0];
230 actionid = (unsigned) inputs[1];
231
232 if( set )
316670eb 233 {
39236c6e
A
234 error = kperf_action_set_userdata( actionid, inputs[2] );
235 if( error )
236 return error;
237 }
238
239 error = kperf_action_get_userdata(actionid, &retval);
240 if(error)
241 return (error);
242
243 inputs[2] = retval;
244
245 if( error == 0 )
316670eb 246 error = SYSCTL_OUT( req, inputs, 3*sizeof(inputs[0]) );
39236c6e
A
247
248 return error;
249}
250
251static int
252sysctl_action_filter( __unused struct sysctl_oid *oidp,
253 struct sysctl_req *req, int is_task_t )
254{
255 int error = 0;
256 uint64_t inputs[3];
257 int retval;
258 unsigned actionid, set = 0;
259 mach_port_name_t portname;
260 int pid;
261
262 /* get 3x 64-bit words */
263 error = SYSCTL_IN( req, inputs, 3*sizeof(inputs[0]) );
264 if(error)
265 return (error);
266
267 /* setup inputs */
268 set = (unsigned) inputs[0];
269 actionid = (unsigned) inputs[1];
270
271 if( set )
272 {
273 if( is_task_t )
274 {
275 portname = (mach_port_name_t) inputs[2];
276 pid = kperf_port_to_pid(portname);
277 }
278 else
279 pid = (int) inputs[2];
280
281 error = kperf_action_set_filter( actionid, pid );
316670eb 282 if( error )
39236c6e 283 return error;
316670eb
A
284 }
285
39236c6e
A
286 error = kperf_action_get_filter(actionid, &retval);
287 if(error)
288 return (error);
289
290 inputs[2] = retval;
291
292 if( error == 0 )
293 error = SYSCTL_OUT( req, inputs, 3*sizeof(inputs[0]) );
294
316670eb
A
295 return error;
296}
297
298static int
299sysctl_sampling( struct sysctl_oid *oidp, struct sysctl_req *req )
300{
301 int error = 0;
302 uint32_t value = 0;
303
304 /* get the old value and process it */
305 value = kperf_sampling_status();
306
307 /* copy out the old value, get the new value */
308 error = sysctl_handle_int(oidp, &value, 0, req);
309 if (error || !req->newptr)
310 return (error);
311
316670eb
A
312 /* if that worked, and we're writing... */
313 if( value )
314 error = kperf_sampling_enable();
315 else
316 error = kperf_sampling_disable();
317
318 return error;
319}
320
321static int
322sysctl_action_count( struct sysctl_oid *oidp, struct sysctl_req *req )
323{
324 int error = 0;
325 uint32_t value = 0;
326
327 /* get the old value and process it */
328 value = kperf_action_get_count();
329
330 /* copy out the old value, get the new value */
331 error = sysctl_handle_int(oidp, &value, 0, req);
332 if (error || !req->newptr)
333 return (error);
334
316670eb
A
335 /* if that worked, and we're writing... */
336 return kperf_action_set_count(value);
337}
338
339static int
340sysctl_timer_count( struct sysctl_oid *oidp, struct sysctl_req *req )
341{
342 int error = 0;
343 uint32_t value = 0;
344
345 /* get the old value and process it */
346 value = kperf_timer_get_count();
347
348 /* copy out the old value, get the new value */
349 error = sysctl_handle_int(oidp, &value, 0, req);
350 if (error || !req->newptr)
351 return (error);
352
316670eb
A
353 /* if that worked, and we're writing... */
354 return kperf_timer_set_count(value);
355}
356
357static int
358sysctl_timer_pet( struct sysctl_oid *oidp, struct sysctl_req *req )
359{
360 int error = 0;
361 uint32_t value = 0;
362
363 /* get the old value and process it */
364 value = kperf_timer_get_petid();
365
366 /* copy out the old value, get the new value */
367 error = sysctl_handle_int(oidp, &value, 0, req);
368 if (error || !req->newptr)
369 return (error);
370
316670eb
A
371 /* if that worked, and we're writing... */
372 return kperf_timer_set_petid(value);
373}
374
39236c6e
A
375static int
376sysctl_bless( struct sysctl_oid *oidp, struct sysctl_req *req )
377{
378 int error = 0;
379 int value = 0;
380
381 /* get the old value and process it */
382 value = blessed_pid;
383
384 /* copy out the old value, get the new value */
385 error = sysctl_handle_int(oidp, &value, 0, req);
386 if (error || !req->newptr)
387 return (error);
388
389 /* if that worked, and we're writing... */
390 error = kperf_bless_pid(value);
391
392 return error;
393}
394
395static int
396sysctl_bless_preempt( struct sysctl_oid *oidp, struct sysctl_req *req )
397{
398 int error = 0;
399 int value = 0;
400
401 /* get the old value and process it */
402 value = blessed_preempt;
403
404 /* copy out the old value, get the new value */
405 error = sysctl_handle_int(oidp, &value, 0, req);
406 if (error || !req->newptr)
407 return (error);
408
409 /* if that worked, and we're writing... */
410 blessed_preempt = value ? TRUE : FALSE;
411
412 return 0;
413}
414
415
416static int
417sysctl_kdbg_callstacks( struct sysctl_oid *oidp, struct sysctl_req *req )
418{
419 int error = 0;
420 int value = 0;
421
422 /* get the old value and process it */
423 value = kperf_kdbg_get_stacks();
424
425 /* copy out the old value, get the new value */
426 error = sysctl_handle_int(oidp, &value, 0, req);
427 if (error || !req->newptr)
428 return (error);
429
430 /* if that worked, and we're writing... */
431 error = kperf_kdbg_set_stacks(value);
432
433 return error;
434}
435
436static int
437sysctl_pet_idle_rate( struct sysctl_oid *oidp, struct sysctl_req *req )
438{
439 int error = 0;
440 int value = 0;
441
442 /* get the old value and process it */
443 value = kperf_get_pet_idle_rate();
444
445 /* copy out the old value, get the new value */
446 error = sysctl_handle_int(oidp, &value, 0, req);
447 if (error || !req->newptr)
448 return (error);
449
450 /* if that worked, and we're writing... */
451 kperf_set_pet_idle_rate(value);
452
453 return error;
454}
455
3e170ce0
A
456static int
457sysctl_kdbg_cswitch( struct sysctl_oid *oidp, struct sysctl_req *req )
458{
459 int value = kperf_kdbg_cswitch_get();
460 int error = sysctl_handle_int(oidp, &value, 0, req);
461
462 if (error || !req->newptr) {
463 return error;
464 }
465
466 return kperf_kdbg_cswitch_set(value);
467}
468
469static int
470sysctl_cswitch_action( struct sysctl_oid *oidp, struct sysctl_req *req )
471{
472 int value = kperf_cswitch_action_get();
473 int error = sysctl_handle_int(oidp, &value, 0, req);
474
475 if (error || !req->newptr) {
476 return error;
477 }
478
479 return kperf_cswitch_action_set(value);
480}
481
482static int
483sysctl_signpost_action( struct sysctl_oid *oidp, struct sysctl_req *req )
484{
485 int value = kperf_signpost_action_get();
486 int error = sysctl_handle_int(oidp, &value, 0, req);
487
488 if (error || !req->newptr) {
489 return error;
490 }
491
492 return kperf_signpost_action_set(value);
493}
494
316670eb
A
495/*
496 * #define SYSCTL_HANDLER_ARGS (struct sysctl_oid *oidp, \
497 * void *arg1, int arg2, \
498 * struct sysctl_req *req )
499 */
500static int
501kperf_sysctl SYSCTL_HANDLER_ARGS
502{
39236c6e
A
503 int ret;
504
316670eb
A
505 // __unused struct sysctl_oid *unused_oidp = oidp;
506 (void)arg2;
39236c6e
A
507
508 if ( !kperf_cfg_initted )
509 panic("kperf_bootstrap not called");
510
511 ret = kperf_access_check();
512 if (ret) {
513 return ret;
514 }
515
516 lck_mtx_lock(&kperf_cfg_lock);
517
316670eb
A
518 /* which request */
519 switch( (uintptr_t) arg1 )
520 {
521 case REQ_ACTION_COUNT:
39236c6e
A
522 ret = sysctl_action_count( oidp, req );
523 break;
316670eb 524 case REQ_ACTION_SAMPLERS:
39236c6e
A
525 ret = sysctl_action_samplers( oidp, req );
526 break;
527 case REQ_ACTION_USERDATA:
528 ret = sysctl_action_userdata( oidp, req );
529 break;
316670eb 530 case REQ_TIMER_COUNT:
39236c6e
A
531 ret = sysctl_timer_count( oidp, req );
532 break;
316670eb 533 case REQ_TIMER_PERIOD:
39236c6e
A
534 ret = sysctl_timer_period( oidp, req );
535 break;
316670eb 536 case REQ_TIMER_PET:
39236c6e
A
537 ret = sysctl_timer_pet( oidp, req );
538 break;
539 case REQ_TIMER_ACTION:
540 ret = sysctl_timer_action( oidp, req );
541 break;
316670eb 542 case REQ_SAMPLING:
39236c6e
A
543 ret = sysctl_sampling( oidp, req );
544 break;
545 case REQ_KDBG_CALLSTACKS:
546 ret = sysctl_kdbg_callstacks( oidp, req );
547 break;
3e170ce0
A
548 case REQ_KDBG_CSWITCH:
549 ret = sysctl_kdbg_cswitch( oidp, req );
550 break;
39236c6e
A
551 case REQ_ACTION_FILTER_BY_TASK:
552 ret = sysctl_action_filter( oidp, req, 1 );
553 break;
554 case REQ_ACTION_FILTER_BY_PID:
555 ret = sysctl_action_filter( oidp, req, 0 );
556 break;
557 case REQ_PET_IDLE_RATE:
558 ret = sysctl_pet_idle_rate( oidp, req );
559 break;
560 case REQ_BLESS_PREEMPT:
561 ret = sysctl_bless_preempt( oidp, req );
562 break;
3e170ce0
A
563 case REQ_CSWITCH_ACTION:
564 ret = sysctl_cswitch_action( oidp, req );
565 break;
566 case REQ_SIGNPOST_ACTION:
567 ret = sysctl_signpost_action( oidp, req );
568 break;
316670eb 569 default:
39236c6e
A
570 ret = ENOENT;
571 break;
572 }
573
574 lck_mtx_unlock(&kperf_cfg_lock);
575
576 return ret;
577}
578
579static int
580kperf_sysctl_bless_handler SYSCTL_HANDLER_ARGS
581{
582 int ret;
583 // __unused struct sysctl_oid *unused_oidp = oidp;
584 (void)arg2;
585
586 if ( !kperf_cfg_initted )
587 panic("kperf_bootstrap not called");
588
589 lck_mtx_lock(&kperf_cfg_lock);
590
591 /* which request */
592 if ( (uintptr_t) arg1 == REQ_BLESS )
593 ret = sysctl_bless( oidp, req );
594 else
595 ret = ENOENT;
596
597 lck_mtx_unlock(&kperf_cfg_lock);
598
599 return ret;
600}
601
39236c6e
A
602/***************************
603 *
604 * Access control
605 *
606 ***************************/
607
608/* Validate whether the current process has priviledges to access
609 * kperf (and by extension, trace). Returns 0 if access is granted.
610 */
611int
612kperf_access_check(void)
613{
614 proc_t p = current_proc();
615 proc_t blessed_p;
616 int ret = 0;
617 boolean_t pid_gone = FALSE;
618
619 /* check if the pid that held the lock is gone */
620 blessed_p = proc_find(blessed_pid);
621
622 if ( blessed_p != NULL )
623 proc_rele(blessed_p);
624 else
625 pid_gone = TRUE;
626
627 if ( blessed_pid == -1 || pid_gone ) {
628 /* check for root */
629 ret = suser(kauth_cred_get(), &p->p_acflag);
630 if( !ret )
631 return ret;
632 }
633
634 /* check against blessed pid */
635 if( p->p_pid != blessed_pid )
636 return EACCES;
637
638 /* access granted. */
639 return 0;
640}
641
642/* specify a pid as being able to access kperf/trace, depiste not
643 * being root
644 */
645int
646kperf_bless_pid(pid_t newpid)
647{
648 proc_t p = NULL;
649 pid_t current_pid;
650
651 p = current_proc();
652 current_pid = p->p_pid;
653
654 /* are we allowed to preempt? */
655 if ( (newpid != -1) && (blessed_pid != -1) &&
656 (blessed_pid != current_pid) && !blessed_preempt ) {
657 /* check if the pid that held the lock is gone */
658 p = proc_find(blessed_pid);
659
660 if ( p != NULL ) {
661 proc_rele(p);
662 return EACCES;
663 }
664 }
665
666 /* validate new pid */
667 if ( newpid != -1 ) {
668 p = proc_find(newpid);
669
670 if ( p == NULL )
671 return EINVAL;
672
673 proc_rele(p);
316670eb 674 }
39236c6e 675
fe8ab488
A
676 /* take trace facility as well */
677 kdbg_swap_global_state_pid(blessed_pid, newpid);
678
39236c6e
A
679 blessed_pid = newpid;
680 blessed_preempt = FALSE;
681
682 return 0;
316670eb
A
683}
684
39236c6e
A
685/***************************
686 *
687 * sysctl hooks
688 *
689 ***************************/
690
316670eb
A
691/* root kperf node */
692SYSCTL_NODE(, OID_AUTO, kperf, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
693 "kperf");
694
695/* action sub-section */
696SYSCTL_NODE(_kperf, OID_AUTO, action, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
697 "action");
698
699SYSCTL_PROC(_kperf_action, OID_AUTO, count,
700 CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
701 (void*)REQ_ACTION_COUNT,
702 sizeof(int), kperf_sysctl, "I", "Number of actions");
703
704SYSCTL_PROC(_kperf_action, OID_AUTO, samplers,
705 CTLFLAG_RW|CTLFLAG_ANYBODY,
706 (void*)REQ_ACTION_SAMPLERS,
707 3*sizeof(uint64_t), kperf_sysctl, "UQ",
708 "What to sample what a trigger fires an action");
709
39236c6e
A
710SYSCTL_PROC(_kperf_action, OID_AUTO, userdata,
711 CTLFLAG_RW|CTLFLAG_ANYBODY,
712 (void*)REQ_ACTION_USERDATA,
713 3*sizeof(uint64_t), kperf_sysctl, "UQ",
714 "User data to attribute to action");
715
716SYSCTL_PROC(_kperf_action, OID_AUTO, filter_by_task,
717 CTLFLAG_RW|CTLFLAG_ANYBODY,
718 (void*)REQ_ACTION_FILTER_BY_TASK,
719 3*sizeof(uint64_t), kperf_sysctl, "UQ",
720 "Apply a task filter to the action");
721
722SYSCTL_PROC(_kperf_action, OID_AUTO, filter_by_pid,
723 CTLFLAG_RW|CTLFLAG_ANYBODY,
724 (void*)REQ_ACTION_FILTER_BY_PID,
725 3*sizeof(uint64_t), kperf_sysctl, "UQ",
726 "Apply a pid filter to the action");
727
316670eb
A
728/* timer sub-section */
729SYSCTL_NODE(_kperf, OID_AUTO, timer, CTLFLAG_RW|CTLFLAG_LOCKED, 0,
730 "timer");
731
732SYSCTL_PROC(_kperf_timer, OID_AUTO, count,
733 CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
734 (void*)REQ_TIMER_COUNT,
735 sizeof(int), kperf_sysctl, "I", "Number of time triggers");
736
737SYSCTL_PROC(_kperf_timer, OID_AUTO, period,
738 CTLFLAG_RW|CTLFLAG_ANYBODY,
739 (void*)REQ_TIMER_PERIOD,
740 2*sizeof(uint64_t), kperf_sysctl, "UQ", "Timer number and period");
741
39236c6e
A
742SYSCTL_PROC(_kperf_timer, OID_AUTO, action,
743 CTLFLAG_RW|CTLFLAG_ANYBODY,
744 (void*)REQ_TIMER_ACTION,
745 2*sizeof(uint64_t), kperf_sysctl, "UQ", "Timer number and actionid");
746
316670eb
A
747SYSCTL_PROC(_kperf_timer, OID_AUTO, pet_timer,
748 CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
749 (void*)REQ_TIMER_PET,
750 sizeof(int), kperf_sysctl, "I", "Which timer ID does PET");
751
752/* misc */
753SYSCTL_PROC(_kperf, OID_AUTO, sampling,
754 CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
755 (void*)REQ_SAMPLING,
756 sizeof(int), kperf_sysctl, "I", "Sampling running");
757
39236c6e
A
758SYSCTL_PROC(_kperf, OID_AUTO, blessed_pid,
759 CTLTYPE_INT|CTLFLAG_RW, /* must be root */
760 (void*)REQ_BLESS,
761 sizeof(int), kperf_sysctl_bless_handler, "I", "Blessed pid");
762
763SYSCTL_PROC(_kperf, OID_AUTO, blessed_preempt,
764 CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
765 (void*)REQ_BLESS_PREEMPT,
766 sizeof(int), kperf_sysctl, "I", "Blessed preemption");
767
39236c6e
A
768SYSCTL_PROC(_kperf, OID_AUTO, kdbg_callstacks,
769 CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
770 (void*)REQ_KDBG_CALLSTACKS,
771 sizeof(int), kperf_sysctl, "I", "Generate kdbg callstacks");
772
3e170ce0
A
773SYSCTL_PROC(_kperf, OID_AUTO, kdbg_cswitch,
774 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY,
775 (void *)REQ_KDBG_CSWITCH,
776 sizeof(int), kperf_sysctl, "I", "Generate context switch info");
39236c6e
A
777
778SYSCTL_PROC(_kperf, OID_AUTO, pet_idle_rate,
779 CTLTYPE_INT|CTLFLAG_RW|CTLFLAG_ANYBODY,
780 (void*)REQ_PET_IDLE_RATE,
781 sizeof(int), kperf_sysctl, "I", "Rate at which unscheduled threads are forced to be sampled in PET mode");
782
3e170ce0
A
783SYSCTL_PROC(_kperf, OID_AUTO, cswitch_action,
784 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY,
785 (void*)REQ_CSWITCH_ACTION,
786 sizeof(int), kperf_sysctl, "I", "ID of action to trigger on context-switch");
787
788SYSCTL_PROC(_kperf, OID_AUTO, signpost_action,
789 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY,
790 (void*)REQ_SIGNPOST_ACTION,
791 sizeof(int), kperf_sysctl, "I", "ID of action to trigger on signposts");
792
39236c6e
A
793/* debug */
794SYSCTL_INT(_kperf, OID_AUTO, debug_level, CTLFLAG_RW,
795 &kperf_debug_level, 0, "debug level");
796