提交 babbf176 编写于 作者: A Alex Williamson

vfio/type1: Chunk contiguous reserved/invalid page mappings

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: NAlex Williamson <alex.williamson@redhat.com>
上级 6fe1010d
...@@ -265,6 +265,7 @@ static long vfio_pin_pages(unsigned long vaddr, long npage, ...@@ -265,6 +265,7 @@ static long vfio_pin_pages(unsigned long vaddr, long npage,
unsigned long limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; unsigned long limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
bool lock_cap = capable(CAP_IPC_LOCK); bool lock_cap = capable(CAP_IPC_LOCK);
long ret, i; long ret, i;
bool rsvd;
if (!current->mm) if (!current->mm)
return -ENODEV; return -ENODEV;
...@@ -273,10 +274,9 @@ static long vfio_pin_pages(unsigned long vaddr, long npage, ...@@ -273,10 +274,9 @@ static long vfio_pin_pages(unsigned long vaddr, long npage,
if (ret) if (ret)
return ret; return ret;
if (is_invalid_reserved_pfn(*pfn_base)) rsvd = is_invalid_reserved_pfn(*pfn_base);
return 1;
if (!lock_cap && current->mm->locked_vm + 1 > limit) { if (!rsvd && !lock_cap && current->mm->locked_vm + 1 > limit) {
put_pfn(*pfn_base, prot); put_pfn(*pfn_base, prot);
pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n", __func__, pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n", __func__,
limit << PAGE_SHIFT); limit << PAGE_SHIFT);
...@@ -284,7 +284,8 @@ static long vfio_pin_pages(unsigned long vaddr, long npage, ...@@ -284,7 +284,8 @@ static long vfio_pin_pages(unsigned long vaddr, long npage,
} }
if (unlikely(disable_hugepages)) { if (unlikely(disable_hugepages)) {
vfio_lock_acct(1); if (!rsvd)
vfio_lock_acct(1);
return 1; return 1;
} }
...@@ -296,12 +297,14 @@ static long vfio_pin_pages(unsigned long vaddr, long npage, ...@@ -296,12 +297,14 @@ static long vfio_pin_pages(unsigned long vaddr, long npage,
if (ret) if (ret)
break; 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); put_pfn(pfn, prot);
break; 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); put_pfn(pfn, prot);
pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n", pr_warn("%s: RLIMIT_MEMLOCK (%ld) exceeded\n",
__func__, limit << PAGE_SHIFT); __func__, limit << PAGE_SHIFT);
...@@ -309,7 +312,8 @@ static long vfio_pin_pages(unsigned long vaddr, long npage, ...@@ -309,7 +312,8 @@ static long vfio_pin_pages(unsigned long vaddr, long npage,
} }
} }
vfio_lock_acct(i); if (!rsvd)
vfio_lock_acct(i);
return i; return i;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册