Skip to content

Commit c349b38

Browse files
isilenceXiaoguang Wang
authored andcommitted
io_wq: add per-wq work handler instead of per work
to #28736503 commit f5fa38c upstream 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 <asml.silence@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Xiaoguang Wang <xiaoguang.wang@linux.alibaba.com> Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com>
1 parent efc0728 commit c349b38

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
@@ -113,6 +113,7 @@ struct io_wq {
113113
unsigned long state;
114114

115115
free_work_fn *free_work;
116+
io_wq_work_fn *do_work;
116117

117118
struct task_struct *manager;
118119
struct user_struct *user;
@@ -529,7 +530,7 @@ static void io_worker_handle_work(struct io_worker *worker)
529530

530531
hash = io_get_work_hash(work);
531532
linked = old_work = work;
532-
linked->func(&linked);
533+
wq->do_work(&linked);
533534
linked = (old_work == linked) ? NULL : linked;
534535

535536
work = next_hashed;
@@ -786,7 +787,7 @@ static void io_run_cancel(struct io_wq_work *work, struct io_wqe *wqe)
786787
struct io_wq_work *old_work = work;
787788

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

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

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

10401041
wq->free_work = data->free_work;
1042+
wq->do_work = data->do_work;
10411043

10421044
/* caller must already hold a reference to this */
10431045
wq->user = data->user;
@@ -1094,7 +1096,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)
10941096

10951097
bool io_wq_get(struct io_wq *wq, struct io_wq_data *data)
10961098
{
1097-
if (data->free_work != wq->free_work)
1099+
if (data->free_work != wq->free_work || data->do_work != wq->do_work)
10981100
return false;
10991101

11001102
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
@@ -5695,7 +5695,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
56955695
refcount_set(&req->refs, 2);
56965696
req->task = NULL;
56975697
req->result = 0;
5698-
INIT_IO_WORK(&req->work, io_wq_submit_work);
5698+
INIT_IO_WORK(&req->work);
56995699

57005700
if (unlikely(req->opcode >= IORING_OP_LAST))
57015701
return -EINVAL;
@@ -6695,6 +6695,7 @@ static int io_init_wq_offload(struct io_ring_ctx *ctx,
66956695

66966696
data.user = ctx->user;
66976697
data.free_work = io_free_work;
6698+
data.do_work = io_wq_submit_work;
66986699

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

0 commit comments

Comments
 (0)