xref: /xnu-11215.41.3/osfmk/kern/policy_internal.h (revision 33de042d024d46de5ff4e89f2471de6608e37fa4)
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