Skip to content

Commit 225dc96

Browse files
calebsanderaxboe
authored andcommitted
ublk: inline __ublk_ch_uring_cmd()
ublk_ch_uring_cmd_local() is a thin wrapper around __ublk_ch_uring_cmd() that copies the ublksrv_io_cmd from user-mapped memory to the stack using READ_ONCE(). This ublksrv_io_cmd is passed by pointer to __ublk_ch_uring_cmd() and __ublk_ch_uring_cmd() is a large function unlikely to be inlined, so __ublk_ch_uring_cmd() will have to load the ublksrv_io_cmd fields back from the stack. Inline __ublk_ch_uring_cmd() into ublk_ch_uring_cmd_local() and load the ublksrv_io_cmd fields into local variables with READ_ONCE(). This allows the compiler to delay loading the fields until they are needed and choose whether to store them in registers or on the stack. Signed-off-by: Caleb Sander Mateos <csander@purestorage.com> Reviewed-by: Ming Lei <ming.lei@redhat.com> Link: https://lore.kernel.org/r/20250808153251.282107-1-csander@purestorage.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 4dbe13c commit 225dc96

File tree

1 file changed

+23
-39
lines changed

1 file changed

+23
-39
lines changed

drivers/block/ublk_drv.c

Lines changed: 23 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,23 +2265,28 @@ static bool ublk_get_data(const struct ublk_queue *ubq, struct ublk_io *io,
22652265
return ublk_start_io(ubq, req, io);
22662266
}
22672267

2268-
static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
2269-
unsigned int issue_flags,
2270-
const struct ublksrv_io_cmd *ub_cmd)
2268+
static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
2269+
unsigned int issue_flags)
22712270
{
2271+
/* May point to userspace-mapped memory */
2272+
const struct ublksrv_io_cmd *ub_src = io_uring_sqe_cmd(cmd->sqe);
22722273
u16 buf_idx = UBLK_INVALID_BUF_IDX;
22732274
struct ublk_device *ub = cmd->file->private_data;
22742275
struct ublk_queue *ubq;
22752276
struct ublk_io *io;
22762277
u32 cmd_op = cmd->cmd_op;
2277-
unsigned tag = ub_cmd->tag;
2278+
u16 q_id = READ_ONCE(ub_src->q_id);
2279+
u16 tag = READ_ONCE(ub_src->tag);
2280+
s32 result = READ_ONCE(ub_src->result);
2281+
u64 addr = READ_ONCE(ub_src->addr); /* unioned with zone_append_lba */
22782282
struct request *req;
22792283
int ret;
22802284
bool compl;
22812285

2286+
WARN_ON_ONCE(issue_flags & IO_URING_F_UNLOCKED);
2287+
22822288
pr_devel("%s: received: cmd op %d queue %d tag %d result %d\n",
2283-
__func__, cmd->cmd_op, ub_cmd->q_id, tag,
2284-
ub_cmd->result);
2289+
__func__, cmd->cmd_op, q_id, tag, result);
22852290

22862291
ret = ublk_check_cmd_op(cmd_op);
22872292
if (ret)
@@ -2292,25 +2297,24 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
22922297
* so no need to validate the q_id, tag, or task
22932298
*/
22942299
if (_IOC_NR(cmd_op) == UBLK_IO_UNREGISTER_IO_BUF)
2295-
return ublk_unregister_io_buf(cmd, ub, ub_cmd->addr,
2296-
issue_flags);
2300+
return ublk_unregister_io_buf(cmd, ub, addr, issue_flags);
22972301

22982302
ret = -EINVAL;
2299-
if (ub_cmd->q_id >= ub->dev_info.nr_hw_queues)
2303+
if (q_id >= ub->dev_info.nr_hw_queues)
23002304
goto out;
23012305

2302-
ubq = ublk_get_queue(ub, ub_cmd->q_id);
2306+
ubq = ublk_get_queue(ub, q_id);
23032307

23042308
if (tag >= ubq->q_depth)
23052309
goto out;
23062310

