Index: sys/dev/iommu/iommu_gas.c =================================================================== --- sys/dev/iommu/iommu_gas.c +++ sys/dev/iommu/iommu_gas.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -206,6 +207,11 @@ } #endif +static COUNTER_U64_DEFINE_EARLY(gas_total); +SYSCTL_COUNTER_U64(_hw_iommu, OID_AUTO, gas_total, CTLFLAG_RD, + &gas_total, + "Sum of gas tree sizes"); + static void iommu_gas_rb_remove(struct iommu_domain *domain, struct iommu_map_entry *entry) { @@ -304,6 +310,11 @@ struct iommu_map_entry *entry; }; +static COUNTER_U64_DEFINE_EARLY(gas_lookup); +SYSCTL_COUNTER_U64(_hw_iommu, OID_AUTO, gas_lookup, CTLFLAG_RD, + &gas_lookup, + "Number of gas node accesses"); + /* * The interval [beg, end) is a free interval between two iommu_map_entries. * Addresses can be allocated only in the range [lbound, ubound). Try to @@ -369,6 +380,7 @@ entry->start = start; entry->end = start + roundup2(size + offset, IOMMU_PAGE_SIZE); entry->flags = IOMMU_MAP_ENTRY_MAP; + counter_u64_add(gas_total, a->domain->entries_cnt); return (true); } @@ -381,15 +393,19 @@ if ((next = RB_RIGHT(curr, rb_entry)) != NULL && next->free_down >= min_free) { /* Find next entry in right subtree. */ - do + do { + counter_u64_add(gas_lookup, 1); curr = next; - while ((next = RB_LEFT(curr, rb_entry)) != NULL && + } while ((next = RB_LEFT(curr, rb_entry)) != NULL && next->free_down >= min_free); } else { /* Find next entry in a left-parent ancestor. */ while ((next = RB_PARENT(curr, rb_entry)) != NULL && - curr == RB_RIGHT(next, rb_entry)) + curr == RB_RIGHT(next, rb_entry)) { + counter_u64_add(gas_lookup, 1); curr = next; + } + counter_u64_add(gas_lookup, 1); curr = next; } return (curr); @@ -421,6 +437,7 @@ curr = RB_ROOT(&domain->rb_root); first = NULL; while (curr != NULL && curr->free_down >= min_free) { + counter_u64_add(gas_lookup, 1); first = curr; curr = RB_LEFT(curr, rb_entry); } @@ -458,10 +475,13 @@ * before highaddr that could abut a big-enough range. */ addr = a->common->highaddr; - while (curr != NULL && curr->last < addr) + while (curr != NULL && curr->last < addr) { + counter_u64_add(gas_lookup, 1); curr = RB_PARENT(curr, rb_entry); + } first = NULL; while (curr != NULL && curr->free_down >= min_free) { + counter_u64_add(gas_lookup, 1); if (addr < curr->end) curr = RB_LEFT(curr, rb_entry); else {