]>
git.proxmox.com Git - ceph.git/blob - ceph/src/os/bluestore/io_uring.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "ceph_io_uring.h"
6 #if defined(HAVE_LIBURING) && defined(__x86_64__)
13 static bool hipri
= false; /* use IO polling */
14 static bool sq_thread
= false; /* use kernel submission/poller thread */
17 struct io_uring io_uring
;
18 pthread_mutex_t cq_mutex
;
19 pthread_mutex_t sq_mutex
;
21 std::map
<int, int> fixed_fds_map
;
24 static int ioring_get_cqe(struct ioring_data
*d
, unsigned int max
,
27 struct io_uring
*ring
= &d
->io_uring
;
28 struct io_uring_cqe
*cqe
;
32 io_uring_for_each_cqe(ring
, head
, cqe
) {
33 struct aio_t
*io
= (struct aio_t
*)(uintptr_t) io_uring_cqe_get_data(cqe
);
41 io_uring_cq_advance(ring
, nr
);
46 static int find_fixed_fd(struct ioring_data
*d
, int real_fd
)
48 auto it
= d
->fixed_fds_map
.find(real_fd
);
49 if (it
== d
->fixed_fds_map
.end())
55 static void init_sqe(struct ioring_data
*d
, struct io_uring_sqe
*sqe
,
58 int fixed_fd
= find_fixed_fd(d
, io
->fd
);
60 ceph_assert(fixed_fd
!= -1);
62 if (io
->iocb
.aio_lio_opcode
== IO_CMD_PWRITEV
)
63 io_uring_prep_writev(sqe
, fixed_fd
, &io
->iov
[0],
64 io
->iov
.size(), io
->offset
);
65 else if (io
->iocb
.aio_lio_opcode
== IO_CMD_PREADV
)
66 io_uring_prep_readv(sqe
, fixed_fd
, &io
->iov
[0],
67 io
->iov
.size(), io
->offset
);
71 io_uring_sqe_set_data(sqe
, io
);
72 io_uring_sqe_set_flags(sqe
, IOSQE_FIXED_FILE
);
75 static int ioring_queue(struct ioring_data
*d
, void *priv
,
76 list
<aio_t
>::iterator beg
, list
<aio_t
>::iterator end
)
78 struct io_uring
*ring
= &d
->io_uring
;
79 struct aio_t
*io
= nullptr;
81 ceph_assert(beg
!= end
);
84 struct io_uring_sqe
*sqe
= io_uring_get_sqe(ring
);
93 } while (++beg
!= end
);
96 /* Queue is full, go and reap something first */
99 return io_uring_submit(ring
);
102 static void build_fixed_fds_map(struct ioring_data
*d
,
103 std::vector
<int> &fds
)
106 for (int real_fd
: fds
) {
107 d
->fixed_fds_map
[real_fd
] = fixed_fd
++;
111 ioring_queue_t::ioring_queue_t(unsigned iodepth_
) :
112 d(make_unique
<ioring_data
>()),
117 ioring_queue_t::~ioring_queue_t()
121 int ioring_queue_t::init(std::vector
<int> &fds
)
125 pthread_mutex_init(&d
->cq_mutex
, NULL
);
126 pthread_mutex_init(&d
->sq_mutex
, NULL
);
129 flags
|= IORING_SETUP_IOPOLL
;
131 flags
|= IORING_SETUP_SQPOLL
;
133 int ret
= io_uring_queue_init(iodepth
, &d
->io_uring
, flags
);
137 ret
= io_uring_register(d
->io_uring
.ring_fd
, IORING_REGISTER_FILES
,
138 &fds
[0], fds
.size());
144 build_fixed_fds_map(d
.get(), fds
);
146 d
->epoll_fd
= epoll_create1(0);
147 if (d
->epoll_fd
< 0) {
152 struct epoll_event ev
;
154 ret
= epoll_ctl(d
->epoll_fd
, EPOLL_CTL_ADD
, d
->io_uring
.ring_fd
, &ev
);
165 io_uring_queue_exit(&d
->io_uring
);
170 void ioring_queue_t::shutdown()
172 d
->fixed_fds_map
.clear();
175 io_uring_queue_exit(&d
->io_uring
);
178 int ioring_queue_t::submit_batch(aio_iter beg
, aio_iter end
,
179 uint16_t aios_size
, void *priv
,
185 pthread_mutex_lock(&d
->sq_mutex
);
186 int rc
= ioring_queue(d
.get(), priv
, beg
, end
);
187 pthread_mutex_unlock(&d
->sq_mutex
);
192 int ioring_queue_t::get_next_completed(int timeout_ms
, aio_t
**paio
, int max
)
195 pthread_mutex_lock(&d
->cq_mutex
);
196 int events
= ioring_get_cqe(d
.get(), max
, paio
);
197 pthread_mutex_unlock(&d
->cq_mutex
);
200 struct epoll_event ev
;
201 int ret
= epoll_wait(d
->epoll_fd
, &ev
, 1, timeout_ms
);
212 bool ioring_queue_t::supported()
214 struct io_uring_params p
;
216 memset(&p
, 0, sizeof(p
));
217 int fd
= io_uring_setup(16, &p
);
226 #else // #if defined(HAVE_LIBURING) && defined(__x86_64__)
228 struct ioring_data
{};
230 ioring_queue_t::ioring_queue_t(unsigned iodepth_
)
235 ioring_queue_t::~ioring_queue_t()
240 int ioring_queue_t::init(std::vector
<int> &fds
)
245 void ioring_queue_t::shutdown()
250 int ioring_queue_t::submit_batch(aio_iter beg
, aio_iter end
,
251 uint16_t aios_size
, void *priv
,
257 int ioring_queue_t::get_next_completed(int timeout_ms
, aio_t
**paio
, int max
)
262 bool ioring_queue_t::supported()
267 #endif // #if defined(HAVE_LIBURING) && defined(__x86_64__)