mm: add account_locked_vm utility function
locked_vm accounting is done roughly the same way in five places, so unify them in a helper. Include the helper's caller in the debug print to distinguish between callsites. Error codes stay the same, so user-visible behavior does too. The one exception is that the -EPERM case in tce_account_locked_vm is removed because Alexey has never seen it triggered. [daniel.m.jordan@oracle.com: v3] Link: http://lkml.kernel.org/r/20190529205019.20927-1-daniel.m.jordan@oracle.com [sfr@canb.auug.org.au: fix mm/util.c] Link: http://lkml.kernel.org/r/20190524175045.26897-1-daniel.m.jordan@oracle.com Signed-off-by: Daniel Jordan <daniel.m.jordan@oracle.com> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Tested-by: Alexey Kardashevskiy <aik@ozlabs.ru> Acked-by: Alex Williamson <alex.williamson@redhat.com> Cc: Alan Tull <atull@kernel.org> Cc: Alex Williamson <alex.williamson@redhat.com> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Christoph Lameter <cl@linux.com> Cc: Christophe Leroy <christophe.leroy@c-s.fr> Cc: Davidlohr Bueso <dave@stgolabs.net> Cc: Jason Gunthorpe <jgg@mellanox.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Moritz Fischer <mdf@kernel.org> Cc: Paul Mackerras <paulus@ozlabs.org> Cc: Steve Sistare <steven.sistare@oracle.com> Cc: Wu Hao <hao.wu@intel.com> Cc: Ira Weiny <ira.weiny@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
此提交包含在:
@@ -19,6 +19,7 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/sched/mm.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/tce.h>
|
||||
@@ -31,51 +32,6 @@
|
||||
static void tce_iommu_detach_group(void *iommu_data,
|
||||
struct iommu_group *iommu_group);
|
||||
|
||||
static long try_increment_locked_vm(struct mm_struct *mm, long npages)
|
||||
{
|
||||
long ret = 0, locked, lock_limit;
|
||||
|
||||
if (WARN_ON_ONCE(!mm))
|
||||
return -EPERM;
|
||||
|
||||
if (!npages)
|
||||
return 0;
|
||||
|
||||
down_write(&mm->mmap_sem);
|
||||
locked = mm->locked_vm + npages;
|
||||
lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
|
||||
if (locked > lock_limit && !capable(CAP_IPC_LOCK))
|
||||
ret = -ENOMEM;
|
||||
else
|
||||
mm->locked_vm += npages;
|
||||
|
||||
pr_debug("[%d] RLIMIT_MEMLOCK +%ld %ld/%ld%s\n", current->pid,
|
||||
npages << PAGE_SHIFT,
|
||||
mm->locked_vm << PAGE_SHIFT,
|
||||
rlimit(RLIMIT_MEMLOCK),
|
||||
ret ? " - exceeded" : "");
|
||||
|
||||
up_write(&mm->mmap_sem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void decrement_locked_vm(struct mm_struct *mm, long npages)
|
||||
{
|
||||
if (!mm || !npages)
|
||||
return;
|
||||
|
||||
down_write(&mm->mmap_sem);
|
||||
if (WARN_ON_ONCE(npages > mm->locked_vm))
|
||||
npages = mm->locked_vm;
|
||||
mm->locked_vm -= npages;
|
||||
pr_debug("[%d] RLIMIT_MEMLOCK -%ld %ld/%ld\n", current->pid,
|
||||
npages << PAGE_SHIFT,
|
||||
mm->locked_vm << PAGE_SHIFT,
|
||||
rlimit(RLIMIT_MEMLOCK));
|
||||
up_write(&mm->mmap_sem);
|
||||
}
|
||||
|
||||
/*
|
||||
* VFIO IOMMU fd for SPAPR_TCE IOMMU implementation
|
||||
*
|
||||
@@ -333,7 +289,7 @@ static int tce_iommu_enable(struct tce_container *container)
|
||||
return ret;
|
||||
|
||||
locked = table_group->tce32_size >> PAGE_SHIFT;
|
||||
ret = try_increment_locked_vm(container->mm, locked);
|
||||
ret = account_locked_vm(container->mm, locked, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -352,7 +308,7 @@ static void tce_iommu_disable(struct tce_container *container)
|
||||
container->enabled = false;
|
||||
|
||||
BUG_ON(!container->mm);
|
||||
decrement_locked_vm(container->mm, container->locked_pages);
|
||||
account_locked_vm(container->mm, container->locked_pages, false);
|
||||
}
|
||||
|
||||
static void *tce_iommu_open(unsigned long arg)
|
||||
@@ -656,7 +612,7 @@ static long tce_iommu_create_table(struct tce_container *container,
|
||||
if (!table_size)
|
||||
return -EINVAL;
|
||||
|
||||
ret = try_increment_locked_vm(container->mm, table_size >> PAGE_SHIFT);
|
||||
ret = account_locked_vm(container->mm, table_size >> PAGE_SHIFT, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -675,7 +631,7 @@ static void tce_iommu_free_table(struct tce_container *container,
|
||||
unsigned long pages = tbl->it_allocated_size >> PAGE_SHIFT;
|
||||
|
||||
iommu_tce_table_put(tbl);
|
||||
decrement_locked_vm(container->mm, pages);
|
||||
account_locked_vm(container->mm, pages, false);
|
||||
}
|
||||
|
||||
static long tce_iommu_create_window(struct tce_container *container,
|
||||
|
@@ -272,21 +272,8 @@ static int vfio_lock_acct(struct vfio_dma *dma, long npage, bool async)
|
||||
|
||||
ret = down_write_killable(&mm->mmap_sem);
|
||||
if (!ret) {
|
||||
if (npage > 0) {
|
||||
if (!dma->lock_cap) {
|
||||
unsigned long limit;
|
||||
|
||||
limit = task_rlimit(dma->task,
|
||||
RLIMIT_MEMLOCK) >> PAGE_SHIFT;
|
||||
|
||||
if (mm->locked_vm + npage > limit)
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
mm->locked_vm += npage;
|
||||
|
||||
ret = __account_locked_vm(mm, abs(npage), npage > 0, dma->task,
|
||||
dma->lock_cap);
|
||||
up_write(&mm->mmap_sem);
|
||||
}
|
||||
|
||||
|
新增問題並參考
封鎖使用者