| Summary: | [libgeom] O(n^2) behavior in geom_stats_resync | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Alan Somers <asomers> |
| Component: | bin | Assignee: | 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 | ||
Fixed by this commit, but I forgot to include the PR tag. https://cgit.freebsd.org/src/commit/?id=ab63da3564e8ab0907f9d8eb565774848ffdadeb Looks like the change was MFCed as well: https://cgit.freebsd.org/src/commit/?id=8cfe6a4729f598d8a65d846a01184f1fabe2ebc7 https://cgit.freebsd.org/src/commit/?id=2d1c164591ff5993cfca4b1190a345e40529593f Can we close this bug? Yep. |
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++; } }