Skip to content

Commit

Permalink
iommu/iova: Try harder to allocate from rcache magazine
Browse files Browse the repository at this point in the history
When devices with different DMA masks are using the same domain, or for
PCI devices where we usually try a speculative 32-bit allocation first,
there is a fair possibility that the top PFN of the rcache stack at any
given time may be unsuitable for the lower limit, prompting a fallback
to allocating anew from the rbtree. Consequently, we may end up
artifically increasing pressure on the 32-bit IOVA space as unused IOVAs
accumulate lower down in the rcache stacks, while callers with 32-bit
masks also impose unnecessary rbtree overhead.

In such cases, let's try a bit harder to satisfy the allocation locally
first - scanning the whole stack should still be relatively inexpensive.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>
  • Loading branch information
Robin Murphy authored and Joerg Roedel committed Sep 28, 2017
1 parent b826ee9 commit e8b1984
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions drivers/iommu/iova.c
Original file line number Diff line number Diff line change
Expand Up @@ -821,12 +821,21 @@ static bool iova_magazine_empty(struct iova_magazine *mag)
static unsigned long iova_magazine_pop(struct iova_magazine *mag,
unsigned long limit_pfn)
{
int i;
unsigned long pfn;

BUG_ON(iova_magazine_empty(mag));

if (mag->pfns[mag->size - 1] > limit_pfn)
return 0;
/* Only fall back to the rbtree if we have no suitable pfns at all */
for (i = mag->size - 1; mag->pfns[i] > limit_pfn; i--)
if (i == 0)
return 0;

/* Swap it to pop it */
pfn = mag->pfns[i];
mag->pfns[i] = mag->pfns[--mag->size];

return mag->pfns[--mag->size];
return pfn;
}

static void iova_magazine_push(struct iova_magazine *mag, unsigned long pfn)
Expand Down

0 comments on commit e8b1984

Please sign in to comment.