> 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


Reply via email to