1 /* 2 * Copyright (c) 2013 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 #ifndef _KERN_COALITION_H_ 30 #define _KERN_COALITION_H_ 31 32 /* only kernel-private interfaces */ 33 #ifdef XNU_KERNEL_PRIVATE 34 #include <mach/coalition.h> 35 #include <kern/thread_group.h> 36 37 __BEGIN_DECLS 38 39 #if CONFIG_COALITIONS 40 41 void coalitions_init(void); 42 43 /* These may return: 44 * KERN_ALREADY_IN_SET task is already in a coalition (maybe this one, maybe a different one) 45 * KERN_TERMINATED coalition is already terminated (so it may not adopt any more tasks) 46 */ 47 kern_return_t coalitions_adopt_task(coalition_t *coaltions, task_t task); 48 kern_return_t coalitions_adopt_init_task(task_t task); 49 kern_return_t coalitions_adopt_corpse_task(task_t task); 50 51 /* Currently, no error conditions. If task is not already in a coalition, 52 * KERN_SUCCESS is returned because removing it did not fail. 53 */ 54 kern_return_t coalitions_remove_task(task_t task); 55 void task_release_coalitions(task_t task); 56 57 /* 58 * 59 */ 60 kern_return_t coalitions_set_roles(coalition_t coalitions[COALITION_NUM_TYPES], 61 task_t task, int roles[COALITION_NUM_TYPES]); 62 63 uint64_t coalition_id(coalition_t coal); 64 void task_coalition_ids(task_t task, uint64_t ids[COALITION_NUM_TYPES]); 65 void task_coalition_roles(task_t task, int roles[COALITION_NUM_TYPES]); 66 int task_coalition_role_for_type(task_t task, int coalition_type); 67 int coalition_type(coalition_t coal); 68 69 coalition_t task_get_coalition(task_t task, int type); 70 71 void task_coalition_update_gpu_stats(task_t task, uint64_t gpu_ns_delta); 72 void coalition_update_ane_stats(coalition_t coalition, uint64_t ane_mach_time, uint64_t ane_energy_nj); 73 boolean_t task_coalition_adjust_focal_count(task_t task, int count, uint32_t *new_count); 74 uint32_t task_coalition_focal_count(task_t task); 75 uint32_t task_coalition_game_mode_count(task_t task); 76 bool task_coalition_adjust_game_mode_count(task_t task, int count, uint32_t *new_count); 77 uint32_t task_coalition_carplay_mode_count(task_t task); 78 bool task_coalition_adjust_carplay_mode_count(task_t task, int count, uint32_t *new_count); 79 boolean_t task_coalition_adjust_nonfocal_count(task_t task, int count, uint32_t *new_count); 80 uint32_t task_coalition_nonfocal_count(task_t task); 81 82 #if CONFIG_THREAD_GROUPS 83 84 /* Thread group lives as long as the task is holding the coalition reference */ 85 struct thread_group *task_coalition_get_thread_group(task_t task); 86 87 /* Donates the thread group reference to the coalition */ 88 void coalition_set_thread_group(coalition_t coal, struct thread_group *tg); 89 struct thread_group *kdp_coalition_get_thread_group(coalition_t coal); 90 91 /* Thread group lives as long as the coalition reference is held */ 92 struct thread_group *coalition_get_thread_group(coalition_t coal); 93 94 void task_coalition_thread_group_focal_update(task_t task); 95 void task_coalition_thread_group_game_mode_update(task_t task); 96 void task_coalition_thread_group_carplay_mode_update(task_t task); 97 void task_coalition_thread_group_application_set(task_t task); 98 #endif /* CONFIG_THREAD_GROUPS */ 99 100 typedef bool (^coalition_for_each_task_block_t)(task_t task); 101 102 void coalition_for_each_task(coalition_t coal, 103 coalition_for_each_task_block_t block); 104 105 /* Coalition ledger */ 106 struct coalition_ledger_indices { 107 int logical_writes; 108 }; 109 void init_coalition_ledgers(void); 110 int coalition_ledger_set_logical_writes_limit(coalition_t coal, int64_t limit); 111 void coalition_io_monitor_ctl(struct coalition *coalition, uint32_t flags, int64_t limit); 112 ledger_t coalition_ledger_get_from_task(task_t task); 113 void coalition_io_rate_exceeded(int warning, const void *param0, __unused const void *param1); 114 void coalition_io_ledger_update(task_t task, int32_t flavor, boolean_t is_credit, uint32_t io_size); 115 /* 116 * Mark this coalition as eligible for swap. 117 * All tasks currently in this coalition will become swap enabled 118 * and new tasks launched into this coalition will be swap enabled. 119 * 120 * Note: 121 * This function can only be called on jetsam coalitions. 122 */ 123 void coalition_mark_swappable(coalition_t coal); 124 /* 125 * Returns true iff the coalition has been marked as swappable. 126 * 127 * Note: 128 * This function can only be called on jetsam coalitions. 129 */ 130 bool coalition_is_swappable(coalition_t coal); 131 132 /* Max limit for coalition logical_writes ledger in MB. Setting to 16 TB */ 133 #define COALITION_MAX_LOGICAL_WRITES_LIMIT ((ledger_amount_t)(1ULL << 24)) 134 /* logical_writes ledger's refill time interval */ 135 #define COALITION_LEDGER_MONITOR_INTERVAL_SECS (24 * 60 * 60) 136 137 138 typedef void (*coalition_iterate_fn_t)(void*, int, coalition_t); 139 kern_return_t coalition_iterate_stackshot(coalition_iterate_fn_t callout, void *arg, uint32_t coalition_type); 140 141 /* Returns with a reference, or COALITION_NULL. 142 * There is no coalition with id 0. 143 */ 144 coalition_t coalition_find_by_id(uint64_t coal_id); 145 146 /* Returns with a reference and an activation, or COALITION_NULL. 147 * There is no coalition with id 0. 148 */ 149 coalition_t coalition_find_and_activate_by_id(uint64_t coal_id); 150 151 void coalition_remove_active(coalition_t coal); 152 153 void coalition_retain(coalition_t coal); 154 155 void coalition_release(coalition_t coal); 156 157 /* 158 * The following functions are to be used by the syscall wrapper 159 * in bsd/kern/kern_proc.c, after it has verified the caller's privilege. 160 */ 161 162 /* This may return: 163 * KERN_DEFAULT_SET The default coalition, which contains the kernel, may 164 * not be terminated. 165 * KERN_TERMINATED The coalition was already reaped. 166 * KERN_FAILURE The coalition was not empty or has never been terminated. 167 */ 168 kern_return_t coalition_reap_internal(coalition_t coal); 169 170 /* This may return: 171 * KERN_DEFAULT_SET The default coalition, which contains the kernel, may 172 * not be terminated. 173 * KERN_TERMINATED The coalition was already terminated (or even reaped) 174 * KERN_INVALID_NAME The coalition was already reaped. 175 */ 176 kern_return_t coalition_request_terminate_internal(coalition_t coal); 177 178 /* This may return: 179 * KERN_RESOURCE_SHORTAGE Unable to allocate kernel resources for a 180 * new coalition. 181 */ 182 kern_return_t coalition_create_internal(int type, int role, boolean_t privileged, boolean_t efficient, coalition_t *out, uint64_t *cid); 183 184 boolean_t coalition_term_requested(coalition_t coal); 185 boolean_t coalition_is_terminated(coalition_t coal); 186 boolean_t coalition_is_reaped(coalition_t coal); 187 boolean_t coalition_is_privileged(coalition_t coal); 188 boolean_t task_is_in_privileged_coalition(task_t task, int type); 189 190 kern_return_t coalition_resource_usage_internal(coalition_t coal, struct coalition_resource_usage *cru_out); 191 192 kern_return_t coalition_debug_info_internal(coalition_t coal, 193 struct coalinfo_debuginfo *c_debuginfo); 194 195 task_t kdp_coalition_get_leader(coalition_t coal); 196 197 kern_return_t jetsam_coalition_set_policy(coalition_t coal, int flavor, int value); 198 kern_return_t jetsam_coalition_get_policy(coalition_t coal, int flavor, int *value); 199 200 201 /* 202 * development/debug interfaces 203 */ 204 #if DEVELOPMENT || DEBUG 205 int coalition_should_notify(coalition_t coal); 206 void coalition_set_notify(coalition_t coal, int notify); 207 #endif 208 209 #else /* !CONFIG_COALITIONS */ 210 211 static inline void 212 task_coalition_update_gpu_stats(__unused task_t task, 213 __unused uint64_t gpu_ns_delta) 214 { 215 return; 216 } 217 218 static inline boolean_t 219 task_coalition_adjust_focal_count(__unused task_t task, 220 __unused int count, 221 __unused uint32_t *new_count) 222 { 223 return FALSE; 224 } 225 226 static inline boolean_t 227 task_coalition_adjust_nonfocal_count(__unused task_t task, 228 __unused int count, 229 __unused uint32_t *new_count) 230 { 231 return FALSE; 232 } 233 234 static inline uint32_t 235 task_coalition_focal_count(__unused task_t task) 236 { 237 return 0; 238 } 239 240 static inline void 241 coalition_for_each_task(__unused coalition_t coal, 242 __unused coalition_for_each_task_block_t callback) 243 { 244 return; 245 } 246 247 static inline void 248 coalition_mark_swappable(__unused coalition_t coal) 249 { 250 return; 251 } 252 253 static inline bool 254 coalition_is_swappable(__unused coalition_t coal) 255 { 256 return false; 257 } 258 259 static inline kern_return_t 260 jetsam_coalition_set_policy(coalition_t coal, int flavor, int value) 261 { 262 return KERN_NOT_SUPPORTED; 263 } 264 265 static inline kern_return_t 266 jetsam_coalition_get_policy(coalition_t coal, int flavor, int *value) 267 { 268 return KERN_NOT_SUPPORTED; 269 } 270 271 272 #endif /* CONFIG_COALITIONS */ 273 274 __END_DECLS 275 276 #endif /* XNU_KERNEL_PRIVATE */ 277 #endif /* _KERN_COALITION_H */ 278