Splice via io_uring - bad result too

40% CPU according to perf is lost inside do_splice() -> unix_stream_sendpage()
without io_uring and in various exc_page_fault() with io_uring
nbd-vmsplice
Vitaliy Filippov 2021-11-21 23:30:16 +03:00
parent 6c3248a36c
commit 4936c42132
1 changed files with 35 additions and 5 deletions

View File

@ -26,6 +26,18 @@
const char *exe_name = NULL;
static inline void my_uring_prep_splice(struct io_uring_sqe *sqe,
int fd_in, int64_t off_in,
int fd_out, int64_t off_out,
unsigned int nbytes,
unsigned int splice_flags)
{
my_uring_prep_rw(IORING_OP_SPLICE, sqe, fd_out, NULL, nbytes, (__u64) off_out);
sqe->splice_off_in = (__u64) off_in;
sqe->splice_fd_in = fd_in;
sqe->splice_flags = splice_flags;
}
struct buf_to_free_t
{
void *buf = NULL;
@ -61,6 +73,7 @@ protected:
mmap_manager_t mm;
int pipe_fd[2];
int vmspliced = 0;
public:
static json11::Json::object parse_args(int narg, const char *args[])
@ -571,12 +584,29 @@ protected:
}
else
{
int res = vmsplice(pipe_fd[1], send_list.data(), 1, SPLICE_F_GIFT);
if (res < 0)
io_uring_sqe* sqe = ringloop->get_sqe();
if (!sqe)
{
throw std::runtime_error(std::string("vmsplice: ")+strerror(errno));
return;
}
int sent = res, spl = res;
if (vmspliced <= 0)
{
vmspliced = vmsplice(pipe_fd[1], send_list.data(), 1, SPLICE_F_GIFT);
if (vmspliced < 0)
{
throw std::runtime_error(std::string("vmsplice: ")+strerror(errno));
}
}
send_msg.msg_iovlen = 1;
ring_data_t* data = ((ring_data_t*)sqe->user_data);
data->callback = [this](ring_data_t *data)
{
if (data->res > 0)
vmspliced -= data->res;
handle_send(data->res);
};
my_uring_prep_splice(sqe, pipe_fd[0], -1l, nbd_fd, -1l, vmspliced, SPLICE_F_MOVE);
/*int sent = res, spl = res;
while (spl > 0)
{
res = splice(pipe_fd[0], NULL, nbd_fd, NULL, spl, SPLICE_F_MOVE);
@ -590,7 +620,7 @@ protected:
spl -= res;
}
}
handle_send(sent);
handle_send(sent);*/
}
}