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); } @@ -379,16 +391,19 @@ struct iommu_map_entry *next; if ((next = RB_RIGHT(curr, rb_entry)) != NULL && - next->free_down >= min_free) { + (counter_u64_add(gas_lookup, 1), + next->free_down >= min_free)) { /* Find next entry in right subtree. */ do curr = next; while ((next = RB_LEFT(curr, rb_entry)) != NULL && - next->free_down >= min_free); + (counter_u64_add(gas_lookup, 1), + 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)) + (counter_u64_add(gas_lookup, 1), + curr == RB_RIGHT(next, rb_entry))) curr = next; curr = next; } @@ -420,7 +435,9 @@ domain = a->domain; curr = RB_ROOT(&domain->rb_root); first = NULL; - while (curr != NULL && curr->free_down >= min_free) { + while (curr != NULL && + (counter_u64_add(gas_lookup, 1), + curr->free_down >= min_free)) { first = curr; curr = RB_LEFT(curr, rb_entry); } @@ -458,10 +475,14 @@ * before highaddr that could abut a big-enough range. */ addr = a->common->highaddr; - while (curr != NULL && curr->last < addr) + while (curr != NULL && + (counter_u64_add(gas_lookup, 1), + curr->last < addr)) curr = RB_PARENT(curr, rb_entry); first = NULL; - while (curr != NULL && curr->free_down >= min_free) { + while (curr != NULL && + (counter_u64_add(gas_lookup, 1), + curr->free_down >= min_free)) { if (addr < curr->end) curr = RB_LEFT(curr, rb_entry); else {