Skip to content

Commit 371b47d

Browse files
committed
io_uring: change io_get_ext_arg() to use uaccess begin + end
In scenarios where a high frequency of wait events are seen, the copy of the struct io_uring_getevents_arg is quite noticeable in the profiles in terms of time spent. It can be seen as up to 3.5-4.5%. Rewrite the copy-in logic, saving about 0.5% of the time. Reviewed-by: Keith Busch <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 0a54a7d commit 371b47d

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

io_uring/io_uring.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3240,6 +3240,7 @@ static int io_validate_ext_arg(unsigned flags, const void __user *argp, size_t a
32403240
static int io_get_ext_arg(unsigned flags, const void __user *argp,
32413241
struct ext_arg *ext_arg)
32423242
{
3243+
const struct io_uring_getevents_arg __user *uarg = argp;
32433244
struct io_uring_getevents_arg arg;
32443245

32453246
/*
@@ -3257,8 +3258,18 @@ static int io_get_ext_arg(unsigned flags, const void __user *argp,
32573258
*/
32583259
if (ext_arg->argsz != sizeof(arg))
32593260
return -EINVAL;
3260-
if (copy_from_user(&arg, argp, sizeof(arg)))
3261+
#ifdef CONFIG_64BIT
3262+
if (!user_access_begin(uarg, sizeof(*uarg)))
32613263
return -EFAULT;
3264+
unsafe_get_user(arg.sigmask, &uarg->sigmask, uaccess_end);
3265+
unsafe_get_user(arg.sigmask_sz, &uarg->sigmask_sz, uaccess_end);
3266+
unsafe_get_user(arg.min_wait_usec, &uarg->min_wait_usec, uaccess_end);
3267+
unsafe_get_user(arg.ts, &uarg->ts, uaccess_end);
3268+
user_access_end();
3269+
#else
3270+
if (copy_from_user(&arg, uarg, sizeof(arg)))
3271+
return -EFAULT;
3272+
#endif
32623273
ext_arg->min_time = arg.min_wait_usec * NSEC_PER_USEC;
32633274
ext_arg->sig = u64_to_user_ptr(arg.sigmask);
32643275
ext_arg->argsz = arg.sigmask_sz;
@@ -3268,6 +3279,11 @@ static int io_get_ext_arg(unsigned flags, const void __user *argp,
32683279
ext_arg->ts_set = true;
32693280
}
32703281
return 0;
3282+
#ifdef CONFIG_64BIT
3283+
uaccess_end:
3284+
user_access_end();
3285+
return -EFAULT;
3286+
#endif
32713287
}
32723288

32733289
SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,

0 commit comments

Comments
 (0)