Skip to content

Commit 53f427e

Browse files
Ming Leiaxboe
authored andcommitted
ublk: support UBLK_AUTO_BUF_REG_FALLBACK
For UBLK_F_AUTO_BUF_REG, buffer is registered to uring_cmd context automatically with the provided buffer index. User may provide one wrong buffer index, or the specified buffer is registered by application already. Add UBLK_AUTO_BUF_REG_FALLBACK for supporting to auto buffer registering fallback by completing the uring_cmd and telling ublk server the register failure via UBLK_AUTO_BUF_REG_FALLBACK, then ublk server still can register the buffer from userspace. So we can provide reliable way for supporting auto buffer register. Signed-off-by: Ming Lei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 99c1e4e commit 53f427e

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

drivers/block/ublk_drv.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,16 @@ static inline void __ublk_abort_rq(struct ublk_queue *ubq,
11821182
blk_mq_end_request(rq, BLK_STS_IOERR);
11831183
}
11841184

1185+
static void ublk_auto_buf_reg_fallback(struct request *req, struct ublk_io *io)
1186+
{
1187+
const struct ublk_queue *ubq = req->mq_hctx->driver_data;
1188+
struct ublksrv_io_desc *iod = ublk_get_iod(ubq, req->tag);
1189+
struct ublk_rq_data *data = blk_mq_rq_to_pdu(req);
1190+
1191+
iod->op_flags |= UBLK_IO_F_NEED_REG_BUF;
1192+
refcount_set(&data->ref, 1);
1193+
}
1194+
11851195
static bool ublk_auto_buf_reg(struct request *req, struct ublk_io *io,
11861196
unsigned int issue_flags)
11871197
{
@@ -1192,6 +1202,10 @@ static bool ublk_auto_buf_reg(struct request *req, struct ublk_io *io,
11921202
ret = io_buffer_register_bvec(io->cmd, req, ublk_io_release,
11931203
pdu->buf.index, issue_flags);
11941204
if (ret) {
1205+
if (pdu->buf.flags & UBLK_AUTO_BUF_REG_FALLBACK) {
1206+
ublk_auto_buf_reg_fallback(req, io);
1207+
return true;
1208+
}
11951209
blk_mq_end_request(req, BLK_STS_IOERR);
11961210
return false;
11971211
}
@@ -1971,6 +1985,8 @@ static inline int ublk_set_auto_buf_reg(struct io_uring_cmd *cmd)
19711985
if (pdu->buf.reserved0 || pdu->buf.reserved1)
19721986
return -EINVAL;
19731987

1988+
if (pdu->buf.flags & ~UBLK_AUTO_BUF_REG_F_MASK)
1989+
return -EINVAL;
19741990
return 0;
19751991
}
19761992

include/uapi/linux/ublk_cmd.h

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,16 @@
236236
*
237237
* - all reserved fields in `ublk_auto_buf_reg` need to be zeroed
238238
*
239+
* - pass flags from `ublk_auto_buf_reg.flags` if needed
240+
*
239241
* This way avoids extra cost from two uring_cmd, but also simplifies backend
240242
* implementation, such as, the dependency on IO_REGISTER_IO_BUF and
241243
* IO_UNREGISTER_IO_BUF becomes not necessary.
244+
*
245+
* If wrong data or flags are provided, both IO_FETCH_REQ and
246+
* IO_COMMIT_AND_FETCH_REQ are failed, for the latter, the ublk IO request
247+
* won't be completed until new IO_COMMIT_AND_FETCH_REQ command is issued
248+
* successfully
242249
*/
243250
#define UBLK_F_AUTO_BUF_REG (1ULL << 11)
244251

@@ -328,6 +335,17 @@ struct ublksrv_ctrl_dev_info {
328335
#define UBLK_IO_F_FUA (1U << 13)
329336
#define UBLK_IO_F_NOUNMAP (1U << 15)
330337
#define UBLK_IO_F_SWAP (1U << 16)
338+
/*
339+
* For UBLK_F_AUTO_BUF_REG & UBLK_AUTO_BUF_REG_FALLBACK only.
340+
*
341+
* This flag is set if auto buffer register is failed & ublk server passes
342+
* UBLK_AUTO_BUF_REG_FALLBACK, and ublk server need to register buffer
343+
* manually for handling the delivered IO command if this flag is observed
344+
*
345+
* ublk server has to check this flag if UBLK_AUTO_BUF_REG_FALLBACK is
346+
* passed in.
347+
*/
348+
#define UBLK_IO_F_NEED_REG_BUF (1U << 17)
331349

332350
/*
333351
* io cmd is described by this structure, and stored in share memory, indexed
@@ -362,10 +380,23 @@ static inline __u32 ublksrv_get_flags(const struct ublksrv_io_desc *iod)
362380
return iod->op_flags >> 8;
363381
}
364382

383+
/*
384+
* If this flag is set, fallback by completing the uring_cmd and setting
385+
* `UBLK_IO_F_NEED_REG_BUF` in case of auto-buf-register failure;
386+
* otherwise the client ublk request is failed silently
387+
*
388+
* If ublk server passes this flag, it has to check if UBLK_IO_F_NEED_REG_BUF
389+
* is set in `ublksrv_io_desc.op_flags`. If UBLK_IO_F_NEED_REG_BUF is set,
390+
* ublk server needs to register io buffer manually for handling IO command.
391+
*/
392+
#define UBLK_AUTO_BUF_REG_FALLBACK (1 << 0)
393+
#define UBLK_AUTO_BUF_REG_F_MASK UBLK_AUTO_BUF_REG_FALLBACK
394+
365395
struct ublk_auto_buf_reg {
366396
/* index for registering the delivered request buffer */
367397
__u16 index;
368-
__u16 reserved0;
398+
__u8 flags;
399+
__u8 reserved0;
369400

370401
/*
371402
* io_ring FD can be passed via the reserve field in future for
@@ -379,6 +410,7 @@ struct ublk_auto_buf_reg {
379410
* uring_cmd's sqe->addr:
380411
*
381412
* - bit0 ~ bit15: buffer index
413+
* - bit16 ~ bit23: flags
382414
* - bit24 ~ bit31: reserved0
383415
* - bit32 ~ bit63: reserved1
384416
*/
@@ -387,7 +419,8 @@ static inline struct ublk_auto_buf_reg ublk_sqe_addr_to_auto_buf_reg(
387419
{
388420
struct ublk_auto_buf_reg reg = {
389421
.index = sqe_addr & 0xffff,
390-
.reserved0 = (sqe_addr >> 16) & 0xffff,
422+
.flags = (sqe_addr >> 16) & 0xff,
423+
.reserved0 = (sqe_addr >> 24) & 0xff,
391424
.reserved1 = sqe_addr >> 32,
392425
};
393426

@@ -397,7 +430,7 @@ static inline struct ublk_auto_buf_reg ublk_sqe_addr_to_auto_buf_reg(
397430
static inline __u64
398431
ublk_auto_buf_reg_to_sqe_addr(const struct ublk_auto_buf_reg *buf)
399432
{
400-
__u64 addr = buf->index | (__u64)buf->reserved0 << 16 |
433+
__u64 addr = buf->index | (__u64)buf->flags << 16 | (__u64)buf->reserved0 << 24 |
401434
(__u64)buf->reserved1 << 32;
402435

403436
return addr;

0 commit comments

Comments
 (0)