23072311
io = &ubq->ios[tag];
23082312
/* UBLK_IO_FETCH_REQ can be handled on any task, which sets io->task */
23092313
if (unlikely(_IOC_NR(cmd_op) == UBLK_IO_FETCH_REQ)) {
2310-
ret = ublk_check_fetch_buf(ubq, ub_cmd->addr);
2314+
ret = ublk_check_fetch_buf(ubq, addr);
23112315
if (ret)
23122316
goto out;
2313-
ret = ublk_fetch(cmd, ubq, io, ub_cmd->addr);
2317+
ret = ublk_fetch(cmd, ubq, io, addr);
23142318
if (ret)
23152319
goto out;
23162320

@@ -2324,7 +2328,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
23242328
* so can be handled on any task
23252329
*/
23262330
if (_IOC_NR(cmd_op) == UBLK_IO_REGISTER_IO_BUF)
2327-
return ublk_register_io_buf(cmd, ubq, io, ub_cmd->addr,
2331+
return ublk_register_io_buf(cmd, ubq, io, addr,
23282332
issue_flags);
23292333

23302334
goto out;
@@ -2346,22 +2350,22 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
23462350

23472351
switch (_IOC_NR(cmd_op)) {
23482352
case UBLK_IO_REGISTER_IO_BUF:
2349-
return ublk_daemon_register_io_buf(cmd, ubq, io, ub_cmd->addr,
2353+
return ublk_daemon_register_io_buf(cmd, ubq, io, addr,
23502354
issue_flags);
23512355
case UBLK_IO_COMMIT_AND_FETCH_REQ:
2352-
ret = ublk_check_commit_and_fetch(ubq, io, ub_cmd->addr);
2356+
ret = ublk_check_commit_and_fetch(ubq, io, addr);
23532357
if (ret)
23542358
goto out;
2355-
io->res = ub_cmd->result;
2359+
io->res = result;
23562360
req = ublk_fill_io_cmd(io, cmd);
2357-
ret = ublk_config_io_buf(ubq, io, cmd, ub_cmd->addr, &buf_idx);
2361+
ret = ublk_config_io_buf(ubq, io, cmd, addr, &buf_idx);
23582362
compl = ublk_need_complete_req(ubq, io);
23592363

23602364
/* can't touch 'ublk_io' any more */
23612365
if (buf_idx != UBLK_INVALID_BUF_IDX)
23622366
io_buffer_unregister_bvec(cmd, buf_idx, issue_flags);
23632367
if (req_op(req) == REQ_OP_ZONE_APPEND)
2364-
req->__sector = ub_cmd->zone_append_lba;
2368+
req->__sector = addr;
23652369
if (compl)
23662370
__ublk_complete_rq(req);
23672371

@@ -2375,7 +2379,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd,
23752379
* request
23762380
*/
23772381
req = ublk_fill_io_cmd(io, cmd);
2378-
ret = ublk_config_io_buf(ubq, io, cmd, ub_cmd->addr, NULL);
2382+
ret = ublk_config_io_buf(ubq, io, cmd, addr, NULL);
23792383
WARN_ON_ONCE(ret);
23802384
if (likely(ublk_get_data(ubq, io, req))) {
23812385
__ublk_prep_compl_io_cmd(io, req);
@@ -2426,26 +2430,6 @@ static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub,
24262430
return NULL;
24272431
}
24282432

2429-
static inline int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
2430-
unsigned int issue_flags)
2431-
{
2432-
/*
2433-
* Not necessary for async retry, but let's keep it simple and always
2434-
* copy the values to avoid any potential reuse.
2435-
*/
2436-
const struct ublksrv_io_cmd *ub_src = io_uring_sqe_cmd(cmd->sqe);
2437-
const struct ublksrv_io_cmd ub_cmd = {
2438-
.q_id = READ_ONCE(ub_src->q_id),
2439-
.tag = READ_ONCE(ub_src->tag),
2440-
.result = READ_ONCE(ub_src->result),
2441-
.addr = READ_ONCE(ub_src->addr)
2442-
};
2443-
2444-
WARN_ON_ONCE(issue_flags & IO_URING_F_UNLOCKED);
2445-
2446-
return __ublk_ch_uring_cmd(cmd, issue_flags, &ub_cmd);
2447-
}
2448-
24492433
static void ublk_ch_uring_cmd_cb(struct io_uring_cmd *cmd,
24502434
unsigned int issue_flags)
24512435
{

0 commit comments

Comments
 (0)