Skip to content

Commit b66e65f

Browse files
committed
io_uring: never call io_buffer_select() for a buffer re-select
Callers already have room to store the addr and length information, clean it up by having the caller just assign the previously provided data. Signed-off-by: Jens Axboe <[email protected]>
1 parent 9cfc7e9 commit b66e65f

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

fs/io_uring.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3455,9 +3455,6 @@ static void __user *io_buffer_select(struct io_kiocb *req, size_t *len,
34553455
struct io_ring_ctx *ctx = req->ctx;
34563456
struct io_buffer_list *bl;
34573457

3458-
if (req->flags & REQ_F_BUFFER_SELECTED)
3459-
return u64_to_user_ptr(kbuf->addr);
3460-
34613458
io_ring_submit_lock(req->ctx, issue_flags);
34623459

34633460
bl = io_buffer_get_list(ctx, req->buf_index);
@@ -3497,8 +3494,9 @@ static ssize_t io_compat_import(struct io_kiocb *req, struct iovec *iov,
34973494
buf = io_buffer_select(req, &len, issue_flags);
34983495
if (IS_ERR(buf))
34993496
return PTR_ERR(buf);
3497+
req->rw.addr = (unsigned long) buf;
35003498
iov[0].iov_base = buf;
3501-
iov[0].iov_len = (compat_size_t) len;
3499+
req->rw.len = iov[0].iov_len = (compat_size_t) len;
35023500
return 0;
35033501
}
35043502
#endif
@@ -3519,19 +3517,18 @@ static ssize_t __io_iov_buffer_select(struct io_kiocb *req, struct iovec *iov,
35193517
buf = io_buffer_select(req, &len, issue_flags);
35203518
if (IS_ERR(buf))
35213519
return PTR_ERR(buf);
3520+
req->rw.addr = (unsigned long) buf;
35223521
iov[0].iov_base = buf;
3523-
iov[0].iov_len = len;
3522+
req->rw.len = iov[0].iov_len = len;
35243523
return 0;
35253524
}
35263525

35273526
static ssize_t io_iov_buffer_select(struct io_kiocb *req, struct iovec *iov,
35283527
unsigned int issue_flags)
35293528
{
35303529
if (req->flags & REQ_F_BUFFER_SELECTED) {
3531-
struct io_buffer *kbuf = req->kbuf;
3532-
3533-
iov[0].iov_base = u64_to_user_ptr(kbuf->addr);
3534-
iov[0].iov_len = kbuf->len;
3530+
iov[0].iov_base = u64_to_user_ptr(req->rw.addr);
3531+
iov[0].iov_len = req->rw.len;
35353532
return 0;
35363533
}
35373534
if (req->rw.len != 1)
@@ -3545,6 +3542,13 @@ static ssize_t io_iov_buffer_select(struct io_kiocb *req, struct iovec *iov,
35453542
return __io_iov_buffer_select(req, iov, issue_flags);
35463543
}
35473544

3545+
static inline bool io_do_buffer_select(struct io_kiocb *req)
3546+
{
3547+
if (!(req->flags & REQ_F_BUFFER_SELECT))
3548+
return false;
3549+
return !(req->flags & REQ_F_BUFFER_SELECTED);
3550+
}
3551+
35483552
static struct iovec *__io_import_iovec(int rw, struct io_kiocb *req,
35493553
struct io_rw_state *s,
35503554
unsigned int issue_flags)
@@ -3567,10 +3571,11 @@ static struct iovec *__io_import_iovec(int rw, struct io_kiocb *req,
35673571
sqe_len = req->rw.len;
35683572

35693573
if (opcode == IORING_OP_READ || opcode == IORING_OP_WRITE) {
3570-
if (req->flags & REQ_F_BUFFER_SELECT) {
3574+
if (io_do_buffer_select(req)) {
35713575
buf = io_buffer_select(req, &sqe_len, issue_flags);
35723576
if (IS_ERR(buf))
35733577
return ERR_CAST(buf);
3578+
req->rw.addr = (unsigned long) buf;
35743579
req->rw.len = sqe_len;
35753580
}
35763581

@@ -5555,7 +5560,7 @@ static int io_recvmsg(struct io_kiocb *req, unsigned int issue_flags)
55555560
(sr->flags & IORING_RECVSEND_POLL_FIRST))
55565561
return io_setup_async_msg(req, kmsg);
55575562

5558-
if (req->flags & REQ_F_BUFFER_SELECT) {
5563+
if (io_do_buffer_select(req)) {
55595564
void __user *buf;
55605565

55615566
buf = io_buffer_select(req, &sr->len, issue_flags);
@@ -5619,7 +5624,7 @@ static int io_recv(struct io_kiocb *req, unsigned int issue_flags)
56195624
if (unlikely(!sock))
56205625
return -ENOTSOCK;
56215626

5622-
if (req->flags & REQ_F_BUFFER_SELECT) {
5627+
if (io_do_buffer_select(req)) {
56235628
void __user *buf;
56245629

56255630
buf = io_buffer_select(req, &sr->len, issue_flags);

0 commit comments

Comments
 (0)