Thread (14 messages) 14 messages, 6 authors, 2019-06-03

Re: [PATCH] mm: add account_locked_vm utility function

From: Daniel Jordan <daniel.m.jordan@oracle.com>
Date: 2019-05-20 15:31:38
Also in: kvm, linux-fpga, linux-mm, lkml

On Mon, May 20, 2019 at 04:19:34PM +1000, Alexey Kardashevskiy wrote:
On 04/05/2019 06:16, Daniel Jordan wrote:
quoted
locked_vm accounting is done roughly the same way in five places, so
unify them in a helper.  Standardize the debug prints, which vary
slightly.
And I rather liked that prints were different and tell precisely which
one of three each printk is.
I'm not following.  One of three...callsites?  But there were five callsites.

Anyway, I added a _RET_IP_ to the debug print so you can differentiate.
I commented below but in general this seems working.

Tested-by: Alexey Kardashevskiy <redacted>
Thanks!  And for the review as well.
quoted
diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
index 6b64e45a5269..d39a1b830d82 100644
--- a/drivers/vfio/vfio_iommu_spapr_tce.c
+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
@@ -34,49 +35,13 @@
 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)
+static int tce_account_locked_vm(struct mm_struct *mm, unsigned long npages,
+				 bool inc)
 {
-	long ret = 0, locked, lock_limit;
-
 	if (WARN_ON_ONCE(!mm))
 		return -EPERM;

If this WARN_ON is the only reason for having tce_account_locked_vm()
instead of calling account_locked_vm() directly, you can then ditch the
check as I have never ever seen this triggered.
Great, will do.
quoted
diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index d0f731c9920a..15ac76171ccd 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -273,25 +273,14 @@ static int vfio_lock_acct(struct vfio_dma *dma, long npage, bool async)
 		return -ESRCH; /* process exited */
 
 	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)
+		goto out;

A single "goto" to jump just 3 lines below seems unnecessary.
No strong preference here, I'll take out the goto.
quoted
+int __account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc,
+			struct task_struct *task, bool bypass_rlim)
+{
+	unsigned long locked_vm, limit;
+	int ret = 0;
+
+	locked_vm = mm->locked_vm;
+	if (inc) {
+		if (!bypass_rlim) {
+			limit = task_rlimit(task, RLIMIT_MEMLOCK) >> PAGE_SHIFT;
+			if (locked_vm + pages > limit) {
+				ret = -ENOMEM;
+				goto out;
+			}
+		}
Nit:

if (!ret)

and then you don't need "goto out".
Ok, sure.
quoted
+		mm->locked_vm = locked_vm + pages;
+	} else {
+		WARN_ON_ONCE(pages > locked_vm);
+		mm->locked_vm = locked_vm - pages;

Can go negative here. Not a huge deal but inaccurate imo.
I hear you, but setting a negative value to zero, as we had done previously,
doesn't make much sense to me.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help