[Devel] [PATCH RHEL7 COMMIT] ve/aio: Wait for all inflight AIO reqs of a task

Konstantin Khorenko khorenko at virtuozzo.com
Wed May 11 08:08:58 PDT 2016


The commit is pushed to "branch-rh7-3.10.0-327.10.1.vz7.12.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-327.10.1.vz7.12.18
------>
commit 8b78ecbc68f06905b25b19df6eb1b2367cc8649f
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date:   Wed May 11 19:08:58 2016 +0400

    ve/aio: Wait for all inflight AIO reqs of a task
    
    Make it wait all task's AIO contexts instead of a single AIO request.
    This minimizes the number of syscall we do to dump aios.
    
    https://jira.sw.ru/browse/PSBM-42488
    
    Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
    Acked-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 fs/aio.c | 55 ++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/fs/aio.c b/fs/aio.c
index 2de0735..29d02ab 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1862,37 +1862,58 @@ static bool has_reqs_active(struct kioctx *ctx)
 	return !!nr;
 }
 
-static int ve_aio_wait_inflight_reqs(struct kioctx *ioctx)
+static int ve_aio_wait_inflight_reqs(struct task_struct *p)
 {
-	return wait_event_interruptible(ioctx->wait, !has_reqs_active(ioctx));
+	struct mm_struct *mm;
+	struct kioctx *ctx;
+	int ret;
+
+	if (p->flags & PF_KTHREAD)
+		return -EINVAL;
+
+	task_lock(p);
+	mm = p->mm;
+	if (mm)
+		atomic_inc(&mm->mm_count);
+	task_unlock(p);
+	if (!mm)
+		return -ESRCH;
+
+again:
+	spin_lock_irq(&mm->ioctx_lock);
+	hlist_for_each_entry_rcu(ctx, &mm->ioctx_list, list) {
+		if (!has_reqs_active(ctx))
+			continue;
+
+		atomic_inc(&ctx->users);
+		spin_unlock_irq(&mm->ioctx_lock);
+
+		ret = wait_event_interruptible(ctx->wait, !has_reqs_active(ctx));
+		put_ioctx(ctx);
+
+		if (ret)
+			goto mmdrop;
+		goto again;
+	}
+	spin_unlock_irq(&mm->ioctx_lock);
+	ret = 0;
+mmdrop:
+	mmdrop(mm);
+	return ret;
 }
 
 int ve_aio_ioctl(struct task_struct *task, unsigned int cmd, unsigned long arg)
 {
-	struct ve_ioc_arg karg;
-	struct kioctx *ioctx;
 	int ret;
 
-	if (task != current)
-		return -EBADF;
-
-	if (copy_from_user(&karg, (void *)arg, sizeof(karg)))
-		return -EFAULT;
-
-	ioctx = lookup_ioctx(karg.ctx_id);
-	if (!ioctx)
-		return -ESRCH;
-
 	switch (cmd) {
 		case VE_AIO_IOC_WAIT_ACTIVE:
-			ret = ve_aio_wait_inflight_reqs(ioctx);
+			ret = ve_aio_wait_inflight_reqs(task);
 			break;
 		default:
 			ret = -EINVAL;
 	}
 
-	put_ioctx(ioctx);
-
 	return ret;
 }
 #endif


More information about the Devel mailing list