null.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #include "kublk.h"
  3. #ifndef IORING_NOP_INJECT_RESULT
  4. #define IORING_NOP_INJECT_RESULT (1U << 0)
  5. #endif
  6. #ifndef IORING_NOP_FIXED_BUFFER
  7. #define IORING_NOP_FIXED_BUFFER (1U << 3)
  8. #endif
  9. static int ublk_null_tgt_init(const struct dev_ctx *ctx, struct ublk_dev *dev)
  10. {
  11. const struct ublksrv_ctrl_dev_info *info = &dev->dev_info;
  12. unsigned long dev_size = 250UL << 30;
  13. dev->tgt.dev_size = dev_size;
  14. dev->tgt.params = (struct ublk_params) {
  15. .types = UBLK_PARAM_TYPE_BASIC | UBLK_PARAM_TYPE_DMA_ALIGN |
  16. UBLK_PARAM_TYPE_SEGMENT,
  17. .basic = {
  18. .logical_bs_shift = 9,
  19. .physical_bs_shift = 12,
  20. .io_opt_shift = 12,
  21. .io_min_shift = 9,
  22. .max_sectors = info->max_io_buf_bytes >> 9,
  23. .dev_sectors = dev_size >> 9,
  24. },
  25. .dma = {
  26. .alignment = 4095,
  27. },
  28. .seg = {
  29. .seg_boundary_mask = 4095,
  30. .max_segment_size = 32 << 10,
  31. .max_segments = 32,
  32. },
  33. };
  34. ublk_set_integrity_params(ctx, &dev->tgt.params);
  35. if (info->flags & UBLK_F_SUPPORT_ZERO_COPY)
  36. dev->tgt.sq_depth = dev->tgt.cq_depth = 2 * info->queue_depth;
  37. return 0;
  38. }
  39. static void __setup_nop_io(int tag, const struct ublksrv_io_desc *iod,
  40. struct io_uring_sqe *sqe, int q_id, unsigned buf_idx)
  41. {
  42. unsigned ublk_op = ublksrv_get_op(iod);
  43. io_uring_prep_nop(sqe);
  44. sqe->buf_index = buf_idx;
  45. sqe->flags |= IOSQE_FIXED_FILE;
  46. sqe->rw_flags = IORING_NOP_FIXED_BUFFER | IORING_NOP_INJECT_RESULT;
  47. sqe->len = iod->nr_sectors << 9; /* injected result */
  48. sqe->user_data = build_user_data(tag, ublk_op, 0, q_id, 1);
  49. }
  50. static int null_queue_zc_io(struct ublk_thread *t, struct ublk_queue *q,
  51. int tag)
  52. {
  53. const struct ublksrv_io_desc *iod = ublk_get_iod(q, tag);
  54. struct io_uring_sqe *sqe[3];
  55. unsigned short buf_idx = ublk_io_buf_idx(t, q, tag);
  56. ublk_io_alloc_sqes(t, sqe, 3);
  57. io_uring_prep_buf_register(sqe[0], q, tag, q->q_id, buf_idx);
  58. sqe[0]->user_data = build_user_data(tag,
  59. ublk_cmd_op_nr(sqe[0]->cmd_op), 0, q->q_id, 1);
  60. sqe[0]->flags |= IOSQE_CQE_SKIP_SUCCESS | IOSQE_IO_HARDLINK;
  61. __setup_nop_io(tag, iod, sqe[1], q->q_id, buf_idx);
  62. sqe[1]->flags |= IOSQE_IO_HARDLINK;
  63. io_uring_prep_buf_unregister(sqe[2], q, tag, q->q_id, buf_idx);
  64. sqe[2]->user_data = build_user_data(tag, ublk_cmd_op_nr(sqe[2]->cmd_op), 0, q->q_id, 1);
  65. // buf register is marked as IOSQE_CQE_SKIP_SUCCESS
  66. return 2;
  67. }
  68. static int null_queue_auto_zc_io(struct ublk_thread *t, struct ublk_queue *q,
  69. int tag)
  70. {
  71. const struct ublksrv_io_desc *iod = ublk_get_iod(q, tag);
  72. struct io_uring_sqe *sqe[1];
  73. ublk_io_alloc_sqes(t, sqe, 1);
  74. __setup_nop_io(tag, iod, sqe[0], q->q_id, ublk_io_buf_idx(t, q, tag));
  75. return 1;
  76. }
  77. static void ublk_null_io_done(struct ublk_thread *t, struct ublk_queue *q,
  78. const struct io_uring_cqe *cqe)
  79. {
  80. unsigned tag = user_data_to_tag(cqe->user_data);
  81. unsigned op = user_data_to_op(cqe->user_data);
  82. struct ublk_io *io = ublk_get_io(q, tag);
  83. if (cqe->res < 0 || op != ublk_cmd_op_nr(UBLK_U_IO_UNREGISTER_IO_BUF)) {
  84. if (!io->result)
  85. io->result = cqe->res;
  86. if (cqe->res < 0)
  87. ublk_err("%s: io failed op %x user_data %lx\n",
  88. __func__, op, cqe->user_data);
  89. }
  90. /* buffer register op is IOSQE_CQE_SKIP_SUCCESS */
  91. if (op == ublk_cmd_op_nr(UBLK_U_IO_REGISTER_IO_BUF))
  92. io->tgt_ios += 1;
  93. if (ublk_completed_tgt_io(t, q, tag))
  94. ublk_complete_io(t, q, tag, io->result);
  95. }
  96. static int ublk_null_queue_io(struct ublk_thread *t, struct ublk_queue *q,
  97. int tag)
  98. {
  99. const struct ublksrv_io_desc *iod = ublk_get_iod(q, tag);
  100. unsigned auto_zc = ublk_queue_use_auto_zc(q);
  101. unsigned zc = ublk_queue_use_zc(q);
  102. int queued;
  103. if (auto_zc && !ublk_io_auto_zc_fallback(iod))
  104. queued = null_queue_auto_zc_io(t, q, tag);
  105. else if (zc)
  106. queued = null_queue_zc_io(t, q, tag);
  107. else {
  108. ublk_complete_io(t, q, tag, iod->nr_sectors << 9);
  109. return 0;
  110. }
  111. ublk_queued_tgt_io(t, q, tag, queued);
  112. return 0;
  113. }
  114. /*
  115. * return invalid buffer index for triggering auto buffer register failure,
  116. * then UBLK_IO_RES_NEED_REG_BUF handling is covered
  117. */
  118. static unsigned short ublk_null_buf_index(const struct ublk_thread *t,
  119. const struct ublk_queue *q, int tag)
  120. {
  121. if (ublk_queue_auto_zc_fallback(q))
  122. return (unsigned short)-1;
  123. return ublk_io_buf_idx(t, q, tag);
  124. }
  125. const struct ublk_tgt_ops null_tgt_ops = {
  126. .name = "null",
  127. .init_tgt = ublk_null_tgt_init,
  128. .queue_io = ublk_null_queue_io,
  129. .tgt_io_done = ublk_null_io_done,
  130. .buf_index = ublk_null_buf_index,
  131. };