0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-29 10:12:39 +01:00

ircd::fs::aio: Add statistics for AIO subsystem w/ console cmd.

This commit is contained in:
Jason Volk 2018-11-27 19:54:24 -08:00
parent 12cf8c8772
commit 5cdd2e6376
5 changed files with 134 additions and 8 deletions

View file

@ -11,20 +11,51 @@
#pragma once
#define HAVE_IRCD_FS_AIO_H
// Public and unconditional interface for Linux AIO. This file is part of
// the standard include stack and available whether or not this platform
// is Linux with AIO, and whether or not it's enabled, etc. If it is not
// most of this stuff does nothing and will have null values.
//
// Public and unconditional interface for AIO. This file is part of the
// standard include stack and available whether or not this platform is Linux
// with AIO, and whether or not it's enabled, etc. If it is not most of this
// stuff does nothing and will have null values.
/// Asynchronous filesystem Input/Output
///
namespace ircd::fs::aio
{
struct init;
struct stats;
struct kernel;
struct request;
extern kernel *context;
extern struct stats stats;
}
/// Statistics structure.
///
/// Subtract complete from requests to get the count of requests pending
/// "in flight." Subtract errors from complete to only get the count of
/// fully successful operations. complete will always eventually match
/// up with requests.
///
/// Subtract complete_bytes from requests_bytes to get the total bytes
/// currently pending "in flight." Subtract errors_bytes from response_bytes
/// to only get bytes successfully read or written. complete_bytes will
/// always eventually match up with requests_bytes.
///
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 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
};
struct ircd::fs::aio::init
{
init();

View file

@ -383,6 +383,8 @@ noexcept try
//assert(count > 0);
assert(count >= 0);
aio::stats.handles++;
aio::stats.events += count;
for(ssize_t i(0); i < count; ++i)
handle_event(event[i]);
@ -481,6 +483,10 @@ ircd::fs::aio::request::cancel()
assert(context);
syscall_nointr<SYS_io_cancel>(context->idp, cb, &result);
aio::stats.cancel_bytes += bytes(iovec());
aio::stats.cancel++;
context->handle_event(result);
}
@ -499,17 +505,35 @@ try
static_cast<iocb *>(this)
};
syscall<SYS_io_submit>(context->idp, 1, &cbs); do
syscall<SYS_io_submit>(context->idp, 1, &cbs);
const size_t submitted_bytes
{
bytes(iovec())
};
// Update stats for submission phase
aio::stats.requests_bytes += submitted_bytes;
aio::stats.requests++;
// Block for completion
while(retval == std::numeric_limits<ssize_t>::min())
ctx::wait();
}
while(retval == std::numeric_limits<ssize_t>::min());
// Update stats for completion phase.
aio::stats.complete_bytes += submitted_bytes;
aio::stats.complete++;
if(retval == -1)
{
aio::stats.errors++;
aio::stats.errors_bytes += submitted_bytes;
throw fs::error
{
make_error_code(errcode)
};
}
return size_t(retval);
}
@ -526,3 +550,13 @@ catch(const ctx::terminated &)
cancel();
throw;
}
ircd::vector_view<const struct ::iovec>
ircd::fs::aio::request::iovec()
const
{
return
{
reinterpret_cast<const ::iovec *>(aio_buf), aio_nbytes
};
}

View file

@ -74,6 +74,8 @@ struct ircd::fs::aio::request
ssize_t errcode {0};
public:
vector_view<const struct ::iovec> iovec() const;
size_t operator()();
void cancel();

View file

@ -781,6 +781,11 @@ decltype(ircd::fs::aio::context)
ircd::fs::aio::context
{};
/// Global stats structure
decltype(ircd::fs::aio::stats)
ircd::fs::aio::stats
{};
//
// init
//

View file

@ -727,6 +727,60 @@ console_cmd__env(opt &out, const string_view &line)
return true;
}
//
// aio
//
bool
console_cmd__aio(opt &out, const string_view &line)
{
if(!fs::aio::context)
throw error
{
"AIO is not available."
};
const auto &s
{
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))
<< std::endl;
out << std::setw(12) << std::left << "success"
<< std::setw(9) << std::right << (s.complete - s.errors)
<< " " << pretty(iec(s.complete_bytes - s.errors_bytes))
<< std::endl;
out << std::setw(12) << std::left << "errors"
<< std::setw(9) << std::right << s.errors
<< " " << pretty(iec(s.errors_bytes))
<< std::endl;
out << std::setw(12) << std::left << "cancel"
<< std::setw(9) << std::right << s.cancel
<< " " << pretty(iec(s.cancel_bytes))
<< std::endl;
out << std::setw(12) << std::left << "handles"
<< std::setw(9) << std::right << s.handles
<< std::endl;
out << std::setw(12) << std::left << "events"
<< std::setw(9) << std::right << s.events
<< std::endl;
return true;
}
//
// conf
//