> viommu_replay_mappings() sent every mapping of a domain to the device > with a synchronous request, holding mappings_lock - and with it > interrupts - across the whole walk, so the IRQ-off window grew with the > number of mappings: 233 ms for 8192 4K mappings, 29 s for a million. > > Queue them instead and wait once. One mapping per mappings_lock section, > so that a full virtqueue - the only wait in there - bounds a single lock > hold rather than the whole walk; the walk is a single pass, because the > endpoint was published before it (a mapping inserted while it runs is > queued by map_pages() itself) and a mapping removed meanwhile has its > UNMAP queued in the section that removed it. The requests carry the > device's errno back - the first error it reported - so a rejected replay > fails the attach with the device's own status, and a device that goes > away fails it with -ENODEV rather than reporting a replay that never > happened; a duplicate MAP, which a replay can legitimately produce, is > answered S_INVAL - the spec says a duplicate MAP SHOULD be rejected and > MUST NOT change the existing mapping - and is not treated as a rejection. > A rejected MAP on the map path is still ignored, as before. > > Measured, N=8192 4K mappings: max IRQ-off window 233.7 ms -> 1.4-2.5 ms, > and no longer growing with N (1.4-2.5 ms from N=64 to 32768, against > 3.6/45/233 ms on the unpatched driver); attach ioctl 218.9/249.0 -> > 50.3/48.8 ms (48-67 ms across runs); viommu_send_req_sync() calls 8193 -> > 1; the device receives exactly the same MAPs (8244). > > Signed-off-by: Anlai Lu <[email protected]>
Sashiko has reviewed this patch and found no issues. It looks great! -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=6
