1*c43cad87SWarner Losh #include "jemalloc/internal/jemalloc_preamble.h" 2*c43cad87SWarner Losh #include "jemalloc/internal/jemalloc_internal_includes.h" 3*c43cad87SWarner Losh 4*c43cad87SWarner Losh /* 5*c43cad87SWarner Losh * This file is logically part of the PA module. While pa.c contains the core 6*c43cad87SWarner Losh * allocator functionality, this file contains boring integration functionality; 7*c43cad87SWarner Losh * things like the pre- and post- fork handlers, and stats merging for CTL 8*c43cad87SWarner Losh * refreshes. 9*c43cad87SWarner Losh */ 10*c43cad87SWarner Losh 11*c43cad87SWarner Losh void 12*c43cad87SWarner Losh pa_shard_prefork0(tsdn_t *tsdn, pa_shard_t *shard) { 13*c43cad87SWarner Losh malloc_mutex_prefork(tsdn, &shard->pac.decay_dirty.mtx); 14*c43cad87SWarner Losh malloc_mutex_prefork(tsdn, &shard->pac.decay_muzzy.mtx); 15*c43cad87SWarner Losh } 16*c43cad87SWarner Losh 17*c43cad87SWarner Losh void 18*c43cad87SWarner Losh pa_shard_prefork2(tsdn_t *tsdn, pa_shard_t *shard) { 19*c43cad87SWarner Losh if (shard->ever_used_hpa) { 20*c43cad87SWarner Losh sec_prefork2(tsdn, &shard->hpa_sec); 21*c43cad87SWarner Losh } 22*c43cad87SWarner Losh } 23*c43cad87SWarner Losh 24*c43cad87SWarner Losh void 25*c43cad87SWarner Losh pa_shard_prefork3(tsdn_t *tsdn, pa_shard_t *shard) { 26*c43cad87SWarner Losh malloc_mutex_prefork(tsdn, &shard->pac.grow_mtx); 27*c43cad87SWarner Losh if (shard->ever_used_hpa) { 28*c43cad87SWarner Losh hpa_shard_prefork3(tsdn, &shard->hpa_shard); 29*c43cad87SWarner Losh } 30*c43cad87SWarner Losh } 31*c43cad87SWarner Losh 32*c43cad87SWarner Losh void 33*c43cad87SWarner Losh pa_shard_prefork4(tsdn_t *tsdn, pa_shard_t *shard) { 34*c43cad87SWarner Losh ecache_prefork(tsdn, &shard->pac.ecache_dirty); 35*c43cad87SWarner Losh ecache_prefork(tsdn, &shard->pac.ecache_muzzy); 36*c43cad87SWarner Losh ecache_prefork(tsdn, &shard->pac.ecache_retained); 37*c43cad87SWarner Losh if (shard->ever_used_hpa) { 38*c43cad87SWarner Losh hpa_shard_prefork4(tsdn, &shard->hpa_shard); 39*c43cad87SWarner Losh } 40*c43cad87SWarner Losh } 41*c43cad87SWarner Losh 42*c43cad87SWarner Losh void 43*c43cad87SWarner Losh pa_shard_prefork5(tsdn_t *tsdn, pa_shard_t *shard) { 44*c43cad87SWarner Losh edata_cache_prefork(tsdn, &shard->edata_cache); 45*c43cad87SWarner Losh } 46*c43cad87SWarner Losh 47*c43cad87SWarner Losh void 48*c43cad87SWarner Losh pa_shard_postfork_parent(tsdn_t *tsdn, pa_shard_t *shard) { 49*c43cad87SWarner Losh edata_cache_postfork_parent(tsdn, &shard->edata_cache); 50*c43cad87SWarner Losh ecache_postfork_parent(tsdn, &shard->pac.ecache_dirty); 51*c43cad87SWarner Losh ecache_postfork_parent(tsdn, &shard->pac.ecache_muzzy); 52*c43cad87SWarner Losh ecache_postfork_parent(tsdn, &shard->pac.ecache_retained); 53*c43cad87SWarner Losh malloc_mutex_postfork_parent(tsdn, &shard->pac.grow_mtx); 54*c43cad87SWarner Losh malloc_mutex_postfork_parent(tsdn, &shard->pac.decay_dirty.mtx); 55*c43cad87SWarner Losh malloc_mutex_postfork_parent(tsdn, &shard->pac.decay_muzzy.mtx); 56*c43cad87SWarner Losh if (shard->ever_used_hpa) { 57*c43cad87SWarner Losh sec_postfork_parent(tsdn, &shard->hpa_sec); 58*c43cad87SWarner Losh hpa_shard_postfork_parent(tsdn, &shard->hpa_shard); 59*c43cad87SWarner Losh } 60*c43cad87SWarner Losh } 61*c43cad87SWarner Losh 62*c43cad87SWarner Losh void 63*c43cad87SWarner Losh pa_shard_postfork_child(tsdn_t *tsdn, pa_shard_t *shard) { 64*c43cad87SWarner Losh edata_cache_postfork_child(tsdn, &shard->edata_cache); 65*c43cad87SWarner Losh ecache_postfork_child(tsdn, &shard->pac.ecache_dirty); 66*c43cad87SWarner Losh ecache_postfork_child(tsdn, &shard->pac.ecache_muzzy); 67*c43cad87SWarner Losh ecache_postfork_child(tsdn, &shard->pac.ecache_retained); 68*c43cad87SWarner Losh malloc_mutex_postfork_child(tsdn, &shard->pac.grow_mtx); 69*c43cad87SWarner Losh malloc_mutex_postfork_child(tsdn, &shard->pac.decay_dirty.mtx); 70*c43cad87SWarner Losh malloc_mutex_postfork_child(tsdn, &shard->pac.decay_muzzy.mtx); 71*c43cad87SWarner Losh if (shard->ever_used_hpa) { 72*c43cad87SWarner Losh sec_postfork_child(tsdn, &shard->hpa_sec); 73*c43cad87SWarner Losh hpa_shard_postfork_child(tsdn, &shard->hpa_shard); 74*c43cad87SWarner Losh } 75*c43cad87SWarner Losh } 76*c43cad87SWarner Losh 77*c43cad87SWarner Losh void 78*c43cad87SWarner Losh pa_shard_basic_stats_merge(pa_shard_t *shard, size_t *nactive, size_t *ndirty, 79*c43cad87SWarner Losh size_t *nmuzzy) { 80*c43cad87SWarner Losh *nactive += atomic_load_zu(&shard->nactive, ATOMIC_RELAXED); 81*c43cad87SWarner Losh *ndirty += ecache_npages_get(&shard->pac.ecache_dirty); 82*c43cad87SWarner Losh *nmuzzy += ecache_npages_get(&shard->pac.ecache_muzzy); 83*c43cad87SWarner Losh } 84*c43cad87SWarner Losh 85*c43cad87SWarner Losh void 86*c43cad87SWarner Losh pa_shard_stats_merge(tsdn_t *tsdn, pa_shard_t *shard, 87*c43cad87SWarner Losh pa_shard_stats_t *pa_shard_stats_out, pac_estats_t *estats_out, 88*c43cad87SWarner Losh hpa_shard_stats_t *hpa_stats_out, sec_stats_t *sec_stats_out, 89*c43cad87SWarner Losh size_t *resident) { 90*c43cad87SWarner Losh cassert(config_stats); 91*c43cad87SWarner Losh 92*c43cad87SWarner Losh pa_shard_stats_out->pac_stats.retained += 93*c43cad87SWarner Losh ecache_npages_get(&shard->pac.ecache_retained) << LG_PAGE; 94*c43cad87SWarner Losh pa_shard_stats_out->edata_avail += atomic_load_zu( 95*c43cad87SWarner Losh &shard->edata_cache.count, ATOMIC_RELAXED); 96*c43cad87SWarner Losh 97*c43cad87SWarner Losh size_t resident_pgs = 0; 98*c43cad87SWarner Losh resident_pgs += atomic_load_zu(&shard->nactive, ATOMIC_RELAXED); 99*c43cad87SWarner Losh resident_pgs += ecache_npages_get(&shard->pac.ecache_dirty); 100*c43cad87SWarner Losh *resident += (resident_pgs << LG_PAGE); 101*c43cad87SWarner Losh 102*c43cad87SWarner Losh /* Dirty decay stats */ 103*c43cad87SWarner Losh locked_inc_u64_unsynchronized( 104*c43cad87SWarner Losh &pa_shard_stats_out->pac_stats.decay_dirty.npurge, 105*c43cad87SWarner Losh locked_read_u64(tsdn, LOCKEDINT_MTX(*shard->stats_mtx), 106*c43cad87SWarner Losh &shard->pac.stats->decay_dirty.npurge)); 107*c43cad87SWarner Losh locked_inc_u64_unsynchronized( 108*c43cad87SWarner Losh &pa_shard_stats_out->pac_stats.decay_dirty.nmadvise, 109*c43cad87SWarner Losh locked_read_u64(tsdn, LOCKEDINT_MTX(*shard->stats_mtx), 110*c43cad87SWarner Losh &shard->pac.stats->decay_dirty.nmadvise)); 111*c43cad87SWarner Losh locked_inc_u64_unsynchronized( 112*c43cad87SWarner Losh &pa_shard_stats_out->pac_stats.decay_dirty.purged, 113*c43cad87SWarner Losh locked_read_u64(tsdn, LOCKEDINT_MTX(*shard->stats_mtx), 114*c43cad87SWarner Losh &shard->pac.stats->decay_dirty.purged)); 115*c43cad87SWarner Losh 116*c43cad87SWarner Losh /* Muzzy decay stats */ 117*c43cad87SWarner Losh locked_inc_u64_unsynchronized( 118*c43cad87SWarner Losh &pa_shard_stats_out->pac_stats.decay_muzzy.npurge, 119*c43cad87SWarner Losh locked_read_u64(tsdn, LOCKEDINT_MTX(*shard->stats_mtx), 120*c43cad87SWarner Losh &shard->pac.stats->decay_muzzy.npurge)); 121*c43cad87SWarner Losh locked_inc_u64_unsynchronized( 122*c43cad87SWarner Losh &pa_shard_stats_out->pac_stats.decay_muzzy.nmadvise, 123*c43cad87SWarner Losh locked_read_u64(tsdn, LOCKEDINT_MTX(*shard->stats_mtx), 124*c43cad87SWarner Losh &shard->pac.stats->decay_muzzy.nmadvise)); 125*c43cad87SWarner Losh locked_inc_u64_unsynchronized( 126*c43cad87SWarner Losh &pa_shard_stats_out->pac_stats.decay_muzzy.purged, 127*c43cad87SWarner Losh locked_read_u64(tsdn, LOCKEDINT_MTX(*shard->stats_mtx), 128*c43cad87SWarner Losh &shard->pac.stats->decay_muzzy.purged)); 129*c43cad87SWarner Losh 130*c43cad87SWarner Losh atomic_load_add_store_zu(&pa_shard_stats_out->pac_stats.abandoned_vm, 131*c43cad87SWarner Losh atomic_load_zu(&shard->pac.stats->abandoned_vm, ATOMIC_RELAXED)); 132*c43cad87SWarner Losh 133*c43cad87SWarner Losh for (pszind_t i = 0; i < SC_NPSIZES; i++) { 134*c43cad87SWarner Losh size_t dirty, muzzy, retained, dirty_bytes, muzzy_bytes, 135*c43cad87SWarner Losh retained_bytes; 136*c43cad87SWarner Losh dirty = ecache_nextents_get(&shard->pac.ecache_dirty, i); 137*c43cad87SWarner Losh muzzy = ecache_nextents_get(&shard->pac.ecache_muzzy, i); 138*c43cad87SWarner Losh retained = ecache_nextents_get(&shard->pac.ecache_retained, i); 139*c43cad87SWarner Losh dirty_bytes = ecache_nbytes_get(&shard->pac.ecache_dirty, i); 140*c43cad87SWarner Losh muzzy_bytes = ecache_nbytes_get(&shard->pac.ecache_muzzy, i); 141*c43cad87SWarner Losh retained_bytes = ecache_nbytes_get(&shard->pac.ecache_retained, 142*c43cad87SWarner Losh i); 143*c43cad87SWarner Losh 144*c43cad87SWarner Losh estats_out[i].ndirty = dirty; 145*c43cad87SWarner Losh estats_out[i].nmuzzy = muzzy; 146*c43cad87SWarner Losh estats_out[i].nretained = retained; 147*c43cad87SWarner Losh estats_out[i].dirty_bytes = dirty_bytes; 148*c43cad87SWarner Losh estats_out[i].muzzy_bytes = muzzy_bytes; 149*c43cad87SWarner Losh estats_out[i].retained_bytes = retained_bytes; 150*c43cad87SWarner Losh } 151*c43cad87SWarner Losh 152*c43cad87SWarner Losh if (shard->ever_used_hpa) { 153*c43cad87SWarner Losh hpa_shard_stats_merge(tsdn, &shard->hpa_shard, hpa_stats_out); 154*c43cad87SWarner Losh sec_stats_merge(tsdn, &shard->hpa_sec, sec_stats_out); 155*c43cad87SWarner Losh } 156*c43cad87SWarner Losh } 157*c43cad87SWarner Losh 158*c43cad87SWarner Losh static void 159*c43cad87SWarner Losh pa_shard_mtx_stats_read_single(tsdn_t *tsdn, mutex_prof_data_t *mutex_prof_data, 160*c43cad87SWarner Losh malloc_mutex_t *mtx, int ind) { 161*c43cad87SWarner Losh malloc_mutex_lock(tsdn, mtx); 162*c43cad87SWarner Losh malloc_mutex_prof_read(tsdn, &mutex_prof_data[ind], mtx); 163*c43cad87SWarner Losh malloc_mutex_unlock(tsdn, mtx); 164*c43cad87SWarner Losh } 165*c43cad87SWarner Losh 166*c43cad87SWarner Losh void 167*c43cad87SWarner Losh pa_shard_mtx_stats_read(tsdn_t *tsdn, pa_shard_t *shard, 168*c43cad87SWarner Losh mutex_prof_data_t mutex_prof_data[mutex_prof_num_arena_mutexes]) { 169*c43cad87SWarner Losh pa_shard_mtx_stats_read_single(tsdn, mutex_prof_data, 170*c43cad87SWarner Losh &shard->edata_cache.mtx, arena_prof_mutex_extent_avail); 171*c43cad87SWarner Losh pa_shard_mtx_stats_read_single(tsdn, mutex_prof_data, 172*c43cad87SWarner Losh &shard->pac.ecache_dirty.mtx, arena_prof_mutex_extents_dirty); 173*c43cad87SWarner Losh pa_shard_mtx_stats_read_single(tsdn, mutex_prof_data, 174*c43cad87SWarner Losh &shard->pac.ecache_muzzy.mtx, arena_prof_mutex_extents_muzzy); 175*c43cad87SWarner Losh pa_shard_mtx_stats_read_single(tsdn, mutex_prof_data, 176*c43cad87SWarner Losh &shard->pac.ecache_retained.mtx, arena_prof_mutex_extents_retained); 177*c43cad87SWarner Losh pa_shard_mtx_stats_read_single(tsdn, mutex_prof_data, 178*c43cad87SWarner Losh &shard->pac.decay_dirty.mtx, arena_prof_mutex_decay_dirty); 179*c43cad87SWarner Losh pa_shard_mtx_stats_read_single(tsdn, mutex_prof_data, 180*c43cad87SWarner Losh &shard->pac.decay_muzzy.mtx, arena_prof_mutex_decay_muzzy); 181*c43cad87SWarner Losh 182*c43cad87SWarner Losh if (shard->ever_used_hpa) { 183*c43cad87SWarner Losh pa_shard_mtx_stats_read_single(tsdn, mutex_prof_data, 184*c43cad87SWarner Losh &shard->hpa_shard.mtx, arena_prof_mutex_hpa_shard); 185*c43cad87SWarner Losh pa_shard_mtx_stats_read_single(tsdn, mutex_prof_data, 186*c43cad87SWarner Losh &shard->hpa_shard.grow_mtx, 187*c43cad87SWarner Losh arena_prof_mutex_hpa_shard_grow); 188*c43cad87SWarner Losh sec_mutex_stats_read(tsdn, &shard->hpa_sec, 189*c43cad87SWarner Losh &mutex_prof_data[arena_prof_mutex_hpa_sec]); 190*c43cad87SWarner Losh } 191*c43cad87SWarner Losh } 192