Skip to content

Commit f5fa38c

Browse files
isilenceaxboe
authored andcommitted
io_wq: add per-wq work handler instead of per work
io_uring is the only user of io-wq, and now it uses only io-wq callback for all its requests, namely io_wq_submit_work(). Instead of storing work->runner callback in each instance of io_wq_work, keep it in io-wq itself. pros: - reduces io_wq_work size - more robust -- ->func won't be invalidated with mem{cpy,set}(req) - helps other work Signed-off-by: Pavel Begunkov <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent d4c81f3 commit f5fa38c

File tree

3 files changed

+12
-8
lines changed

3 files changed

+12
-8
lines changed

fs/io-wq.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ struct io_wq {
112112
unsigned long state;
113113

114114
free_work_fn *free_work;
115+
io_wq_work_fn *do_work;
115116

116117
struct task_struct *manager;
117118
struct user_struct *user;
@@ -528,7 +529,7 @@ static void io_worker_handle_work(struct io_worker *worker)
528529

529530
hash = io_get_work_hash(work);
530531
linked = old_work = work;
531-
linked->func(&linked);
532+
wq->do_work(&linked);
532533
linked = (old_work == linked) ? NULL : linked;
533534

534535
work = next_hashed;
@@ -785,7 +786,7 @@ static void io_run_cancel(struct io_wq_work *work, struct io_wqe *wqe)
785786
struct io_wq_work *old_work = work;
786787

787788
work->flags |= IO_WQ_WORK_CANCEL;
788-
work->func(&work);
789+
wq->do_work(&work);
789790
work = (work == old_work) ? NULL : work;
790791
wq->free_work(old_work);
791792
} while (work);
@@ -1023,7 +1024,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
10231024
int ret = -ENOMEM, node;
10241025
struct io_wq *wq;
10251026

1026-
if (WARN_ON_ONCE(!data->free_work))
1027+
if (WARN_ON_ONCE(!data->free_work || !data->do_work))
10271028
return ERR_PTR(-EINVAL);
10281029

10291030
wq = kzalloc(sizeof(*wq), GFP_KERNEL);
@@ -1037,6 +1038,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
10371038
}
10381039

10391040
wq->free_work = data->free_work;
1041+
wq->do_work = data->do_work;
10401042

10411043
/* caller must already hold a reference to this */
10421044
wq->user = data->user;
@@ -1093,7 +1095,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
10931095

10941096
bool io_wq_get(struct io_wq *wq, struct io_wq_data *data)
10951097
{
1096-
if (data->free_work != wq->free_work)
1098+
if (data->free_work != wq->free_work || data->do_work != wq->do_work)
10971099
return false;
10981100

10991101
return refcount_inc_not_zero(&wq->use_refs);

fs/io-wq.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ static inline void wq_list_del(struct io_wq_work_list *list,
8585

8686
struct io_wq_work {
8787
struct io_wq_work_node list;
88-
void (*func)(struct io_wq_work **);
8988
struct files_struct *files;
9089
struct mm_struct *mm;
9190
const struct cred *creds;
@@ -94,9 +93,9 @@ struct io_wq_work {
9493
pid_t task_pid;
9594
};
9695

97-
#define INIT_IO_WORK(work, _func) \
96+
#define INIT_IO_WORK(work) \
9897
do { \
99-
*(work) = (struct io_wq_work){ .func = _func }; \
98+
*(work) = (struct io_wq_work){}; \
10099
} while (0) \
101100

102101
static inline struct io_wq_work *wq_next_work(struct io_wq_work *work)
@@ -108,10 +107,12 @@ static inline struct io_wq_work *wq_next_work(struct io_wq_work *work)
108107
}
109108

110109
typedef void (free_work_fn)(struct io_wq_work *);
110+
typedef void (io_wq_work_fn)(struct io_wq_work **);
111111

112112
struct io_wq_data {
113113
struct user_struct *user;
114114

115+
io_wq_work_fn *do_work;
115116
free_work_fn *free_work;
116117
};
117118

fs/io_uring.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5776,7 +5776,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
57765776
refcount_set(&req->refs, 2);
57775777
req->task = NULL;
57785778
req->result = 0;
5779-
INIT_IO_WORK(&req->work, io_wq_submit_work);
5779+
INIT_IO_WORK(&req->work);
57805780

57815781
if (unlikely(req->opcode >= IORING_OP_LAST))
57825782
return -EINVAL;
@@ -6796,6 +6796,7 @@ static int io_init_wq_offload(struct io_ring_ctx *ctx,
67966796

67976797
data.user = ctx->user;
67986798
data.free_work = io_free_work;
6799+
data.do_work = io_wq_submit_work;
67996800

68006801
if (!(p->flags & IORING_SETUP_ATTACH_WQ)) {
68016802
/* Do QD, or 4 * CPUS, whatever is smallest */

0 commit comments

Comments
 (0)