Bug 253877

Summary: [libgeom] O(n^2) behavior in geom_stats_resync
Product: Base System Reporter: Alan Somers <asomers>
Component: binAssignee: Alan Somers <asomers>
Status: Closed FIXED    
Severity: Affects Many People CC: emaste, markj
Priority: --- Flags: asomers: mfc-stable13+
asomers: mfc-stable12+
Version: CURRENT   
Hardware: Any   
OS: Any   

Description Alan Somers freebsd_committer freebsd_triage 2021-02-26 17:33:31 UTC
geom_stats_resync tries to mmap all of /dev/devstat.  But without knowing that device's size, it simply tries to mmap successively larger amounts of memory until it fails.  That means that the entire operation has O(n^2) syscalls, where n is related to the number of geom providers.  On a system with a few thousand providers, running "mdconfig -l" can take several minutes.

void
geom_stats_resync(void)
{
        void *p;

        if (statsfd == -1)
                return;
        for (;;) {
                p = mmap(statp, (npages + 1) * pagesize,
                    PROT_READ, MAP_SHARED, statsfd, 0);
                if (p == MAP_FAILED)
                        break;
                else
                        statp = p;
                npages++;
        }
}
Comment 1 Alan Somers freebsd_committer freebsd_triage 2021-03-04 00:36:37 UTC
Fixed by this commit, but I forgot to include the PR tag.
https://cgit.freebsd.org/src/commit/?id=ab63da3564e8ab0907f9d8eb565774848ffdadeb
Comment 3 Alan Somers freebsd_committer freebsd_triage 2021-06-16 15:38:01 UTC
Yep.