Skip to content

Commit bf098d7

Browse files
ps-ushankaraxboe
authored andcommitted
selftests: ublk: kublk: plumb q_id in io_uring user_data
Currently, when we process CQEs, we know which ublk_queue we are working on because we know which ring we are working on, and ublk_queues and rings are in 1:1 correspondence. However, as we decouple ublk_queues from ublk server threads, ublk_queues and rings will no longer be in 1:1 correspondence - each ublk server thread will have a ring, and each thread may issue commands against more than one ublk_queue. So in order to know which ublk_queue a CQE refers to, plumb that information in the associated SQE's user_data. Signed-off-by: Uday Shankar <[email protected]> Reviewed-by: Ming Lei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent ab03a61 commit bf098d7

File tree

6 files changed

+39
-28
lines changed

6 files changed

+39
-28
lines changed

tools/testing/selftests/ublk/fault_inject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ static int ublk_fault_inject_queue_io(struct ublk_queue *q, int tag)
4848

4949
ublk_queue_alloc_sqes(q, &sqe, 1);
5050
io_uring_prep_timeout(sqe, &ts, 1, 0);
51-
sqe->user_data = build_user_data(tag, ublksrv_get_op(iod), 0, 1);
51+
sqe->user_data = build_user_data(tag, ublksrv_get_op(iod), 0, q->q_id, 1);
5252

5353
ublk_queued_tgt_io(q, tag, 1);
5454

tools/testing/selftests/ublk/file_backed.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ static int loop_queue_flush_io(struct ublk_queue *q, const struct ublksrv_io_des
2222
io_uring_prep_fsync(sqe[0], 1 /*fds[1]*/, IORING_FSYNC_DATASYNC);
2323
io_uring_sqe_set_flags(sqe[0], IOSQE_FIXED_FILE);
2424
/* bit63 marks us as tgt io */
25-
sqe[0]->user_data = build_user_data(tag, ublk_op, 0, 1);
25+
sqe[0]->user_data = build_user_data(tag, ublk_op, 0, q->q_id, 1);
2626
return 1;
2727
}
2828

@@ -48,7 +48,7 @@ static int loop_queue_tgt_rw_io(struct ublk_queue *q, const struct ublksrv_io_de
4848
sqe[0]->buf_index = tag;
4949
io_uring_sqe_set_flags(sqe[0], IOSQE_FIXED_FILE);
5050
/* bit63 marks us as tgt io */
51-
sqe[0]->user_data = build_user_data(tag, ublk_op, 0, 1);
51+
sqe[0]->user_data = build_user_data(tag, ublk_op, 0, q->q_id, 1);
5252
return 1;
5353
}
5454

@@ -57,17 +57,17 @@ static int loop_queue_tgt_rw_io(struct ublk_queue *q, const struct ublksrv_io_de
5757
io_uring_prep_buf_register(sqe[0], 0, tag, q->q_id, tag);
5858
sqe[0]->flags |= IOSQE_CQE_SKIP_SUCCESS | IOSQE_IO_HARDLINK;
5959
sqe[0]->user_data = build_user_data(tag,
60-
ublk_cmd_op_nr(sqe[0]->cmd_op), 0, 1);
60+
ublk_cmd_op_nr(sqe[0]->cmd_op), 0, q->q_id, 1);
6161

6262
io_uring_prep_rw(op, sqe[1], 1 /*fds[1]*/, 0,
6363
iod->nr_sectors << 9,
6464
iod->start_sector << 9);
6565
sqe[1]->buf_index = tag;
6666
sqe[1]->flags |= IOSQE_FIXED_FILE | IOSQE_IO_HARDLINK;
67-
sqe[1]->user_data = build_user_data(tag, ublk_op, 0, 1);
67+
sqe[1]->user_data = build_user_data(tag, ublk_op, 0, q->q_id, 1);
6868

6969
io_uring_prep_buf_unregister(sqe[2], 0, tag, q->q_id, tag);
70-
sqe[2]->user_data = build_user_data(tag, ublk_cmd_op_nr(sqe[2]->cmd_op), 0, 1);
70+
sqe[2]->user_data = build_user_data(tag, ublk_cmd_op_nr(sqe[2]->cmd_op), 0, q->q_id, 1);
7171

7272
return 2;
7373
}

tools/testing/selftests/ublk/kublk.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ int ublk_queue_io_cmd(struct ublk_queue *q, struct ublk_io *io, unsigned tag)
627627
if (q->state & UBLKSRV_AUTO_BUF_REG)
628628
ublk_set_auto_buf_reg(q, sqe[0], tag);
629629

630-
user_data = build_user_data(tag, _IOC_NR(cmd_op), 0, 0);
630+
user_data = build_user_data(tag, _IOC_NR(cmd_op), 0, q->q_id, 0);
631631
io_uring_sqe_set_data64(sqe[0], user_data);
632632

