1 /* 2 * Copyright (c) 2015-2016 Apple 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 #ifndef _KERN_POLICY_INTERNAL_H_ 30 #define _KERN_POLICY_INTERNAL_H_ 31 32 /* 33 * Interfaces for functionality implemented in task_ or thread_policy subsystem 34 */ 35 36 #ifdef XNU_KERNEL_PRIVATE 37 38 #include <sys/cdefs.h> 39 #include <mach/kern_return.h> 40 #include <kern/kern_types.h> 41 #include <mach/task_policy.h> 42 #include <kern/task.h> 43 #include <kern/ledger.h> 44 #include <sys/kdebug.h> 45 #include <kern/sched_prim.h> 46 /* 47 ****************************** 48 * XNU-internal functionality 49 ****************************** 50 */ 51 52 /* 53 * Get effective policy 54 * Only for use by relevant subsystem, should never be passed into a setter! 55 */ 56 extern int proc_get_effective_task_policy(task_t task, int flavor); 57 extern int proc_get_effective_thread_policy(thread_t thread, int flavor); 58 59 /* Set task 'nice' value */ 60 extern kern_return_t task_importance(task_t task, integer_t importance); 61 62 /* value */ 63 #define TASK_POLICY_DISABLE 0x0 64 #define TASK_POLICY_ENABLE 0x1 65 66 /* category */ 67 #define TASK_POLICY_INTERNAL 0x0 68 #define TASK_POLICY_EXTERNAL 0x1 69 #define TASK_POLICY_ATTRIBUTE 0x2 70 71 /* for tracing */ 72 #define TASK_POLICY_TASK 0x4 73 #define TASK_POLICY_THREAD 0x8 74 75 /* flavors (also DBG_IMPORTANCE subclasses 0x20 - 0x3F) */ 76 77 /* internal or external, thread or task */ 78 #define TASK_POLICY_DARWIN_BG IMP_TASK_POLICY_DARWIN_BG 79 #define TASK_POLICY_IOPOL IMP_TASK_POLICY_IOPOL 80 #define TASK_POLICY_IO IMP_TASK_POLICY_IO 81 #define TASK_POLICY_PASSIVE_IO IMP_TASK_POLICY_PASSIVE_IO 82 83 /* internal, task only */ 84 #define TASK_POLICY_DARWIN_BG_IOPOL IMP_TASK_POLICY_DARWIN_BG_IOPOL 85 86 /* task-only attributes */ 87 /* unused was: IMP_TASK_POLICY_TAL */ 88 #define TASK_POLICY_BOOST IMP_TASK_POLICY_BOOST 89 #define TASK_POLICY_ROLE IMP_TASK_POLICY_ROLE 90 /* unused 0x2B */ 91 #define TASK_POLICY_TERMINATED IMP_TASK_POLICY_TERMINATED 92 #define TASK_POLICY_NEW_SOCKETS_BG IMP_TASK_POLICY_NEW_SOCKETS_BG 93 #define TASK_POLICY_SUP_ACTIVE IMP_TASK_POLICY_SUP_ACTIVE 94 #define TASK_POLICY_LATENCY_QOS IMP_TASK_POLICY_LATENCY_QOS 95 #define TASK_POLICY_THROUGH_QOS IMP_TASK_POLICY_THROUGH_QOS 96 #define TASK_POLICY_WATCHERS_BG IMP_TASK_POLICY_WATCHERS_BG 97 #define TASK_POLICY_SFI_MANAGED IMP_TASK_POLICY_SFI_MANAGED 98 #define TASK_POLICY_ALL_SOCKETS_BG IMP_TASK_POLICY_ALL_SOCKETS_BG 99 100 #define TASK_POLICY_BASE_LATENCY_AND_THROUGHPUT_QOS IMP_TASK_POLICY_BASE_LATENCY_AND_THROUGHPUT_QOS /* latency as value1, throughput as value2 */ 101 #define TASK_POLICY_OVERRIDE_LATENCY_AND_THROUGHPUT_QOS IMP_TASK_POLICY_OVERRIDE_LATENCY_AND_THROUGHPUT_QOS /* latency as value1, throughput as value2 */ 102 103 /* thread-only attributes */ 104 #define TASK_POLICY_PIDBIND_BG IMP_TASK_POLICY_PIDBIND_BG 105 /* unused 0x33 */ 106 #define TASK_POLICY_QOS 0x35 /* Used only as a convenience for getter */ 107 #define TASK_POLICY_QOS_OVERRIDE IMP_TASK_POLICY_QOS_OVERRIDE 108 #define TASK_POLICY_QOS_AND_RELPRIO IMP_TASK_POLICY_QOS_AND_RELPRIO /* QoS as value1, relative priority as value2 */ 109 #define TASK_POLICY_QOS_WORKQ_OVERRIDE IMP_TASK_POLICY_QOS_WORKQ_OVERRIDE 110 #define TASK_POLICY_QOS_PROMOTE IMP_TASK_POLICY_QOS_PROMOTE 111 #define TASK_POLICY_QOS_KEVENT_OVERRIDE IMP_TASK_POLICY_QOS_KEVENT_OVERRIDE 112 #define TASK_POLICY_QOS_SERVICER_OVERRIDE IMP_TASK_POLICY_QOS_SERVICER_OVERRIDE 113 #define TASK_POLICY_IOTIER_KEVENT_OVERRIDE IMP_TASK_POLICY_IOTIER_KEVENT_OVERRIDE 114 115 #define TASK_POLICY_MAX 0x40 116 117 /* The main entrance to task policy is this function */ 118 extern void proc_set_task_policy(task_t task, int category, int flavor, int value); 119 extern int proc_get_task_policy(task_t task, int category, int flavor); 120 121 extern void proc_set_thread_policy(thread_t thread, int category, int flavor, int value); 122 extern int proc_get_thread_policy(thread_t thread, int category, int flavor); 123 124 /* For use when you don't already hold a reference on the target thread */ 125 extern void proc_set_thread_policy_with_tid(task_t task, uint64_t tid, int category, int flavor, int value); 126 127 128 /* Functions used by kern_resource.c */ 129 extern boolean_t thread_has_qos_policy(thread_t thread); 130 extern kern_return_t thread_remove_qos_policy(thread_t thread); 131 132 extern int proc_darwin_role_to_task_role(int darwin_role, task_role_t* task_role); 133 extern int proc_task_role_to_darwin_role(task_role_t task_role); 134 135 /* Functions used by kern_exec.c */ 136 extern void task_set_main_thread_qos(task_t task, thread_t main_thread); 137 extern void proc_set_task_spawnpolicy(task_t task, thread_t thread, int apptype, int qos_clamp, task_role_t role, 138 ipc_port_t * portwatch_ports, uint32_t portwatch_count); 139 extern void proc_inherit_task_role(task_t new_task, task_t old_task); 140 141 /* IO Throttle tiers */ 142 #define THROTTLE_LEVEL_NONE -1 143 #define THROTTLE_LEVEL_TIER0 0 /* IOPOL_NORMAL, IOPOL_DEFAULT, IOPOL_PASSIVE */ 144 145 #define THROTTLE_LEVEL_THROTTLED 1 146 #define THROTTLE_LEVEL_TIER1 1 /* IOPOL_STANDARD */ 147 #define THROTTLE_LEVEL_TIER2 2 /* IOPOL_UTILITY */ 148 #define THROTTLE_LEVEL_TIER3 3 /* IOPOL_THROTTLE */ 149 150 #define THROTTLE_LEVEL_START 0 151 #define THROTTLE_LEVEL_END 3 152 153 #define THROTTLE_LEVEL_COMPRESSOR_TIER0 THROTTLE_LEVEL_TIER0 154 #define THROTTLE_LEVEL_COMPRESSOR_TIER1 THROTTLE_LEVEL_TIER1 155 #define THROTTLE_LEVEL_COMPRESSOR_TIER2 THROTTLE_LEVEL_TIER2 156 157 #define THROTTLE_LEVEL_PAGEOUT_THROTTLED THROTTLE_LEVEL_TIER2 158 #define THROTTLE_LEVEL_PAGEOUT_UNTHROTTLED THROTTLE_LEVEL_TIER1 159 160 #if CONFIG_IOSCHED 161 #define IOSCHED_METADATA_TIER THROTTLE_LEVEL_TIER1 162 #define IOSCHED_METADATA_EXPEDITED_TIER THROTTLE_LEVEL_TIER0 163 _Static_assert(IOSCHED_METADATA_EXPEDITED_TIER < IOSCHED_METADATA_TIER, 164 "expedited metadata tier must be less than metadata tier"); 165 #endif /* CONFIG_IOSCHED */ 166 167 extern int proc_get_darwinbgstate(task_t task, uint32_t *flagsp); 168 extern int task_get_apptype(task_t); 169 170 #ifdef MACH_BSD 171 extern void proc_apply_task_networkbg(int pid, thread_t thread); 172 #endif /* MACH_BSD */ 173 174 extern void thread_freeze_base_pri(thread_t thread); 175 extern bool thread_unfreeze_base_pri(thread_t thread); 176 177 /* Functions used by pthread_shims.c */ 178 extern int proc_thread_qos_add_override(task_t task, thread_t thread, uint64_t tid, 179 int override_qos, boolean_t first_override_for_resource, 180 user_addr_t resource, int resource_type); 181 extern int proc_thread_qos_remove_override(task_t task, thread_t thread, uint64_t tid, 182 user_addr_t resource, int resource_type); 183 184 extern void thread_reset_workq_qos(thread_t thread, uint32_t qos); 185 extern void thread_set_workq_override(thread_t thread, uint32_t qos); 186 extern void thread_set_workq_pri(thread_t thread, thread_qos_t qos, integer_t priority, integer_t policy); 187 extern uint8_t thread_workq_pri_for_qos(thread_qos_t qos) __pure2; 188 extern thread_qos_t thread_workq_qos_for_pri(int priority); 189 190 extern thread_qos_t 191 task_get_default_manager_qos(task_t task); 192 193 extern void proc_thread_qos_deallocate(thread_t thread); 194 195 extern int task_clear_cpuusage(task_t task, int cpumon_entitled); 196 197 #if CONFIG_TASKWATCH 198 /* Taskwatch related external BSD interface */ 199 extern int proc_lf_pidbind(task_t curtask, uint64_t tid, task_t target_task, int bind); 200 #endif /* CONFIG_TASKWATCH */ 201 202 /* Importance inheritance functions not under IMPORTANCE_INHERITANCE */ 203 extern void task_importance_mark_donor(task_t task, boolean_t donating); 204 extern void task_importance_reset(task_t task); 205 extern void task_importance_init_from_parent(task_t new_task, task_t parent_task); 206 207 #if IMPORTANCE_INHERITANCE 208 extern boolean_t task_is_importance_donor(task_t task); 209 extern boolean_t task_is_importance_receiver_type(task_t task); 210 211 extern int task_importance_hold_file_lock_assertion(task_t target_task, uint32_t count); 212 extern int task_importance_drop_file_lock_assertion(task_t target_task, uint32_t count); 213 214 extern int task_importance_hold_legacy_external_assertion(task_t target_task, uint32_t count); 215 extern int task_importance_drop_legacy_external_assertion(task_t target_task, uint32_t count); 216 #endif /* IMPORTANCE_INHERITANCE */ 217 218 /* Functions used by process_policy.c */ 219 extern boolean_t proc_task_is_tal(task_t task); 220 221 /* Arguments to proc_set_task_ruse_cpu */ 222 #define TASK_POLICY_RESOURCE_ATTRIBUTE_NONE 0x00 223 #define TASK_POLICY_RESOURCE_ATTRIBUTE_THROTTLE 0x01 224 #define TASK_POLICY_RESOURCE_ATTRIBUTE_SUSPEND 0x02 225 #define TASK_POLICY_RESOURCE_ATTRIBUTE_TERMINATE 0x03 226 #define TASK_POLICY_RESOURCE_ATTRIBUTE_NOTIFY_KQ 0x04 227 #define TASK_POLICY_RESOURCE_ATTRIBUTE_NOTIFY_EXC 0x05 228 #define TASK_POLICY_RESOURCE_ATTRIBUTE_DEFAULT TASK_POLICY_RESOURCE_ATTRIBUTE_NONE 229 230 extern int proc_get_task_ruse_cpu(task_t task, uint32_t *policyp, uint8_t *percentagep, 231 uint64_t *intervalp, uint64_t *deadlinep); 232 extern int proc_set_task_ruse_cpu(task_t task, uint16_t policy, uint8_t percentage, 233 uint64_t interval, uint64_t deadline, int cpumon_entitled); 234 extern int task_suspend_cpumon(task_t task); 235 extern int task_resume_cpumon(task_t task); 236 extern int proc_clear_task_ruse_cpu(task_t task, int cpumon_entitled); 237 238 extern int proc_apply_resource_actions(void * p, int type, int action); 239 extern int proc_restore_resource_actions(void * p, int type, int action); 240 241 /* VM/Jetsam importance callouts */ 242 extern int task_low_mem_privileged_listener(task_t task, boolean_t new_value, boolean_t *old_value); 243 extern boolean_t task_has_been_notified(task_t task, int pressurelevel); 244 extern boolean_t task_used_for_purging(task_t task, int pressurelevel); 245 extern void task_mark_has_been_notified(task_t task, int pressurelevel); 246 extern void task_mark_used_for_purging(task_t task, int pressurelevel); 247 extern void task_clear_has_been_notified(task_t task, int pressurelevel); 248 extern void task_clear_used_for_purging(task_t task); 249 extern int task_importance_estimate(task_t task); 250 251 extern kern_return_t thread_policy_set_internal(thread_t thread, thread_policy_flavor_t flavor, 252 thread_policy_t policy_info, mach_msg_type_number_t count); 253 254 extern boolean_t thread_recompute_user_promotion_locked(thread_t thread); 255 extern boolean_t thread_recompute_kernel_promotion_locked(thread_t thread); 256 extern thread_qos_t thread_user_promotion_qos_for_pri(int priority); 257 258 extern void thread_set_exec_promotion(thread_t thread); 259 extern void thread_clear_exec_promotion(thread_t thread); 260 261 /* for servicer override management (workloops only) */ 262 extern void thread_add_servicer_override(thread_t thread, uint32_t qos_override); 263 extern void thread_update_servicer_override(thread_t thread, uint32_t qos_override); 264 extern void thread_drop_servicer_override(thread_t thread); 265 extern void thread_update_servicer_iotier_override(thread_t thread, uint8_t iotier_override); 266 267 /* for generic kevent override management */ 268 extern void thread_add_kevent_override(thread_t thread, uint32_t qos_override); 269 extern void thread_update_kevent_override(thread_t thread, uint32_t qos_override); 270 extern void thread_drop_kevent_override(thread_t thread); 271 272 /* for ipc_pset.c */ 273 extern thread_qos_t thread_get_requested_qos(thread_t thread, int *relpri); 274 275 extern boolean_t task_is_app(task_t task); 276 277 extern const struct thread_requested_policy default_thread_requested_policy; 278 /* 279 ****************************** 280 * Mach-internal functionality 281 ****************************** 282 */ 283 284 #ifdef MACH_KERNEL_PRIVATE 285 286 /* 287 * this exports the internal policy update calls 288 * for IPC importance hooks into task policy 289 */ 290 291 typedef struct task_pend_token { 292 uint32_t tpt_update_sockets :1, 293 tpt_update_timers :1, 294 tpt_update_watchers :1, 295 tpt_update_live_donor :1, 296 tpt_update_coal_sfi :1, 297 tpt_update_throttle :1, 298 tpt_update_thread_sfi :1, 299 tpt_force_recompute_pri :1, 300 tpt_update_tg_ui_flag :1, 301 tpt_update_turnstile :1; 302 } *task_pend_token_t; 303 304 extern void task_policy_update_complete_unlocked(task_t task, task_pend_token_t pend_token); 305 extern void task_update_boost_locked(task_t task, boolean_t boost_active, task_pend_token_t pend_token); 306 307 extern void thread_policy_update_locked(thread_t thread, task_pend_token_t pend_token); 308 extern void thread_policy_update_complete_unlocked(thread_t task, task_pend_token_t pend_token); 309 310 typedef struct { 311 int16_t qos_pri[THREAD_QOS_LAST]; 312 int16_t qos_iotier[THREAD_QOS_LAST]; 313 uint32_t qos_through_qos[THREAD_QOS_LAST]; 314 uint32_t qos_latency_qos[THREAD_QOS_LAST]; 315 } qos_policy_params_t; 316 317 extern const qos_policy_params_t thread_qos_policy_params; 318 319 /* for task policy tracepoints */ 320 /* Convenience functions for munging a policy bitfield into a tracepoint */ 321 uintptr_t threquested_0(thread_t thread); 322 uintptr_t threquested_1(thread_t thread); 323 uintptr_t theffective_0(thread_t thread); 324 uintptr_t theffective_1(thread_t thread); 325 extern uint32_t tpending(task_pend_token_t pend_token); 326 327 extern void proc_iopol_to_tier(int iopolicy, int *tier, int *passive); 328 extern int proc_tier_to_iopol(int tier, int passive); 329 330 extern void set_thread_iotier_override(thread_t, int policy); 331 332 extern integer_t task_grab_latency_qos(task_t task); 333 extern void task_policy_create(task_t task, task_t parent_task); 334 extern void thread_policy_create(thread_t thread); 335 336 extern boolean_t task_is_daemon(task_t task); 337 338 #if CONFIG_TASKWATCH 339 /* Taskwatch related external interface */ 340 extern void thead_remove_taskwatch(thread_t thread); 341 extern void task_removewatchers(task_t task); 342 343 typedef struct task_watcher task_watch_t; 344 #endif /* CONFIG_TASKWATCH */ 345 346 #if IMPORTANCE_INHERITANCE 347 extern boolean_t task_is_marked_importance_donor(task_t task); 348 extern boolean_t task_is_marked_importance_receiver(task_t task); 349 350 extern boolean_t task_is_marked_importance_denap_receiver(task_t task); 351 #endif /* IMPORTANCE_INHERITANCE */ 352 353 /* flags for rusage_cpu_flags */ 354 #define TASK_RUSECPU_FLAGS_PROC_LIMIT 0x01 355 #define TASK_RUSECPU_FLAGS_PERTHR_LIMIT 0x02 356 #define TASK_RUSECPU_FLAGS_DEADLINE 0x04 357 #define TASK_RUSECPU_FLAGS_FATAL_CPUMON 0x08 /* CPU usage monitor violations are fatal */ 358 #define TASK_RUSECPU_FLAGS_FATAL_WAKEUPSMON 0x10 /* wakeups monitor violations are fatal */ 359 360 extern void proc_init_cpumon_params(void); 361 362 thread_qos_t task_compute_main_thread_qos(task_t task); 363 364 /* thread policy internals */ 365 extern void thread_policy_reset(thread_t thread); 366 extern kern_return_t thread_set_mode_and_absolute_pri(thread_t thread, integer_t policy, integer_t priority); 367 368 extern void thread_policy_update_tasklocked(thread_t thread, integer_t priority, integer_t max_priority, task_pend_token_t pend_token); 369 370 #include "mach/resource_notify.h" /* from MIG */ 371 372 /*! @function send_resource_violation 373 * @abstract send usage monitor violation notification 374 * 375 * @param violator the task (process) violating its CPU budget 376 * @param ledger_info the entry tracking the resource limit 377 * @param flags see constants for type in sys/reason.h 378 * 379 * @result KERN_SUCCESS if the message was sent 380 * 381 * @discussion 382 * send_resource_violation() calls the corresponding MIG routine 383 * over the host special RESOURCE_NOTIFY port. 384 */ 385 kern_return_t send_resource_violation(typeof(send_cpu_usage_violation), 386 task_t violator, 387 struct ledger_entry_info *ledger_info, 388 resource_notify_flags_t flags); 389 390 /*! @function send_resource_violation_with_fatal_port 391 * @abstract send usage monitor violation notification 392 * 393 * @param sendfunc function pointer of type send_port_space_violation 394 * @param violator the task (process) violating its limits (should be the current task) 395 * @param current_size size of the resource table 396 * @param limit limit set on the size of the resource table 397 * @param fatal_port used to kill the process if it hits the hard limit 398 * @param flags see constants for type in sys/reason.h 399 * 400 * @result KERN_SUCCESS if the message was sent 401 * 402 * @discussion 403 * send_resource_violation_with_fatal_port() calls the corresponding MIG routine 404 * over the host special RESOURCE_NOTIFY port. If port is set, then deallocating 405 * that port right, will kill the process. 406 * 407 */ 408 kern_return_t send_resource_violation_with_fatal_port(typeof(send_port_space_violation) sendfunc, 409 task_t violator, 410 int64_t current_size, 411 int64_t limit, 412 mach_port_t fatal_port, 413 resource_notify_flags_t flags); 414 415 /*! @function trace_resource_violation 416 * @abstract trace violations on K32/64 417 * 418 * @param code the (K64) DBG_MACH_RESOURCE trace code 419 * @param ledger_info the entry tracking the resource limit 420 * 421 * @discussion 422 * Trace observed usage and corresponding limit on K32 or K64. On 423 * K32, a pair of trace points are used. The low nibble of the K32 424 * trace points must start at double the low nibble of the provided 425 * K64 trace point. For example: 426 #define LOGWRITES_VIOLATED 0x022 427 * ... 428 #define LOGWRITES_VIOLATED_K32A 0x024 429 #define LOGWRITES_VIOLATED_K32B 0x025 430 */ 431 void trace_resource_violation(uint16_t code, 432 struct ledger_entry_info *ledger_info); 433 434 #endif /* MACH_KERNEL_PRIVATE */ 435 436 #endif /* XNU_KERNEL_PRIVATE */ 437 438 #endif /* _KERN_POLICY_INTERNAL_H_ */ 439