Print this page

        

*** 116,126 **** * - per vnode (entity->vme_vnode_hash) * - per shared amp (entity->vme_amp_hash) * For accurate counting of map-shared and COW-shared pages. * * - visited private anons (refcnt > 1) for each collective. ! * (entity->vme_anon) * For accurate counting of COW-shared pages. * * The common accounting structure is the vmu_entity_t, which represents * collectives: * --- 116,126 ---- * - per vnode (entity->vme_vnode_hash) * - per shared amp (entity->vme_amp_hash) * For accurate counting of map-shared and COW-shared pages. * * - visited private anons (refcnt > 1) for each collective. ! * (entity->vme_anon_hash) * For accurate counting of COW-shared pages. * * The common accounting structure is the vmu_entity_t, which represents * collectives: *
*** 154,164 **** #include <sys/systm.h> #include <sys/var.h> #include <sys/vm_usage.h> #include <sys/zone.h> #include <sys/sunddi.h> - #include <sys/sysmacros.h> #include <sys/avl.h> #include <vm/anon.h> #include <vm/as.h> #include <vm/seg_vn.h> #include <vm/seg_spt.h> --- 154,163 ----
*** 202,219 **** short vmo_type; avl_tree_t vmo_bounds; } vmu_object_t; /* - * Node for tree of visited COW anons. - */ - typedef struct vmu_anon { - avl_node_t vma_node; - uintptr_t vma_addr; - } vmu_anon_t; - - /* * Entity by which to count results. * * The entity structure keeps the current rss/swap counts for each entity * (zone, project, etc), and hashes of vm structures that have already * been visited for the entity. --- 201,210 ----
*** 232,242 **** typedef struct vmu_entity { struct vmu_entity *vme_next; struct vmu_entity *vme_next_calc; mod_hash_t *vme_vnode_hash; /* vnodes visited for entity */ mod_hash_t *vme_amp_hash; /* shared amps visited for entity */ ! avl_tree_t vme_anon; /* COW anons visited for entity */ vmusage_t vme_result; /* identifies entity and results */ } vmu_entity_t; /* * Hash of entities visited within a zone, and an entity for the zone --- 223,233 ---- typedef struct vmu_entity { struct vmu_entity *vme_next; struct vmu_entity *vme_next_calc; mod_hash_t *vme_vnode_hash; /* vnodes visited for entity */ mod_hash_t *vme_amp_hash; /* shared amps visited for entity */ ! mod_hash_t *vme_anon_hash; /* COW anons visited for entity */ vmusage_t vme_result; /* identifies entity and results */ } vmu_entity_t; /* * Hash of entities visited within a zone, and an entity for the zone
*** 335,361 **** return (1); } /* - * Comparison routine for our AVL tree of anon structures. - */ - static int - vmu_anon_cmp(const void *lhs, const void *rhs) - { - const vmu_anon_t *l = lhs, *r = rhs; - - if (l->vma_addr == r->vma_addr) - return (0); - - if (l->vma_addr < r->vma_addr) - return (-1); - - return (1); - } - - /* * Save a bound on the free list. */ static void vmu_free_bound(vmu_bound_t *bound) { --- 326,335 ----
*** 391,413 **** */ static void vmu_free_entity(mod_hash_val_t val) { vmu_entity_t *entity = (vmu_entity_t *)val; - vmu_anon_t *anon; - void *cookie = NULL; if (entity->vme_vnode_hash != NULL) i_mod_hash_clear_nosync(entity->vme_vnode_hash); if (entity->vme_amp_hash != NULL) i_mod_hash_clear_nosync(entity->vme_amp_hash); - while ((anon = avl_destroy_nodes(&entity->vme_anon, &cookie)) != NULL) - kmem_free(anon, sizeof (vmu_anon_t)); - - avl_destroy(&entity->vme_anon); - entity->vme_next = vmu_data.vmu_free_entities; vmu_data.vmu_free_entities = entity; } /* --- 365,382 ---- */ static void vmu_free_entity(mod_hash_val_t val) { vmu_entity_t *entity = (vmu_entity_t *)val; if (entity->vme_vnode_hash != NULL) i_mod_hash_clear_nosync(entity->vme_vnode_hash); if (entity->vme_amp_hash != NULL) i_mod_hash_clear_nosync(entity->vme_amp_hash); + if (entity->vme_anon_hash != NULL) + i_mod_hash_clear_nosync(entity->vme_anon_hash); entity->vme_next = vmu_data.vmu_free_entities; vmu_data.vmu_free_entities = entity; } /*
*** 518,532 **** if (entity->vme_amp_hash == NULL) entity->vme_amp_hash = mod_hash_create_ptrhash( "vmusage amp hash", VMUSAGE_HASH_SIZE, vmu_free_object, sizeof (struct anon_map)); ! VERIFY(avl_first(&entity->vme_anon) == NULL); - avl_create(&entity->vme_anon, vmu_anon_cmp, sizeof (struct vmu_anon), - offsetof(struct vmu_anon, vma_node)); - entity->vme_next = vmu_data.vmu_entities; vmu_data.vmu_entities = entity; vmu_data.vmu_nentities++; return (entity); --- 487,501 ---- if (entity->vme_amp_hash == NULL) entity->vme_amp_hash = mod_hash_create_ptrhash( "vmusage amp hash", VMUSAGE_HASH_SIZE, vmu_free_object, sizeof (struct anon_map)); ! if (entity->vme_anon_hash == NULL) ! entity->vme_anon_hash = mod_hash_create_ptrhash( ! "vmusage anon hash", VMUSAGE_HASH_SIZE, ! mod_hash_null_valdtor, sizeof (struct anon)); entity->vme_next = vmu_data.vmu_entities; vmu_data.vmu_entities = entity; vmu_data.vmu_nentities++; return (entity);
*** 647,669 **** } return (object); } static int ! vmu_find_insert_anon(vmu_entity_t *entity, void *key) { ! vmu_anon_t anon, *ap; ! anon.vma_addr = (uintptr_t)key; ! if (avl_find(&entity->vme_anon, &anon, NULL) != NULL) return (0); ! ap = kmem_alloc(sizeof (vmu_anon_t), KM_SLEEP); ! ap->vma_addr = (uintptr_t)key; ! avl_add(&entity->vme_anon, ap); return (1); } static vmu_entity_t * --- 616,640 ---- } return (object); } static int ! vmu_find_insert_anon(mod_hash_t *hash, caddr_t key) { ! int ret; ! caddr_t val; ! ret = i_mod_hash_find_nosync(hash, (mod_hash_key_t)key, ! (mod_hash_val_t *)&val); ! if (ret == 0) return (0); ! ret = i_mod_hash_insert_nosync(hash, (mod_hash_key_t)key, ! (mod_hash_val_t)key, (mod_hash_hndl_t)0); ! ASSERT(ret == 0); return (1); } static vmu_entity_t *
*** 1371,1381 **** result = &entity->vme_result; /* * Track COW anons per entity so * they are not double counted. */ ! if (vmu_find_insert_anon(entity, ap) == 0) continue; result->vmu_rss_all += (pgcnt << PAGESHIFT); result->vmu_rss_private += (pgcnt << PAGESHIFT); --- 1342,1353 ---- result = &entity->vme_result; /* * Track COW anons per entity so * they are not double counted. */ ! if (vmu_find_insert_anon(entity->vme_anon_hash, ! (caddr_t)ap) == 0) continue; result->vmu_rss_all += (pgcnt << PAGESHIFT); result->vmu_rss_private += (pgcnt << PAGESHIFT);
*** 1645,1655 **** vmu_data.vmu_free_entities->vme_next; if (te->vme_vnode_hash != NULL) mod_hash_destroy_hash(te->vme_vnode_hash); if (te->vme_amp_hash != NULL) mod_hash_destroy_hash(te->vme_amp_hash); ! VERIFY(avl_first(&te->vme_anon) == NULL); kmem_free(te, sizeof (vmu_entity_t)); } while (vmu_data.vmu_free_zones != NULL) { tz = vmu_data.vmu_free_zones; vmu_data.vmu_free_zones = --- 1617,1628 ---- vmu_data.vmu_free_entities->vme_next; if (te->vme_vnode_hash != NULL) mod_hash_destroy_hash(te->vme_vnode_hash); if (te->vme_amp_hash != NULL) mod_hash_destroy_hash(te->vme_amp_hash); ! if (te->vme_anon_hash != NULL) ! mod_hash_destroy_hash(te->vme_anon_hash); kmem_free(te, sizeof (vmu_entity_t)); } while (vmu_data.vmu_free_zones != NULL) { tz = vmu_data.vmu_free_zones; vmu_data.vmu_free_zones =