633633
io->flags = 0;
@@ -673,10 +673,11 @@ static inline void ublksrv_handle_tgt_cqe(struct ublk_queue *q,
673673
q->tgt_ops->tgt_io_done(q, tag, cqe);
674674
}
675675

676-
static void ublk_handle_cqe(struct io_uring *r,
676+
static void ublk_handle_cqe(struct ublk_dev *dev,
677677
struct io_uring_cqe *cqe, void *data)
678678
{
679-
struct ublk_queue *q = container_of(r, struct ublk_queue, ring);
679+
unsigned q_id = user_data_to_q_id(cqe->user_data);
680+
struct ublk_queue *q = &dev->q[q_id];
680681
unsigned tag = user_data_to_tag(cqe->user_data);
681682
unsigned cmd_op = user_data_to_op(cqe->user_data);
682683
int fetch = (cqe->res != UBLK_IO_RES_ABORT) &&
@@ -727,17 +728,17 @@ static void ublk_handle_cqe(struct io_uring *r,
727728
}
728729
}
729730

730-
static int ublk_reap_events_uring(struct io_uring *r)
731+
static int ublk_reap_events_uring(struct ublk_queue *q)
731732
{
732733
struct io_uring_cqe *cqe;
733734
unsigned head;
734735
int count = 0;
735736

736-
io_uring_for_each_cqe(r, head, cqe) {
737-
ublk_handle_cqe(r, cqe, NULL);
737+
io_uring_for_each_cqe(&q->ring, head, cqe) {
738+
ublk_handle_cqe(q->dev, cqe, NULL);
738739
count += 1;
739740
}
740-
io_uring_cq_advance(r, count);
741+
io_uring_cq_advance(&q->ring, count);
741742

742743
return count;
743744
}
@@ -756,7 +757,7 @@ static int ublk_process_io(struct ublk_queue *q)
756757
return -ENODEV;
757758

758759
ret = io_uring_submit_and_wait(&q->ring, 1);
759-
reapped = ublk_reap_events_uring(&q->ring);
760+
reapped = ublk_reap_events_uring(q);
760761

761762
ublk_dbg(UBLK_DBG_QUEUE, "submit result %d, reapped %d stop %d idle %d\n",
762763
ret, reapped, (q->state & UBLKSRV_QUEUE_STOPPING),

tools/testing/selftests/ublk/kublk.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949
#define UBLKSRV_IO_IDLE_SECS 20
5050

5151
#define UBLK_IO_MAX_BYTES (1 << 20)
52-
#define UBLK_MAX_QUEUES 32
52+
#define UBLK_MAX_QUEUES_SHIFT 5
53+
#define UBLK_MAX_QUEUES (1 << UBLK_MAX_QUEUES_SHIFT)
5354
#define UBLK_QUEUE_DEPTH 1024
5455

5556
#define UBLK_DBG_DEV (1U << 0)
@@ -225,11 +226,14 @@ static inline int is_target_io(__u64 user_data)
225226
}
226227

227228
static inline __u64 build_user_data(unsigned tag, unsigned op,
228-
unsigned tgt_data, unsigned is_target_io)
229+
unsigned tgt_data, unsigned q_id, unsigned is_target_io)
229230
{
230-
assert(!(tag >> 16) && !(op >> 8) && !(tgt_data >> 16));
231+
/* we only have 7 bits to encode q_id */
232+
_Static_assert(UBLK_MAX_QUEUES_SHIFT <= 7);
233+
assert(!(tag >> 16) && !(op >> 8) && !(tgt_data >> 16) && !(q_id >> 7));
231234

232-
return tag | (op << 16) | (tgt_data << 24) | (__u64)is_target_io << 63;
235+
return tag | (op << 16) | (tgt_data << 24) |
236+
(__u64)q_id << 56 | (__u64)is_target_io << 63;
233237
}
234238

235239
static inline unsigned int user_data_to_tag(__u64 user_data)
@@ -247,6 +251,11 @@ static inline unsigned int user_data_to_tgt_data(__u64 user_data)
247251
return (user_data >> 24) & 0xffff;
248252
}
249253

254+
static inline unsigned int user_data_to_q_id(__u64 user_data)
255+
{
256+
return (user_data >> 56) & 0x7f;
257+
}
258+
250259
static inline unsigned short ublk_cmd_op_nr(unsigned int op)
251260
{
252261
return _IOC_NR(op);

tools/testing/selftests/ublk/null.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static int ublk_null_tgt_init(const struct dev_ctx *ctx, struct ublk_dev *dev)
4343
}
4444

