diff --git a/include/ircd/fs/aio.h b/include/ircd/fs/aio.h index dcf78ba29..8fa232655 100644 --- a/include/ircd/fs/aio.h +++ b/include/ircd/fs/aio.h @@ -43,22 +43,29 @@ namespace ircd::fs::aio /// struct ircd::fs::aio::stats { - uint64_t requests {0}; ///< count of requests created - uint64_t complete {0}; ///< count of requests completed - uint64_t handles {0}; ///< count of event_fd callbacks - uint64_t events {0}; ///< count of events from io_getevents - uint64_t cancel {0}; ///< count of requests canceled - uint64_t errors {0}; ///< count of response errcodes - uint64_t reads {0}; ///< count of read complete - uint64_t writes {0}; ///< count of write complete + uint32_t requests {0}; ///< count of requests created + uint32_t complete {0}; ///< count of requests completed + uint32_t handles {0}; ///< count of event_fd callbacks + uint32_t events {0}; ///< count of events from io_getevents + uint32_t cancel {0}; ///< count of requests canceled + uint32_t errors {0}; ///< count of response errcodes + uint32_t reads {0}; ///< count of read complete + uint32_t writes {0}; ///< count of write complete - uint64_t requests_bytes {0}; ///< total bytes for requests created - uint64_t complete_bytes {0}; ///< total bytes for requests completed - uint64_t errors_bytes {0}; ///< total bytes for completed w/ errc - uint64_t cancel_bytes {0}; ///< total bytes for cancels - uint64_t read_bytes {0}; ///< total bytes for read completed - uint64_t write_bytes {0}; ///< total bytes for write completed + uint64_t bytes_requests {0}; ///< total bytes for requests created + uint64_t bytes_complete {0}; ///< total bytes for requests completed + uint64_t bytes_errors {0}; ///< total bytes for completed w/ errc + uint64_t bytes_cancel {0}; ///< total bytes for cancels + uint64_t bytes_read {0}; ///< total bytes for read completed + uint64_t bytes_write {0}; ///< total bytes for write completed + uint32_t cur_reads {0}; ///< pending reads + uint32_t cur_writes {0}; ///< pending write + uint32_t cur_bytes_write {0}; ///< pending write bytes + + uint32_t max_requests {0}; ///< maximum observed pending requests + uint32_t max_reads {0}; ///< maximum observed pending reads + uint32_t max_writes {0}; ///< maximum observed pending write }; struct ircd::fs::aio::init diff --git a/ircd/aio.cc b/ircd/aio.cc index ad1a6b2ef..7c18340ac 100644 --- a/ircd/aio.cc +++ b/ircd/aio.cc @@ -106,13 +106,21 @@ ircd::fs::aio::read(const fd &fd, fd, make_iov(bufs), opts }; + stats.cur_reads++; + stats.max_reads = std::max(stats.max_reads, stats.cur_reads); + const unwind dec{[] + { + stats.cur_reads--; + }}; + + // Make request; blocks ircd::ctx until completed or throw. const size_t bytes { request() }; - aio::stats.read_bytes += bytes; - aio::stats.reads++; + stats.bytes_read += bytes; + stats.reads++; return bytes; } @@ -150,6 +158,16 @@ ircd::fs::aio::write(const fd &fd, }; #endif + stats.cur_bytes_write += req_bytes; + stats.cur_writes++; + stats.max_writes = std::max(stats.max_writes, stats.cur_writes); + const unwind dec{[&req_bytes] + { + stats.cur_bytes_write -= req_bytes; + stats.cur_writes--; + }}; + + // Make the request; ircd::ctx blocks here. Throws on error const size_t bytes { request() @@ -158,8 +176,8 @@ ircd::fs::aio::write(const fd &fd, // Does linux ever not complete all bytes for an AIO? assert(bytes == req_bytes); - aio::stats.write_bytes += bytes; - aio::stats.writes++; + stats.bytes_write += bytes; + stats.writes++; return bytes; } @@ -357,8 +375,9 @@ noexcept try //assert(count > 0); assert(count >= 0); - aio::stats.handles++; - aio::stats.events += count; + // Update any stats. + stats.events += count; + stats.handles++; for(ssize_t i(0); i < count; ++i) handle_event(event[i]); @@ -458,8 +477,8 @@ ircd::fs::aio::request::cancel() assert(context); syscall_nointr(context->idp, cb, &result); - aio::stats.cancel_bytes += bytes(iovec()); - aio::stats.cancel++; + stats.bytes_cancel += bytes(iovec()); + stats.cancel++; context->handle_event(result); } @@ -484,24 +503,28 @@ try bytes(iovec()) }; + // Submit to kernel syscall(context->idp, 1, &cbs); // Update stats for submission phase - aio::stats.requests_bytes += submitted_bytes; - aio::stats.requests++; + stats.bytes_requests += submitted_bytes; + stats.requests++; + + const auto &curcnt(stats.requests - stats.complete); + stats.max_requests = std::max(stats.max_requests, curcnt); // Block for completion while(retval == std::numeric_limits::min()) ctx::wait(); // Update stats for completion phase. - aio::stats.complete_bytes += submitted_bytes; - aio::stats.complete++; + stats.bytes_complete += submitted_bytes; + stats.complete++; if(retval == -1) { - aio::stats.errors++; - aio::stats.errors_bytes += submitted_bytes; + stats.bytes_errors += submitted_bytes; + stats.errors++; throw fs::error { diff --git a/modules/console.cc b/modules/console.cc index 847734fa6..ae463f490 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -745,39 +745,70 @@ console_cmd__aio(opt &out, const string_view &line) fs::aio::stats }; - out << std::setw(12) << std::left << "pending" - << std::setw(9) << std::right << (s.requests - s.complete) - << " " << pretty(iec(s.requests_bytes - s.complete_bytes)) - << std::endl; - out << std::setw(12) << std::left << "requests" << std::setw(9) << std::right << s.requests - << " " << pretty(iec(s.requests_bytes)) + << " " << pretty(iec(s.bytes_requests)) + << std::endl; + + out << std::setw(12) << std::left << "requests cur" + << std::setw(9) << std::right << (s.requests - s.complete) + << " " << pretty(iec(s.bytes_requests - s.bytes_complete)) << std::endl; out << std::setw(12) << std::left << "requests avg" << std::setw(9) << std::right << " " - << " " << pretty(iec(s.requests_bytes / s.requests)) + << " " << pretty(iec(s.bytes_requests / s.requests)) + << std::endl; + + out << std::setw(12) << std::left << "requests max" + << std::setw(9) << std::right << s.max_requests << std::endl; out << std::setw(12) << std::left << "reads" << std::setw(9) << std::right << s.reads - << " " << pretty(iec(s.read_bytes)) + << " " << pretty(iec(s.bytes_read)) + << std::endl; + + out << std::setw(12) << std::left << "reads cur" + << std::setw(9) << std::right << s.cur_reads + << std::endl; + + out << std::setw(12) << std::left << "reads avg" + << std::setw(9) << std::right << " " + << " " << pretty(iec(s.bytes_read / s.reads)) + << std::endl; + + out << std::setw(12) << std::left << "reads max" + << std::setw(9) << std::right << s.max_reads << std::endl; out << std::setw(12) << std::left << "writes" << std::setw(9) << std::right << s.writes - << " " << pretty(iec(s.write_bytes)) + << " " << pretty(iec(s.bytes_write)) + << std::endl; + + out << std::setw(12) << std::left << "writes cur" + << std::setw(9) << std::right << s.cur_writes + << " " << pretty(iec(s.cur_bytes_write)) + << std::endl; + + out << std::setw(12) << std::left << "writes avg" + << std::setw(9) << std::right << " " + << " " << pretty(iec(s.bytes_write / s.writes)) + << std::endl; + + out << std::setw(12) << std::left << "writes max" + << std::setw(9) << std::right << s.max_writes << std::endl; out << std::setw(12) << std::left << "errors" << std::setw(9) << std::right << s.errors - << " " << pretty(iec(s.errors_bytes)) + << " " << pretty(iec(s.bytes_errors)) << std::endl; out << std::setw(12) << std::left << "cancel" << std::setw(9) << std::right << s.cancel - << " " << pretty(iec(s.cancel_bytes)) + << " " << pretty(iec(s.bytes_cancel)) << std::endl; out << std::setw(12) << std::left << "handles"