|
@@ -821,12 +821,21 @@ static bool iova_magazine_empty(struct iova_magazine *mag)
|
|
static unsigned long iova_magazine_pop(struct iova_magazine *mag,
|
|
static unsigned long iova_magazine_pop(struct iova_magazine *mag,
|
|
unsigned long limit_pfn)
|
|
unsigned long limit_pfn)
|
|
{
|
|
{
|
|
|
|
+ int i;
|
|
|
|
+ unsigned long pfn;
|
|
|
|
+
|
|
BUG_ON(iova_magazine_empty(mag));
|
|
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)
|
|
static void iova_magazine_push(struct iova_magazine *mag, unsigned long pfn)
|