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 - 0x40) */ 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 #define TASK_POLICY_WI_DRIVEN IMP_TASK_POLICY_WI_DRIVEN 115 116 #define TASK_POLICY_MAX 0x41 117 118 /* The main entrance to task policy is this function */ 119 extern void proc_set_task_policy(task_t task, int category, int flavor, int value); 120 extern int proc_get_task_policy(task_t task, int category, int flavor); 121 122 extern void proc_set_thread_policy(thread_t thread, int category, int flavor, int value); 123 extern void proc_set_thread_policy_ext(thread_t thread, int category, int flavor, int value, int value2); 124 extern int proc_get_thread_policy(thread_t thread, int category, int flavor); 125 126 /* For use when you don't already hold a reference on the target thread */ 127 extern void proc_set_thread_policy_with_tid(task_t task, uint64_t tid, int category, int flavor, int value); 128 129 130 /* Functions used by kern_resource.c */ 131 extern boolean_t thread_has_qos_policy(thread_t thread); 132 extern kern_return_t thread_remove_qos_policy(thread_t thread); 133 134 extern int proc_darwin_role_to_task_role(int darwin_role, task_role_t* task_role); 135 extern int proc_task_role_to_darwin_role(task_role_t task_role); 136 137 /* Functions used by kern_exec.c */ 138 extern void task_set_main_thread_qos(task_t task, thread_t main_thread); 139 extern void proc_set_task_spawnpolicy(task_t task, thread_t thread, int apptype, int qos_clamp, task_role_t role, 140 ipc_port_t * portwatch_ports, uint32_t portwatch_count); 141 extern void proc_inherit_task_role(task_t new_task, task_t old_task); 142 143 /* IO Throttle tiers */ 144 #define THROTTLE_LEVEL_NONE -1 145 #define THROTTLE_LEVEL_TIER0 0 /* IOPOL_NORMAL, IOPOL_DEFAULT, IOPOL_PASSIVE */ 146 147 #define THROTTLE_LEVEL_THROTTLED 1 148 #define THROTTLE_LEVEL_TIER1 1 /* IOPOL_STANDARD */ 149 #define THROTTLE_LEVEL_TIER2 2 /* IOPOL_UTILITY */ 150 #define THROTTLE_LEVEL_TIER3 3 /* IOPOL_THROTTLE */ 151 152 #define THROTTLE_LEVEL_START 0 153 #define THROTTLE_LEVEL_END 3 154 155 #define THROTTLE_LEVEL_COMPRESSOR_TIER0 THROTTLE_LEVEL_TIER0 156 #define THROTTLE_LEVEL_COMPRESSOR_TIER1 THROTTLE_LEVEL_TIER1 157 #define THROTTLE_LEVEL_COMPRESSOR_TIER2 THROTTLE_LEVEL_TIER2 158 159 #define THROTTLE_LEVEL_PAGEOUT_THROTTLED THROTTLE_LEVEL_TIER2 160 #define THROTTLE_LEVEL_PAGEOUT_UNTHROTTLED THROTTLE_LEVEL_TIER1 161 162 #if CONFIG_IOSCHED 163 #define IOSCHED_METADATA_TIER THROTTLE_LEVEL_TIER1 164 #define IOSCHED_METADATA_EXPEDITED_TIER THROTTLE_LEVEL_TIER0 165 _Static_assert(IOSCHED_METADATA_EXPEDITED_TIER < IOSCHED_METADATA_TIER, 166 "expedited metadata tier must be less than metadata tier"); 167 #endif /* CONFIG_IOSCHED */ 168 169 extern int proc_get_darwinbgstate(task_t task, uint32_t *flagsp); 170 extern int task_get_apptype(task_t); 171 172 #ifdef MACH_BSD 173 extern void proc_apply_task_networkbg(int pid, thread_t thread); 174 #endif /* MACH_BSD */ 175 176 extern void thread_freeze_base_pri(thread_t thread); 177 extern bool thread_unfreeze_base_pri(thread_t thread); 178 179 /* Functions used by pthread_shims.c */ 180 extern int proc_thread_qos_add_override(task_t task, thread_t thread, uint64_t tid, 181 int override_qos, boolean_t first_override_for_resource, 182 user_addr_t resource, int resource_type); 183 extern int proc_thread_qos_remove_override(task_t task, thread_t thread, uint64_t tid, 184 user_addr_t resource, int resource_type); 185 186 extern void thread_reset_workq_qos(thread_t thread, uint32_t qos); 187 extern void thread_set_workq_override(thread_t thread, uint32_t qos); 188 extern void thread_set_workq_pri(thread_t thread, thread_qos_t qos, integer_t priority, integer_t policy); 189 extern uint8_t thread_workq_pri_for_qos(thread_qos_t qos) __pure2; 190 extern thread_qos_t thread_workq_qos_for_pri(int priority); 191 192 extern thread_qos_t 193 task_get_default_manager_qos(task_t task); 194 195 extern void proc_thread_qos_deallocate(thread_t thread); 196 197 extern int task_clear_cpuusage(task_t task, int cpumon_entitled); 198 199 #if CONFIG_TASKWATCH 200 /* Taskwatch related external BSD interface */ 201 extern int proc_lf_pidbind(task_t curtask, uint64_t tid, task_t target_task, int bind); 202 #endif /* CONFIG_TASKWATCH */ 203 204 /* Importance inheritance functions not under IMPORTANCE_INHERITANCE */ 205 extern void task_importance_mark_donor(task_t task, boolean_t donating); 206 extern void task_importance_reset(task_t task); 207 extern void task_importance_init_from_parent(task_t new_task, task_t parent_task); 208 209 #if IMPORTANCE_INHERITANCE 210 extern boolean_t task_is_importance_donor(task_t task); 211 extern boolean_t task_is_importance_receiver_type(task_t task); 212 213 extern int task_importance_hold_file_lock_assertion(task_t target_task, uint32_t count); 214 extern int task_importance_drop_file_lock_assertion(task_t target_task, uint32_t count); 215 216 extern int task_importance_hold_legacy_external_assertion(task_t target_task, uint32_t count); 217 extern int task_importance_drop_legacy_external_assertion(task_t target_task, uint32_t count); 218 #endif /* IMPORTANCE_INHERITANCE */ 219 220 /* Functions used by process_policy.c */ 221 extern boolean_t proc_task_is_tal(task_t task); 222 223 /* Arguments to proc_set_task_ruse_cpu */ 224 #define TASK_POLICY_RESOURCE_ATTRIBUTE_NONE 0x00 225 #define TASK_POLICY_RESOURCE_ATTRIBUTE_THROTTLE 0x01 226 #define TASK_POLICY_RESOURCE_ATTRIBUTE_SUSPEND 0x02 227 #define TASK_POLICY_RESOURCE_ATTRIBUTE_TERMINATE 0x03 228 #define TASK_POLICY_RESOURCE_ATTRIBUTE_NOTIFY_KQ 0x04 229 #define TASK_POLICY_RESOURCE_ATTRIBUTE_NOTIFY_EXC 0x05 230 #define TASK_POLICY_RESOURCE_ATTRIBUTE_DEFAULT TASK_POLICY_RESOURCE_ATTRIBUTE_NONE 231 232 extern int proc_get_task_ruse_cpu(task_t task, uint32_t *policyp, uint8_t *percentagep, 233 uint64_t *intervalp, uint64_t *deadlinep); 234 extern int proc_set_task_ruse_cpu(task_t task, uint16_t policy, uint8_t percentage, 235 uint64_t interval, uint64_t deadline, int cpumon_entitled); 236 extern int task_suspend_cpumon(task_t task); 237 extern int task_resume_cpumon(task_t task); 238 extern int proc_clear_task_ruse_cpu(task_t task, int cpumon_entitled); 239 240 extern int proc_apply_resource_actions(void * p, int type, int action); 241 extern int proc_restore_resource_actions(void * p, int type, int action); 242 243 /* VM/Jetsam importance callouts */ 244 extern int task_low_mem_privileged_listener(task_t task, boolean_t new_value, boolean_t *old_value); 245 extern boolean_t task_has_been_notified(task_t task, int pressurelevel); 246 extern boolean_t task_used_for_purging(task_t task, int pressurelevel); 247 extern void task_mark_has_been_notified(task_t task, int pressurelevel); 248 extern void task_mark_used_for_purging(task_t task, int pressurelevel); 249 extern void task_clear_has_been_notified(task_t task, int pressurelevel); 250 extern void task_clear_used_for_purging(task_t task); 251 extern int task_importance_estimate(task_t task); 252 253 extern kern_return_t thread_policy_set_internal(thread_t thread, thread_policy_flavor_t flavor, 254 thread_policy_t policy_info, mach_msg_type_number_t count); 255 256 extern boolean_t thread_recompute_user_promotion_locked(thread_t thread); 257 extern boolean_t thread_recompute_kernel_promotion_locked(thread_t thread); 258 extern thread_qos_t thread_user_promotion_qos_for_pri(int priority); 259 260 extern void thread_set_exec_promotion(thread_t thread); 261 extern void thread_clear_exec_promotion(thread_t thread); 262 263 /* for servicer override management (workloops only) */ 264 extern void thread_add_servicer_override(thread_t thread, uint32_t qos_override); 265 extern void thread_update_servicer_override(thread_t thread, uint32_t qos_override); 266 extern void thread_drop_servicer_override(thread_t thread); 267 extern void thread_update_servicer_iotier_override(thread_t thread, uint8_t iotier_override); 268 269 /* for generic kevent override management */ 270 extern void thread_add_kevent_override(thread_t thread, uint32_t qos_override); 271 extern void thread_update_kevent_override(thread_t thread, uint32_t qos_override); 272 extern void thread_drop_kevent_override(thread_t thread); 273 274 /* for ipc_pset.c */ 275 extern thread_qos_t thread_get_requested_qos(thread_t thread, int *relpri); 276 277 extern boolean_t task_is_app(task_t task); 278 279 extern const struct thread_requested_policy default_thread_requested_policy; 280 /* 281 ****************************** 282 * Mach-internal functionality 283 ****************************** 284 */ 285 286 #ifdef MACH_KERNEL_PRIVATE 287 288 /* 289 * this exports the internal policy update calls 290 * for IPC importance hooks into task policy 291 */ 292 293 typedef struct task_pend_token { 294 uint32_t tpt_update_sockets :1, 295 tpt_update_timers :1, 296 tpt_update_watchers :1, 297 tpt_update_live_donor :1, 298 tpt_update_coal_sfi :1, 299 tpt_update_throttle :1, 300 tpt_update_thread_sfi :1, 301 tpt_force_recompute_pri :1, 302 tpt_update_tg_ui_flag :1, 303 tpt_update_turnstile :1, 304 tpt_update_tg_app_flag :1, 305 tpt_update_game_mode :1; 306 } *task_pend_token_t; 307 308 extern void task_policy_update_complete_unlocked(task_t task, task_pend_token_t pend_token); 309 extern void task_update_boost_locked(task_t task, boolean_t boost_active, task_pend_token_t pend_token); 310 311 extern void thread_policy_update_locked(thread_t thread, task_pend_token_t pend_token); 312 extern void thread_policy_update_complete_unlocked(thread_t task, task_pend_token_t pend_token); 313 314 typedef struct { 315 int16_t qos_pri[THREAD_QOS_LAST]; 316 int16_t qos_iotier[THREAD_QOS_LAST]; 317 uint32_t qos_through_qos[THREAD_QOS_LAST]; 318 uint32_t qos_latency_qos[THREAD_QOS_LAST]; 319 } qos_policy_params_t; 320 321 extern const qos_policy_params_t thread_qos_policy_params; 322 323 /* for task policy tracepoints */ 324 /* Convenience functions for munging a policy bitfield into a tracepoint */ 325 uintptr_t threquested_0(thread_t thread); 326 uintptr_t threquested_1(thread_t thread); 327 uintptr_t theffective_0(thread_t thread); 328 uintptr_t theffective_1(thread_t thread); 329 extern uint32_t tpending(task_pend_token_t pend_token); 330 331 extern void proc_iopol_to_tier(int iopolicy, int *tier, int *passive); 332 extern int proc_tier_to_iopol(int tier, int passive); 333 334 extern void set_thread_iotier_override(thread_t, int policy); 335 336 extern integer_t task_grab_latency_qos(task_t task); 337 extern void task_policy_create(task_t task, task_t parent_task); 338 extern void thread_policy_create(thread_t thread); 339 340 extern boolean_t task_is_daemon(task_t task); 341 342 #if CONFIG_TASKWATCH 343 /* Taskwatch related external interface */ 344 extern void thead_remove_taskwatch(thread_t thread); 345 extern void task_removewatchers(task_t task); 346 347 typedef struct task_watcher task_watch_t; 348 #endif /* CONFIG_TASKWATCH */ 349 350 #if IMPORTANCE_INHERITANCE 351 extern boolean_t task_is_marked_importance_donor(task_t task); 352 extern boolean_t task_is_marked_importance_receiver(task_t task); 353 354 extern boolean_t task_is_marked_importance_denap_receiver(task_t task); 355 #endif /* IMPORTANCE_INHERITANCE */ 356 357 /* flags for rusage_cpu_flags */ 358 #define TASK_RUSECPU_FLAGS_PROC_LIMIT 0x01 359 #define TASK_RUSECPU_FLAGS_PERTHR_LIMIT 0x02 360 #define TASK_RUSECPU_FLAGS_DEADLINE 0x04 361 #define TASK_RUSECPU_FLAGS_FATAL_CPUMON 0x08 /* CPU usage monitor violations are fatal */ 362 #define TASK_RUSECPU_FLAGS_FATAL_WAKEUPSMON 0x10 /* wakeups monitor violations are fatal */ 363 364 extern void proc_init_cpumon_params(void); 365 366 thread_qos_t task_compute_main_thread_qos(task_t task); 367 368 /* thread policy internals */ 369 extern void thread_policy_reset(thread_t thread); 370 extern kern_return_t thread_set_mode_and_absolute_pri(thread_t thread, integer_t policy, integer_t priority); 371 372 extern void thread_policy_update_tasklocked(thread_t thread, integer_t priority, integer_t max_priority, task_pend_token_t pend_token); 373 374 #include "mach/resource_notify.h" /* from MIG */ 375 376 /*! @function send_resource_violation 377 * @abstract send usage monitor violation notification 378 * 379 * @param violator the task (process) violating its CPU budget 380 * @param ledger_info the entry tracking the resource limit 381 * @param flags see constants for type in sys/reason.h 382 * 383 * @result KERN_SUCCESS if the message was sent 384 * 385 * @discussion 386 * send_resource_violation() calls the corresponding MIG routine 387 * over the host special RESOURCE_NOTIFY port. 388 */ 389 kern_return_t send_resource_violation(typeof(send_cpu_usage_violation), 390 task_t violator, 391 struct ledger_entry_info *ledger_info, 392 resource_notify_flags_t flags); 393 394 /*! @function send_resource_violation_with_fatal_port 395 * @abstract send usage monitor violation notification 396 * 397 * @param sendfunc function pointer of type send_port_space_violation 398 * @param violator the task (process) violating its limits (should be the current task) 399 * @param current_size size of the resource table 400 * @param limit limit set on the size of the resource table 401 * @param fatal_port used to kill the process if it hits the hard limit 402 * @param flags see constants for type in sys/reason.h 403 * 404 * @result KERN_SUCCESS if the message was sent 405 * 406 * @discussion 407 * send_resource_violation_with_fatal_port() calls the corresponding MIG routine 408 * over the host special RESOURCE_NOTIFY port. If fatal_port is set, then deallocating 409 * that port right, will kill the process. 410 * 411 */ 412 kern_return_t send_resource_violation_with_fatal_port(typeof(send_port_space_violation) sendfunc, 413 task_t violator, 414 int64_t current_size, 415 int64_t limit, 416 mach_port_t fatal_port, 417 resource_notify_flags_t flags); 418 419 /*! @function trace_resource_violation 420 * @abstract trace violations on K32/64 421 * 422 * @param code the (K64) DBG_MACH_RESOURCE trace code 423 * @param ledger_info the entry tracking the resource limit 424 * 425 * @discussion 426 * Trace observed usage and corresponding limit on K32 or K64. On 427 * K32, a pair of trace points are used. The low nibble of the K32 428 * trace points must start at double the low nibble of the provided 429 * K64 trace point. For example: 430 #define LOGWRITES_VIOLATED 0x022 431 * ... 432 #define LOGWRITES_VIOLATED_K32A 0x024 433 #define LOGWRITES_VIOLATED_K32B 0x025 434 */ 435 void trace_resource_violation(uint16_t code, 436 struct ledger_entry_info *ledger_info); 437 438 /* 439 * Evaluate criteria for RT_DISALLOWED promotions/demotions and apply them as 440 * necessary. 441 */ 442 extern void thread_rt_evaluate(thread_t thread); 443 444 #endif /* MACH_KERNEL_PRIVATE */ 445 446 #endif /* XNU_KERNEL_PRIVATE */ 447 448 #endif /* _KERN_POLICY_INTERNAL_H_ */ 449