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