4545
static void __setup_nop_io(int tag, const struct ublksrv_io_desc *iod,
46-
struct io_uring_sqe *sqe)
46+
struct io_uring_sqe *sqe, int q_id)
4747
{
4848
unsigned ublk_op = ublksrv_get_op(iod);
4949

@@ -52,7 +52,7 @@ static void __setup_nop_io(int tag, const struct ublksrv_io_desc *iod,
5252
sqe->flags |= IOSQE_FIXED_FILE;
5353
sqe->rw_flags = IORING_NOP_FIXED_BUFFER | IORING_NOP_INJECT_RESULT;
5454
sqe->len = iod->nr_sectors << 9; /* injected result */
55-
sqe->user_data = build_user_data(tag, ublk_op, 0, 1);
55+
sqe->user_data = build_user_data(tag, ublk_op, 0, q_id, 1);
5656
}
5757

5858
static int null_queue_zc_io(struct ublk_queue *q, int tag)
@@ -64,14 +64,14 @@ static int null_queue_zc_io(struct ublk_queue *q, int tag)
6464

6565
io_uring_prep_buf_register(sqe[0], 0, tag, q->q_id, tag);
6666
sqe[0]->user_data = build_user_data(tag,
67-
ublk_cmd_op_nr(sqe[0]->cmd_op), 0, 1);
67+
ublk_cmd_op_nr(sqe[0]->cmd_op), 0, q->q_id, 1);
6868
sqe[0]->flags |= IOSQE_CQE_SKIP_SUCCESS | IOSQE_IO_HARDLINK;
6969

70-
__setup_nop_io(tag, iod, sqe[1]);
70+
__setup_nop_io(tag, iod, sqe[1], q->q_id);
7171
sqe[1]->flags |= IOSQE_IO_HARDLINK;
7272

7373
io_uring_prep_buf_unregister(sqe[2], 0, tag, q->q_id, tag);
74-
sqe[2]->user_data = build_user_data(tag, ublk_cmd_op_nr(sqe[2]->cmd_op), 0, 1);
74+
sqe[2]->user_data = build_user_data(tag, ublk_cmd_op_nr(sqe[2]->cmd_op), 0, q->q_id, 1);
7575

7676
// buf register is marked as IOSQE_CQE_SKIP_SUCCESS
7777
return 2;
@@ -83,7 +83,7 @@ static int null_queue_auto_zc_io(struct ublk_queue *q, int tag)
8383
struct io_uring_sqe *sqe[1];
8484

8585
ublk_queue_alloc_sqes(q, sqe, 1);
86-
__setup_nop_io(tag, iod, sqe[0]);
86+
__setup_nop_io(tag, iod, sqe[0], q->q_id);
8787
return 1;
8888
}
8989

tools/testing/selftests/ublk/stripe.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ static int stripe_queue_tgt_rw_io(struct ublk_queue *q, const struct ublksrv_io_
144144
io_uring_prep_buf_register(sqe[0], 0, tag, q->q_id, tag);
145145
sqe[0]->flags |= IOSQE_CQE_SKIP_SUCCESS | IOSQE_IO_HARDLINK;
146146
sqe[0]->user_data = build_user_data(tag,
147-
ublk_cmd_op_nr(sqe[0]->cmd_op), 0, 1);
147+
ublk_cmd_op_nr(sqe[0]->cmd_op), 0, q->q_id, 1);
148148
}
149149

150150
for (i = zc; i < s->nr + extra - zc; i++) {
@@ -162,13 +162,14 @@ static int stripe_queue_tgt_rw_io(struct ublk_queue *q, const struct ublksrv_io_
162162
sqe[i]->flags |= IOSQE_IO_HARDLINK;
163163
}
164164
/* bit63 marks us as tgt io */
165-
sqe[i]->user_data = build_user_data(tag, ublksrv_get_op(iod), i - zc, 1);
165+
sqe[i]->user_data = build_user_data(tag, ublksrv_get_op(iod), i - zc, q->q_id, 1);
166166
}
167167
if (zc) {
168168
struct io_uring_sqe *unreg = sqe[s->nr + 1];
169169

170170
io_uring_prep_buf_unregister(unreg, 0, tag, q->q_id, tag);
171-
unreg->user_data = build_user_data(tag, ublk_cmd_op_nr(unreg->cmd_op), 0, 1);
171+
unreg->user_data = build_user_data(
172+
tag, ublk_cmd_op_nr(unreg->cmd_op), 0, q->q_id, 1);
172173
}
173174

174175
/* register buffer is skip_success */
@@ -185,7 +186,7 @@ static int handle_flush(struct ublk_queue *q, const struct ublksrv_io_desc *iod,
185186
for (i = 0; i < conf->nr_files; i++) {
186187
io_uring_prep_fsync(sqe[i], i + 1, IORING_FSYNC_DATASYNC);
187188
io_uring_sqe_set_flags(sqe[i], IOSQE_FIXED_FILE);
188-
sqe[i]->user_data = build_user_data(tag, UBLK_IO_OP_FLUSH, 0, 1);
189+
sqe[i]->user_data = build_user_data(tag, UBLK_IO_OP_FLUSH, 0, q->q_id, 1);
189190
}
190191
return conf->nr_files;
191192
}

0 commit comments

Comments
 (0)