Skip to content

Commit 6030f93

Browse files
committed
Merge branch 'for-7.1/io_uring-fuse' into for-next
* for-7.1/io_uring-fuse: io_uring/rsrc: rename and export IO_IMU_DEST / IO_IMU_SOURCE io_uring/rsrc: add io_buffer_register_bvec() io_uring/rsrc: split io_buffer_register_request() logic io_uring/rsrc: rename io_buffer_register_bvec()/io_buffer_unregister_bvec()
2 parents 5d77540 + b09efad commit 6030f93

7 files changed

Lines changed: 146 additions & 67 deletions

File tree

Documentation/block/ublk.rst

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -382,17 +382,17 @@ Zero copy
382382
---------
383383

384384
ublk zero copy relies on io_uring's fixed kernel buffer, which provides
385-
two APIs: `io_buffer_register_bvec()` and `io_buffer_unregister_bvec`.
385+
two APIs: `io_buffer_register_request()` and `io_buffer_unregister`.
386386

387387
ublk adds IO command of `UBLK_IO_REGISTER_IO_BUF` to call
388-
`io_buffer_register_bvec()` for ublk server to register client request
388+
`io_buffer_register_request()` for ublk server to register client request
389389
buffer into io_uring buffer table, then ublk server can submit io_uring
390390
IOs with the registered buffer index. IO command of `UBLK_IO_UNREGISTER_IO_BUF`
391-
calls `io_buffer_unregister_bvec()` to unregister the buffer, which is
392-
guaranteed to be live between calling `io_buffer_register_bvec()` and
393-
`io_buffer_unregister_bvec()`. Any io_uring operation which supports this
394-
kind of kernel buffer will grab one reference of the buffer until the
395-
operation is completed.
391+
calls `io_buffer_unregister()` to unregister the buffer, which is guaranteed
392+
to be live between calling `io_buffer_register_request()` and
393+
`io_buffer_unregister()`. Any io_uring operation which supports this kind of
394+
kernel buffer will grab one reference of the buffer until the operation is
395+
completed.
396396

397397
ublk server implementing zero copy or user copy has to be CAP_SYS_ADMIN and
398398
be trusted, because it is ublk server's responsibility to make sure IO buffer

