iommu/io-pgtable-arm: Support lockless operation
commit2c3d273eabe8b1ed3b3cffe2c79643b1bf7e2d4a
authorRobin Murphy <robin.murphy@arm.com>
Thu, 22 Jun 2017 15:53:54 +0000 (22 16:53 +0100)
committerWill Deacon <will.deacon@arm.com>
Fri, 23 Jun 2017 16:58:00 +0000 (23 17:58 +0100)
treee5131a99e7c8e2964d34c7ea3d35894e040465b8
parent81b3c25218447c65f93adf08b099a322b6803536
iommu/io-pgtable-arm: Support lockless operation

For parallel I/O with multiple concurrent threads servicing the same
device (or devices, if several share a domain), serialising page table
updates becomes a massive bottleneck. On reflection, though, we don't
strictly need to do that - for valid IOMMU API usage, there are in fact
only two races that we need to guard against: multiple map requests for
different blocks within the same region, when the intermediate-level
table for that region does not yet exist; and multiple unmaps of
different parts of the same block entry. Both of those are fairly easily
solved by using a cmpxchg to install the new table, such that if we then
find that someone else's table got there first, we can simply free ours
and continue.

Make the requisite changes such that we can withstand being called
without the caller maintaining a lock. In theory, this opens up a few
corners in which wildly misbehaving callers making nonsensical
overlapping requests might lead to crashes instead of just unpredictable
results, but correct code really does not deserve to pay a significant
performance cost for the sake of masking bugs in theoretical broken code.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
drivers/iommu/io-pgtable-arm.c