X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b0d623f7f2ae71ed96e60569f61f9a9a27016e80..4b17d6b6e417f714551ec129064745ea9919780e:/osfmk/kern/stack.c diff --git a/osfmk/kern/stack.c b/osfmk/kern/stack.c index a59122569..9906b8b3a 100644 --- a/osfmk/kern/stack.c +++ b/osfmk/kern/stack.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,9 @@ static vm_offset_t stack_free_list; static unsigned int stack_free_count, stack_free_hiwat; /* free list count */ static unsigned int stack_hiwat; unsigned int stack_total; /* current total count */ +unsigned long long stack_allocs; /* total count of allocations */ + +static int stack_fake_zone_index = -1; /* index in zone_info array */ static unsigned int stack_free_target; static int stack_free_delta; @@ -76,6 +80,54 @@ vm_offset_t kernel_stack_size = KERNEL_STACK_SIZE; vm_offset_t kernel_stack_mask = -KERNEL_STACK_SIZE; vm_offset_t kernel_stack_depth_max = 0; +static inline void +STACK_ZINFO_PALLOC(thread_t thread) +{ + task_t task; + zinfo_usage_t zinfo; + + ledger_credit(thread->t_ledger, task_ledgers.tkm_private, kernel_stack_size); + + if (stack_fake_zone_index != -1 && + (task = thread->task) != NULL && (zinfo = task->tkm_zinfo) != NULL) + OSAddAtomic64(kernel_stack_size, + (int64_t *)&zinfo[stack_fake_zone_index].alloc); +} + +static inline void +STACK_ZINFO_PFREE(thread_t thread) +{ + task_t task; + zinfo_usage_t zinfo; + + ledger_debit(thread->t_ledger, task_ledgers.tkm_private, kernel_stack_size); + + if (stack_fake_zone_index != -1 && + (task = thread->task) != NULL && (zinfo = task->tkm_zinfo) != NULL) + OSAddAtomic64(kernel_stack_size, + (int64_t *)&zinfo[stack_fake_zone_index].free); +} + +static inline void +STACK_ZINFO_HANDOFF(thread_t from, thread_t to) +{ + ledger_debit(from->t_ledger, task_ledgers.tkm_private, kernel_stack_size); + ledger_credit(to->t_ledger, task_ledgers.tkm_private, kernel_stack_size); + + if (stack_fake_zone_index != -1) { + task_t task; + zinfo_usage_t zinfo; + + if ((task = from->task) != NULL && (zinfo = task->tkm_zinfo) != NULL) + OSAddAtomic64(kernel_stack_size, + (int64_t *)&zinfo[stack_fake_zone_index].free); + + if ((task = to->task) != NULL && (zinfo = task->tkm_zinfo) != NULL) + OSAddAtomic64(kernel_stack_size, + (int64_t *)&zinfo[stack_fake_zone_index].alloc); + } +} + /* * The next field is at the base of the stack, * so the low end is left unsullied. @@ -98,6 +150,9 @@ roundup_pow2(vm_offset_t size) return 1UL << (log2(size - 1) + 1); } +static vm_offset_t stack_alloc_internal(void); +static void stack_free_stack(vm_offset_t); + void stack_init(void) { @@ -125,18 +180,17 @@ stack_init(void) * Allocate a stack for a thread, may * block. */ -void -stack_alloc( - thread_t thread) + +static vm_offset_t +stack_alloc_internal(void) { vm_offset_t stack; spl_t s; int guard_flags; - assert(thread->kernel_stack == 0); - s = splsched(); stack_lock(); + stack_allocs++; stack = stack_free_list; if (stack != 0) { stack_free_list = stack_next(stack); @@ -163,7 +217,7 @@ stack_alloc( if (kernel_memory_allocate(kernel_map, &stack, kernel_stack_size + (2*PAGE_SIZE), stack_addr_mask, - KMA_KOBJECT | guard_flags) + KMA_KSTACK | KMA_KOBJECT | guard_flags) != KERN_SUCCESS) panic("stack_alloc: kernel_memory_allocate"); @@ -174,8 +228,25 @@ stack_alloc( stack += PAGE_SIZE; } + return stack; +} + +void +stack_alloc( + thread_t thread) +{ + + assert(thread->kernel_stack == 0); + machine_stack_attach(thread, stack_alloc_internal()); + STACK_ZINFO_PALLOC(thread); +} - machine_stack_attach(thread, stack); +void +stack_handoff(thread_t from, thread_t to) +{ + assert(from == current_thread()); + machine_stack_handoff(from, to); + STACK_ZINFO_HANDOFF(from, to); } /* @@ -190,11 +261,23 @@ stack_free( vm_offset_t stack = machine_stack_detach(thread); assert(stack); - if (stack != thread->reserved_stack) + if (stack != thread->reserved_stack) { + STACK_ZINFO_PFREE(thread); stack_free_stack(stack); + } } void +stack_free_reserved( + thread_t thread) +{ + if (thread->reserved_stack != thread->kernel_stack) { + stack_free_stack(thread->reserved_stack); + STACK_ZINFO_PFREE(thread); + } +} + +static void stack_free_stack( vm_offset_t stack) { @@ -240,6 +323,7 @@ stack_alloc_try( cache = &PROCESSOR_DATA(current_processor(), stack_cache); stack = cache->free; if (stack != 0) { + STACK_ZINFO_PALLOC(thread); cache->free = stack_next(stack); cache->count--; } @@ -248,6 +332,7 @@ stack_alloc_try( stack_lock(); stack = stack_free_list; if (stack != 0) { + STACK_ZINFO_PALLOC(thread); stack_free_list = stack_next(stack); stack_free_count--; stack_free_delta--; @@ -360,14 +445,23 @@ __unused void *arg) } void -stack_fake_zone_info(int *count, vm_size_t *cur_size, vm_size_t *max_size, vm_size_t *elem_size, - vm_size_t *alloc_size, int *collectable, int *exhaustable) +stack_fake_zone_init(int zone_index) +{ + stack_fake_zone_index = zone_index; +} + +void +stack_fake_zone_info(int *count, + vm_size_t *cur_size, vm_size_t *max_size, vm_size_t *elem_size, vm_size_t *alloc_size, + uint64_t *sum_size, int *collectable, int *exhaustable, int *caller_acct) { unsigned int total, hiwat, free; + unsigned long long all; spl_t s; s = splsched(); stack_lock(); + all = stack_allocs; total = stack_total; hiwat = stack_hiwat; free = stack_free_count; @@ -379,8 +473,11 @@ stack_fake_zone_info(int *count, vm_size_t *cur_size, vm_size_t *max_size, vm_si *max_size = kernel_stack_size * hiwat; *elem_size = kernel_stack_size; *alloc_size = kernel_stack_size; + *sum_size = all * kernel_stack_size; + *collectable = 1; *exhaustable = 0; + *caller_acct = 1; } /* OBSOLETE */