gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/util/io_uring_util.cc (about) 1 // Copyright 2022 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "test/util/io_uring_util.h" 16 17 #include <memory> 18 19 namespace gvisor { 20 namespace testing { 21 22 PosixErrorOr<std::unique_ptr<IOUring>> IOUring::InitIOUring( 23 unsigned int entries, IOUringParams ¶ms) { 24 PosixErrorOr<FileDescriptor> fd = NewIOUringFD(entries, params); 25 if (!fd.ok()) { 26 return fd.error(); 27 } 28 29 return std::make_unique<IOUring>(std::move(fd.ValueOrDie()), entries, params); 30 } 31 32 IOUring::IOUring(FileDescriptor &&fd, unsigned int entries, 33 IOUringParams ¶ms) 34 : iouringfd_(std::move(fd)) { 35 cring_sz_ = params.cq_off.cqes + params.cq_entries * sizeof(IOUringCqe); 36 sring_sz_ = params.sq_off.array + params.sq_entries * sizeof(unsigned); 37 sqes_sz_ = params.sq_entries * sizeof(IOUringSqe); 38 39 cq_ptr_ = 40 mmap(0, cring_sz_, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, 41 iouringfd_.get(), IORING_OFF_SQ_RING); 42 sq_ptr_ = 43 mmap(0, sring_sz_, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, 44 iouringfd_.get(), IORING_OFF_SQ_RING); 45 sqe_ptr_ = mmap(0, sqes_sz_, PROT_READ | PROT_WRITE, 46 MAP_SHARED | MAP_POPULATE, iouringfd_.get(), IORING_OFF_SQES); 47 48 cqes_ = reinterpret_cast<IOUringCqe *>(reinterpret_cast<char *>(cq_ptr_) + 49 params.cq_off.cqes); 50 51 cq_head_ptr_ = reinterpret_cast<uint32_t *>( 52 reinterpret_cast<char *>(cq_ptr_) + params.cq_off.head); 53 cq_tail_ptr_ = reinterpret_cast<uint32_t *>( 54 reinterpret_cast<char *>(cq_ptr_) + params.cq_off.tail); 55 sq_head_ptr_ = reinterpret_cast<uint32_t *>( 56 reinterpret_cast<char *>(sq_ptr_) + params.sq_off.head); 57 sq_tail_ptr_ = reinterpret_cast<uint32_t *>( 58 reinterpret_cast<char *>(sq_ptr_) + params.sq_off.tail); 59 cq_overflow_ptr_ = reinterpret_cast<uint32_t *>( 60 reinterpret_cast<char *>(cq_ptr_) + params.cq_off.overflow); 61 sq_dropped_ptr_ = reinterpret_cast<uint32_t *>( 62 reinterpret_cast<char *>(sq_ptr_) + params.sq_off.dropped); 63 64 sq_mask_ = *(reinterpret_cast<uint32_t *>(reinterpret_cast<char *>(sq_ptr_) + 65 params.sq_off.ring_mask)); 66 sq_array_ = reinterpret_cast<unsigned *>(reinterpret_cast<char *>(sq_ptr_) + 67 params.sq_off.array); 68 } 69 70 IOUring::~IOUring() { 71 munmap(cq_ptr_, cring_sz_); 72 munmap(sq_ptr_, sring_sz_); 73 munmap(sqe_ptr_, sqes_sz_); 74 } 75 76 uint32_t IOUring::load_cq_head() { return io_uring_atomic_read(cq_head_ptr_); } 77 78 uint32_t IOUring::load_cq_tail() { return io_uring_atomic_read(cq_tail_ptr_); } 79 80 uint32_t IOUring::load_sq_head() { return io_uring_atomic_read(sq_head_ptr_); } 81 82 uint32_t IOUring::load_sq_tail() { return io_uring_atomic_read(sq_tail_ptr_); } 83 84 uint32_t IOUring::load_cq_overflow() { 85 return io_uring_atomic_read(cq_overflow_ptr_); 86 } 87 88 uint32_t IOUring::load_sq_dropped() { 89 return io_uring_atomic_read(sq_dropped_ptr_); 90 } 91 92 void IOUring::store_cq_head(uint32_t cq_head_val) { 93 io_uring_atomic_write(cq_head_ptr_, cq_head_val); 94 } 95 96 void IOUring::store_sq_tail(uint32_t sq_tail_val) { 97 io_uring_atomic_write(sq_tail_ptr_, sq_tail_val); 98 } 99 100 int IOUring::Enter(unsigned int to_submit, unsigned int min_complete, 101 unsigned int flags, sigset_t *sig) { 102 return IOUringEnter(iouringfd_.get(), to_submit, min_complete, flags, sig); 103 } 104 105 IOUringCqe *IOUring::get_cqes() { return cqes_; } 106 107 IOUringSqe *IOUring::get_sqes() { 108 return reinterpret_cast<IOUringSqe *>(sqe_ptr_); 109 } 110 111 uint32_t IOUring::get_sq_mask() { return sq_mask_; } 112 113 unsigned *IOUring::get_sq_array() { return sq_array_; } 114 115 } // namespace testing 116 } // namespace gvisor