Skip to content

Commit

Permalink
vfio/type1: Chunk contiguous reserved/invalid page mappings
Browse files Browse the repository at this point in the history
We currently map invalid and reserved pages, such as often occur from
mapping MMIO regions of a VM through the IOMMU, using single pages.
There's really no reason we can't instead follow the methodology we
use for normal pages and find the largest possible physically
contiguous chunk for mapping.  The only difference is that we don't
do locked memory accounting for these since they're not back by RAM.

In most applications this will be a very minor improvement, but when
graphics and GPGPU devices are in play, MMIO BARs become non-trivial.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
  • Loading branch information
Alex Williamson committed Feb 6, 2015
1 parent 6fe1010 commit babbf17
Showing 1 changed file with 11 additions and 7 deletions.
18 changes: 11 additions & 7 deletions drivers/vfio/vfio_iommu_type1.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ static long vfio_pin_pages(unsigned long vaddr, long npage,
unsigned long limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
bool lock_cap = capable(CAP_IPC_LOCK);
long ret, i;
bool rsvd;

if (!current->mm)
return -ENODEV;
Expand All @@ -273,18 +274,18 @@ static long vfio_pin_pages(unsigned long vaddr, long npage,
if (ret)
return ret;

if (is_invalid_reserved_pfn(*pfn_base))
return 1;
rsvd = is_invalid_reserved_pfn(*pfn_base);

if (!lock_cap && current->mm->locked_vm + 1 > limit) {
if (!rsvd && !lock_cap && current->mm->locked_vm + 1 > limit) {
put_pfn(*pfn_base, prot);
pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n", __func__,
limit << PAGE_SHIFT);
return -ENOMEM;
}

if (unlikely(disable_hugepages)) {
vfio_lock_acct(1);
if (!rsvd)
vfio_lock_acct(1);
return 1;
}

Expand All @@ -296,20 +297,23 @@ static long vfio_pin_pages(unsigned long vaddr, long npage,
if (ret)
break;

if (pfn != *pfn_base + i || is_invalid_reserved_pfn(pfn)) {
if (pfn != *pfn_base + i ||
rsvd != is_invalid_reserved_pfn(pfn)) {
put_pfn(pfn, prot);
break;
}

if (!lock_cap && current->mm->locked_vm + i + 1 > limit) {
if (!rsvd && !lock_cap &&
current->mm->locked_vm + i + 1 > limit) {
put_pfn(pfn, prot);
pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n",
__func__, limit << PAGE_SHIFT);
break;
}
}

vfio_lock_acct(i);
if (!rsvd)
vfio_lock_acct(i);

return i;
}
Expand Down

0 comments on commit babbf17

Please sign in to comment.