Skip to content

Commit

Permalink
io_uring: avoid indirect function calls for the hottest task_work
Browse files Browse the repository at this point in the history
We use task_work for a variety of reasons, but doing completions or
triggering rety after poll are by far the hottest two. Use the indirect
funtion call wrappers to avoid the indirect function call if
CONFIG_RETPOLINE is set.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
axboe committed Jun 2, 2023
1 parent f026be0 commit c92fcfc
Show file tree
Hide file tree
Showing 5 changed files with 12 additions and 4 deletions.
9 changes: 7 additions & 2 deletions io_uring/io_uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@

#include "timeout.h"
#include "poll.h"
#include "rw.h"
#include "alloc_cache.h"

#define IORING_MAX_ENTRIES 32768
Expand Down Expand Up @@ -1205,7 +1206,9 @@ static unsigned int handle_tw_list(struct llist_node *node,
ts->locked = mutex_trylock(&(*ctx)->uring_lock);
percpu_ref_get(&(*ctx)->refs);
}
req->io_task_work.func(req, ts);
INDIRECT_CALL_2(req->io_task_work.func,
io_poll_task_func, io_req_rw_complete,
req, ts);
node = next;
count++;
if (unlikely(need_resched())) {
Expand Down Expand Up @@ -1415,7 +1418,9 @@ static int __io_run_local_work(struct io_ring_ctx *ctx, struct io_tw_state *ts)
struct io_kiocb *req = container_of(node, struct io_kiocb,
io_task_work.node);
prefetch(container_of(next, struct io_kiocb, io_task_work.node));
req->io_task_work.func(req, ts);
INDIRECT_CALL_2(req->io_task_work.func,
io_poll_task_func, io_req_rw_complete,
req, ts);
ret++;
node = next;
}
Expand Down
2 changes: 1 addition & 1 deletion io_uring/poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ static int io_poll_check_events(struct io_kiocb *req, struct io_tw_state *ts)
return IOU_POLL_NO_ACTION;
}

static void io_poll_task_func(struct io_kiocb *req, struct io_tw_state *ts)
void io_poll_task_func(struct io_kiocb *req, struct io_tw_state *ts)
{
int ret;

Expand Down
2 changes: 2 additions & 0 deletions io_uring/poll.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@ bool io_poll_remove_all(struct io_ring_ctx *ctx, struct task_struct *tsk,
bool cancel_all);

void io_apoll_cache_free(struct io_cache_entry *entry);

void io_poll_task_func(struct io_kiocb *req, struct io_tw_state *ts);
2 changes: 1 addition & 1 deletion io_uring/rw.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ static inline int io_fixup_rw_res(struct io_kiocb *req, long res)
return res;
}

static void io_req_rw_complete(struct io_kiocb *req, struct io_tw_state *ts)
void io_req_rw_complete(struct io_kiocb *req, struct io_tw_state *ts)
{
io_req_io_end(req);

Expand Down
1 change: 1 addition & 0 deletions io_uring/rw.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ int io_write(struct io_kiocb *req, unsigned int issue_flags);
int io_writev_prep_async(struct io_kiocb *req);
void io_readv_writev_cleanup(struct io_kiocb *req);
void io_rw_fail(struct io_kiocb *req);
void io_req_rw_complete(struct io_kiocb *req, struct io_tw_state *ts);

0 comments on commit c92fcfc

Please sign in to comment.