drivers/block/ublk_drv.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,8 +1627,8 @@ ublk_auto_buf_register(const struct ublk_queue *ubq, struct request *req,
16271627
{
16281628
int ret;
16291629

1630-
ret = io_buffer_register_bvec(cmd, req, ublk_io_release,
1631-
io->buf.auto_reg.index, issue_flags);
1630+
ret = io_buffer_register_request(cmd, req, ublk_io_release,
1631+
io->buf.auto_reg.index, issue_flags);
16321632
if (ret) {
16331633
if (io->buf.auto_reg.flags & UBLK_AUTO_BUF_REG_FALLBACK) {
16341634
ublk_auto_buf_reg_fallback(ubq, req->tag);
@@ -1828,7 +1828,7 @@ static noinline void ublk_batch_dispatch_fail(struct ublk_queue *ubq,
18281828
ublk_io_unlock(io);
18291829

18301830
if (index != -1)
1831-
io_buffer_unregister_bvec(data->cmd, index,
1831+
io_buffer_unregister(data->cmd, index,
18321832
data->issue_flags);
18331833
}
18341834

@@ -3097,8 +3097,8 @@ static int ublk_register_io_buf(struct io_uring_cmd *cmd,
30973097
if (!req)
30983098
return -EINVAL;
30993099

3100-
ret = io_buffer_register_bvec(cmd, req, ublk_io_release, index,
3101-
issue_flags);
3100+
ret = io_buffer_register_request(cmd, req, ublk_io_release, index,
3101+
issue_flags);
31023102
if (ret) {
31033103
ublk_put_req_ref(io, req);
31043104
return ret;
@@ -3129,8 +3129,8 @@ ublk_daemon_register_io_buf(struct io_uring_cmd *cmd,
31293129
if (!ublk_dev_support_zero_copy(ub) || !ublk_rq_has_data(req))
31303130
return -EINVAL;
31313131

3132-
ret = io_buffer_register_bvec(cmd, req, ublk_io_release, index,
3133-
issue_flags);
3132+
ret = io_buffer_register_request(cmd, req, ublk_io_release, index,
3133+
issue_flags);
31343134
if (ret)
31353135
return ret;
31363136

@@ -3145,7 +3145,7 @@ static int ublk_unregister_io_buf(struct io_uring_cmd *cmd,
31453145
if (!(ub->dev_info.flags & UBLK_F_SUPPORT_ZERO_COPY))
31463146
return -EINVAL;
31473147

3148-
return io_buffer_unregister_bvec(cmd, index, issue_flags);
3148+
return io_buffer_unregister(cmd, index, issue_flags);
31493149
}
31503150

31513151
static int ublk_check_fetch_buf(const struct ublk_device *ub, __u64 buf_addr)
@@ -3286,7 +3286,7 @@ static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
32863286
goto out;
32873287

32883288
/*
3289-
* io_buffer_unregister_bvec() doesn't access the ubq or io,
3289+
* io_buffer_unregister() doesn't access the ubq or io,
32903290
* so no need to validate the q_id, tag, or task
32913291
*/
32923292
if (_IOC_NR(cmd_op) == UBLK_IO_UNREGISTER_IO_BUF)
@@ -3353,7 +3353,7 @@ static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
33533353
req = ublk_fill_io_cmd(io, cmd);
33543354
ret = ublk_config_io_buf(ub, io, cmd, addr, &buf_idx);
33553355
if (buf_idx != UBLK_INVALID_BUF_IDX)
3356-
io_buffer_unregister_bvec(cmd, buf_idx, issue_flags);
3356+
io_buffer_unregister(cmd, buf_idx, issue_flags);
33573357
compl = ublk_need_complete_req(ub, io);
33583358

33593359
if (req_op(req) == REQ_OP_ZONE_APPEND)
@@ -3688,7 +3688,7 @@ static int ublk_batch_commit_io(struct ublk_queue *ubq,
36883688
}
36893689

36903690
if (buf_idx != UBLK_INVALID_BUF_IDX)
3691-
io_buffer_unregister_bvec(data->cmd, buf_idx, data->issue_flags);
3691+
io_buffer_unregister(data->cmd, buf_idx, data->issue_flags);
36923692
if (req_op(req) == REQ_OP_ZONE_APPEND)
36933693
req->__sector = ublk_batch_zone_lba(uc, elem);
36943694
if (compl)

include/linux/io_uring/cmd.h

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,15 @@ struct io_br_sel io_uring_cmd_buffer_select(struct io_uring_cmd *ioucmd,
9191
bool io_uring_mshot_cmd_post_cqe(struct io_uring_cmd *ioucmd,
9292
struct io_br_sel *sel, unsigned int issue_flags);
9393

94+
int io_buffer_register_request(struct io_uring_cmd *cmd, struct request *rq,
95+
void (*release)(void *), unsigned int index,
96+
unsigned int issue_flags);
97+
int io_buffer_register_bvec(struct io_uring_cmd *cmd, const struct bio_vec *bvs,
98+
unsigned int nr_bvecs, void (*release)(void *),
99+
void *priv, u8 dir, unsigned int index,
100+
unsigned int issue_flags);
101+
int io_buffer_unregister(struct io_uring_cmd *cmd, unsigned int index,
102+
unsigned int issue_flags);
94103
#else
95104
static inline int
96105
io_uring_cmd_import_fixed(u64 ubuf, unsigned long len, int rw,
@@ -133,6 +142,29 @@ static inline bool io_uring_mshot_cmd_post_cqe(struct io_uring_cmd *ioucmd,
133142
{
134143
return true;
135144
}
145+
static inline int io_buffer_register_request(struct io_uring_cmd *cmd,
146+
struct request *rq,
147+
void (*release)(void *),
148+
unsigned int index,
149+
unsigned int issue_flags)
150+
{
151+
return -EOPNOTSUPP;
152+
}
153+
static inline int io_buffer_register_bvec(struct io_uring_cmd *cmd,
154+
const struct bio_vec *bvs,
155+
unsigned int nr_bvecs,
156+
void (*release)(void *), void *priv,
157+
u8 dir, unsigned int index,
158+
unsigned int issue_flags)
159+
{
160+
return -EOPNOTSUPP;
161+
}
162+
static inline int io_buffer_unregister(struct io_uring_cmd *cmd,
163+
unsigned int index,
164+
unsigned int issue_flags)
165+
{
166+
return -EOPNOTSUPP;
167+
}
136168
#endif
137169

138170
static inline struct io_uring_cmd *io_uring_cmd_from_tw(struct io_tw_req tw_req)
@@ -182,10 +214,4 @@ static inline void io_uring_cmd_done32(struct io_uring_cmd *ioucmd, s32 ret,
182214
return __io_uring_cmd_done(ioucmd, ret, res2, issue_flags, true);
183215
}
184216

185-
int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
186-
void (*release)(void *), unsigned int index,
187-
unsigned int issue_flags);
188-
int io_buffer_unregister_bvec(struct io_uring_cmd *cmd, unsigned int index,
189-
unsigned int issue_flags);
190-
191217
#endif /* _LINUX_IO_URING_CMD_H */

include/linux/io_uring_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ enum io_uring_cmd_flags {
4444
IO_URING_F_COMPAT = (1 << 12),
4545
};
4646

47+
enum {
48+
IO_BUF_DEST = 1 << ITER_DEST,
49+
IO_BUF_SOURCE = 1 << ITER_SOURCE,
50+
};
51+
4752
struct iou_loop_params;
4853

4954
struct io_wq_work_node {

io_uring/io_uring.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3218,7 +3218,7 @@ static int __init io_uring_init(void)
32183218
io_uring_optable_init();
32193219

32203220
/* imu->dir is u8 */
3221-
BUILD_BUG_ON((IO_IMU_DEST | IO_IMU_SOURCE) > U8_MAX);
3221+
BUILD_BUG_ON((IO_BUF_DEST | IO_BUF_SOURCE) > U8_MAX);
32223222

32233223
/*
32243224
* Allow user copy in the per-command field, which starts after the

io_uring/rsrc.c

Lines changed: 90 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,7 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
820820
imu->release = io_release_ubuf;
821821
imu->priv = imu;
822822
imu->flags = 0;
823-
imu->dir = IO_IMU_DEST | IO_IMU_SOURCE;
823+
imu->dir = IO_BUF_DEST | IO_BUF_SOURCE;
824824
if (coalesced)
825825
imu->folio_shift = data.folio_shift;
826826
refcount_set(&imu->refs, 1);
@@ -924,72 +924,125 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg,
924924
return ret;
925925
}
926926

927-
int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq,
928-
void (*release)(void *), unsigned int index,
929-
unsigned int issue_flags)
927+
static struct io_mapped_ubuf *io_kernel_buffer_init(struct io_ring_ctx *ctx,
928+
unsigned int nr_bvecs,
929+
unsigned int total_bytes,
930+
u8 dir,
931+
void (*release)(void *),
932+
void *priv,
933+
unsigned int index)
930934
{
931-
struct io_ring_ctx *ctx = cmd_to_io_kiocb(cmd)->ctx;
932935
struct io_rsrc_data *data = &ctx->buf_table;
933-
struct req_iterator rq_iter;
934936
struct io_mapped_ubuf *imu;
935937
struct io_rsrc_node *node;
936-
struct bio_vec bv;
937-
unsigned int nr_bvecs = 0;
938-
int ret = 0;
939938

940-
io_ring_submit_lock(ctx, issue_flags);
941-
if (index >= data->nr) {
942-
ret = -EINVAL;
943-
goto unlock;
944-
}
939+
if (index >= data->nr)
940+
return ERR_PTR(-EINVAL);
945941
index = array_index_nospec(index, data->nr);
946942

947-
if (data->nodes[index]) {
948-
ret = -EBUSY;
949-
goto unlock;
950-
}
943+
if (data->nodes[index])
944+
return ERR_PTR(-EBUSY);
951945

952946
node = io_rsrc_node_alloc(ctx, IORING_RSRC_BUFFER);
953-
if (!node) {
954-
ret = -ENOMEM;
955-
goto unlock;
956-
}
947+
if (!node)
948+
return ERR_PTR(-ENOMEM);
957949

958-
/*
959-
* blk_rq_nr_phys_segments() may overestimate the number of bvecs
960-
* but avoids needing to iterate over the bvecs
961-
*/
962-
imu = io_alloc_imu(ctx, blk_rq_nr_phys_segments(rq));
950+
imu = io_alloc_imu(ctx, nr_bvecs);
963951
if (!imu) {
964952
io_cache_free(&ctx->node_cache, node);
965-
ret = -ENOMEM;
966-
goto unlock;
953+
return ERR_PTR(-ENOMEM);
967954
}
968955

969956
imu->ubuf = 0;
970-
imu->len = blk_rq_bytes(rq);
957+
imu->len = total_bytes;
971958
imu->acct_pages = 0;
972959
imu->folio_shift = PAGE_SHIFT;
960+
imu->nr_bvecs = nr_bvecs;
973961
refcount_set(&imu->refs, 1);
974962
imu->release = release;
975-
imu->priv = rq;
963+
imu->priv = priv;
964+
imu->dir = dir;
976965
imu->flags = IO_REGBUF_F_KBUF;
977-
imu->dir = 1 << rq_data_dir(rq);
978966

967+
node->buf = imu;
968+
data->nodes[index] = node;
969+
970+
return imu;
971+
}
972+
973+
int io_buffer_register_request(struct io_uring_cmd *cmd, struct request *rq,
974+
void (*release)(void *), unsigned int index,
975+
unsigned int issue_flags)
976+
{
977+
struct io_ring_ctx *ctx = cmd_to_io_kiocb(cmd)->ctx;
978+
struct req_iterator rq_iter;
979+
struct io_mapped_ubuf *imu;
980+
struct bio_vec bv;
981+
/*
982+
* blk_rq_nr_phys_segments() may overestimate the number of bvecs
983+
* but avoids needing to iterate over the bvecs
984+
*/
985+
unsigned int nr_bvecs = blk_rq_nr_phys_segments(rq);
986+
unsigned int total_bytes = blk_rq_bytes(rq);
987+
int ret = 0;
988+
989+
io_ring_submit_lock(ctx, issue_flags);
990+
991+
imu = io_kernel_buffer_init(ctx, nr_bvecs, total_bytes,
992+
1 << rq_data_dir(rq), release, rq, index);
993+
if (IS_ERR(imu)) {
994+
ret = PTR_ERR(imu);
995+
goto unlock;
996+
}
997+
998+
nr_bvecs = 0;
979999
rq_for_each_bvec(bv, rq, rq_iter)
9801000
imu->bvec[nr_bvecs++] = bv;
9811001
imu->nr_bvecs = nr_bvecs;
9821002

983-
node->buf = imu;
984-
data->nodes[index] = node;
1003+
unlock:
1004+
io_ring_submit_unlock(ctx, issue_flags);
1005+
return ret;
1006+
}
1007+
EXPORT_SYMBOL_GPL(io_buffer_register_request);
1008+
1009+
/*
1010+
* bvs is copied internally. caller may free it on return.
1011+
*/
1012+
int io_buffer_register_bvec(struct io_uring_cmd *cmd, const struct bio_vec *bvs,
1013+
unsigned int nr_bvecs, void (*release)(void *),
1014+
void *priv, u8 dir, unsigned int index,
1015+
unsigned int issue_flags)
1016+
{
1017+
struct io_ring_ctx *ctx = cmd_to_io_kiocb(cmd)->ctx;
1018+
struct io_mapped_ubuf *imu;
1019+
struct bio_vec *bvec;
1020+
unsigned int i, total_bytes = 0;
1021+
int ret = 0;
1022+
1023+
for (i = 0; i < nr_bvecs; i++)
1024+
total_bytes += bvs[i].bv_len;
1025+
1026+
io_ring_submit_lock(ctx, issue_flags);
1027+
imu = io_kernel_buffer_init(ctx, nr_bvecs, total_bytes, dir, release,
1028+
priv, index);
1029+
if (IS_ERR(imu)) {
1030+
ret = PTR_ERR(imu);
1031+
goto unlock;
1032+
}
1033+
1034+
bvec = imu->bvec;
1035+
for (i = 0; i < nr_bvecs; i++)
1036+
bvec[i] = bvs[i];
1037+
9851038
unlock:
9861039
io_ring_submit_unlock(ctx, issue_flags);
9871040
return ret;
9881041
}
9891042
EXPORT_SYMBOL_GPL(io_buffer_register_bvec);
9901043

991-
int io_buffer_unregister_bvec(struct io_uring_cmd *cmd, unsigned int index,
992-
unsigned int issue_flags)
1044+
int io_buffer_unregister(struct io_uring_cmd *cmd, unsigned int index,
1045+
unsigned int issue_flags)
9931046
{
9941047
struct io_ring_ctx *ctx = cmd_to_io_kiocb(cmd)->ctx;
9951048
struct io_rsrc_data *data = &ctx->buf_table;
@@ -1019,7 +1072,7 @@ int io_buffer_unregister_bvec(struct io_uring_cmd *cmd, unsigned int index,
10191072
io_ring_submit_unlock(ctx, issue_flags);
10201073
return ret;
10211074
}
1022-
EXPORT_SYMBOL_GPL(io_buffer_unregister_bvec);
1075+
EXPORT_SYMBOL_GPL(io_buffer_unregister);
10231076

10241077
static int validate_fixed_range(u64 buf_addr, size_t len,
10251078
const struct io_mapped_ubuf *imu)

io_uring/rsrc.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,6 @@ struct io_rsrc_node {
2323
};
2424
};
2525

26-
enum {
27-
IO_IMU_DEST = 1 << ITER_DEST,
28-
IO_IMU_SOURCE = 1 << ITER_SOURCE,
29-
};
30-
3126
enum {
3227
IO_REGBUF_F_KBUF = 1,
3328
};

0 commit comments

Comments
 (0)