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 @@ -351,6 +352,11 @@ return (false); } +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_match_insert(struct iommu_gas_match_args *a) { @@ -366,12 +372,18 @@ */ a->entry->end = a->entry->start + a->size; + counter_u64_add(gas_total, a->domain->entries_cnt); found = iommu_gas_rb_insert(a->domain, a->entry); KASSERT(found, ("found dup %p start %jx size %jx", a->domain, (uintmax_t)a->entry->start, (uintmax_t)a->size)); a->entry->flags = IOMMU_MAP_ENTRY_MAP; } +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"); + static int iommu_gas_lowermatch(struct iommu_gas_match_args *a, struct iommu_map_entry *entry) { @@ -386,6 +398,8 @@ if (entry->first >= a->common->lowaddr) return (ENOMEM); child = RB_RIGHT(entry, rb_entry); + if (child != NULL) + counter_u64_add(gas_lookup, 1); if (child != NULL && 0 == iommu_gas_lowermatch(a, child)) return (0); if (child != NULL && entry->end < a->common->lowaddr && @@ -395,6 +409,8 @@ return (0); } child = RB_LEFT(entry, rb_entry); + if (child != NULL) + counter_u64_add(gas_lookup, 1); if (child != NULL && child->last < a->common->lowaddr && iommu_gas_match_one(a, child->last, entry->start, a->common->lowaddr)) { @@ -420,6 +436,8 @@ if (entry->last < a->common->highaddr) return (ENOMEM); child = RB_LEFT(entry, rb_entry); + if (child != NULL) + counter_u64_add(gas_lookup, 1); if (child != NULL && 0 == iommu_gas_uppermatch(a, child)) return (0); if (child != NULL && child->last >= a->common->highaddr && @@ -429,6 +447,8 @@ return (0); } child = RB_RIGHT(entry, rb_entry); + if (child != NULL) + counter_u64_add(gas_lookup, 1); if (child != NULL && entry->end >= a->common->highaddr && iommu_gas_match_one(a, entry->end, child->first, a->domain->end)) { @@ -460,6 +480,8 @@ a.entry = entry; /* Handle lower region. */ + if (common->lowaddr > 0 ||common->highaddr < domain->end) + counter_u64_add(gas_lookup, 1); if (common->lowaddr > 0) { error = iommu_gas_lowermatch(&a, RB_ROOT(&domain->rb_root)); @@ -791,6 +813,9 @@ { int error; + CTR4(KTR_SPARE5, + "iommu_map: domain %p, entries %u, size %jd, offset %d", + domain, domain->entries_cnt, (uintmax_t)size, offset); error = iommu_gas_map(domain, common, size, offset, eflags, flags, ma, res);