diff options
Diffstat (limited to 'iotop/taskstats.cpp')
-rw-r--r-- | iotop/taskstats.cpp | 134 |
1 files changed, 71 insertions, 63 deletions
diff --git a/iotop/taskstats.cpp b/iotop/taskstats.cpp index 263c92a9..eff1d4df 100644 --- a/iotop/taskstats.cpp +++ b/iotop/taskstats.cpp @@ -13,9 +13,9 @@ // limitations under the License. #include <linux/taskstats.h> +#include <netlink/socket.h> #include <netlink/genl/ctrl.h> #include <netlink/genl/genl.h> -#include <netlink/socket.h> #include <algorithm> #include <memory> @@ -24,10 +24,13 @@ #include "taskstats.h" -TaskstatsSocket::TaskstatsSocket() : nl_(nullptr, nl_socket_free), family_id_(0) {} +TaskstatsSocket::TaskstatsSocket() + : nl_(nullptr, nl_socket_free), family_id_(0) { +} bool TaskstatsSocket::Open() { - std::unique_ptr<nl_sock, decltype(&nl_socket_free)> nl(nl_socket_alloc(), nl_socket_free); + std::unique_ptr<nl_sock, decltype(&nl_socket_free)> nl( + nl_socket_alloc(), nl_socket_free); if (!nl.get()) { LOG(ERROR) << "Failed to allocate netlink socket"; return false; @@ -41,8 +44,7 @@ bool TaskstatsSocket::Open() { int family_id = genl_ctrl_resolve(nl.get(), TASKSTATS_GENL_NAME); if (family_id < 0) { - LOG(ERROR) << nl_geterror(family_id) << std::endl - << "Unable to determine taskstats family id (does your kernel support taskstats?)"; + LOG(ERROR) << nl_geterror(family_id) << std::endl << "Unable to determine taskstats family id (does your kernel support taskstats?)"; return false; } @@ -61,23 +63,25 @@ struct TaskStatsRequest { taskstats stats; }; -static pid_t ParseAggregateTaskStats(nlattr* attr, int attr_size, taskstats* stats) { +static pid_t ParseAggregateTaskStats(nlattr* attr, int attr_size, + taskstats* stats) { pid_t received_pid = -1; nla_for_each_attr(attr, attr, attr_size, attr_size) { switch (nla_type(attr)) { - case TASKSTATS_TYPE_PID: - case TASKSTATS_TYPE_TGID: - received_pid = nla_get_u32(attr); - break; - case TASKSTATS_TYPE_STATS: { - int len = static_cast<int>(sizeof(*stats)); - len = std::min(len, nla_len(attr)); - nla_memcpy(stats, attr, len); - return received_pid; - } - default: - LOG(ERROR) << "unexpected attribute inside AGGR"; - return -1; + case TASKSTATS_TYPE_PID: + case TASKSTATS_TYPE_TGID: + received_pid = nla_get_u32(attr); + break; + case TASKSTATS_TYPE_STATS: + { + int len = static_cast<int>(sizeof(*stats)); + len = std::min(len, nla_len(attr)); + nla_memcpy(stats, attr, len); + return received_pid; + } + default: + LOG(ERROR) << "unexpected attribute inside AGGR"; + return -1; } } @@ -92,27 +96,28 @@ static int ParseTaskStats(nl_msg* msg, void* arg) { nla_for_each_attr(attr, attr, remaining, remaining) { switch (nla_type(attr)) { - case TASKSTATS_TYPE_AGGR_PID: - case TASKSTATS_TYPE_AGGR_TGID: { - nlattr* nested_attr = static_cast<nlattr*>(nla_data(attr)); - taskstats stats; - pid_t ret; - - ret = ParseAggregateTaskStats(nested_attr, nla_len(attr), &stats); - if (ret < 0) { - LOG(ERROR) << "Bad AGGR_PID contents"; - } else if (ret == taskstats_request->requested_pid) { - taskstats_request->stats = stats; - } else { - LOG(WARNING) << "got taskstats for unexpected pid " << ret << " (expected " - << taskstats_request->requested_pid << ", continuing..."; - } - break; + case TASKSTATS_TYPE_AGGR_PID: + case TASKSTATS_TYPE_AGGR_TGID: + { + nlattr* nested_attr = static_cast<nlattr*>(nla_data(attr)); + taskstats stats; + pid_t ret; + + ret = ParseAggregateTaskStats(nested_attr, nla_len(attr), &stats); + if (ret < 0) { + LOG(ERROR) << "Bad AGGR_PID contents"; + } else if (ret == taskstats_request->requested_pid) { + taskstats_request->stats = stats; + } else { + LOG(WARNING) << "got taskstats for unexpected pid " << ret << + " (expected " << taskstats_request->requested_pid << ", continuing..."; } - case TASKSTATS_TYPE_NULL: - break; - default: - LOG(ERROR) << "unexpected attribute in taskstats"; + break; + } + case TASKSTATS_TYPE_NULL: + break; + default: + LOG(ERROR) << "unexpected attribute in taskstats"; } } return NL_OK; @@ -122,10 +127,11 @@ bool TaskstatsSocket::GetStats(int pid, int type, TaskStatistics& stats) { TaskStatsRequest taskstats_request = TaskStatsRequest(); taskstats_request.requested_pid = pid; - std::unique_ptr<nl_msg, decltype(&nlmsg_free)> message(nlmsg_alloc(), nlmsg_free); + std::unique_ptr<nl_msg, decltype(&nlmsg_free)> message(nlmsg_alloc(), + nlmsg_free); - genlmsg_put(message.get(), NL_AUTO_PID, NL_AUTO_SEQ, family_id_, 0, 0, TASKSTATS_CMD_GET, - TASKSTATS_VERSION); + genlmsg_put(message.get(), NL_AUTO_PID, NL_AUTO_SEQ, family_id_, 0, 0, + TASKSTATS_CMD_GET, TASKSTATS_VERSION); nla_put_u32(message.get(), type, pid); int result = nl_send_auto_complete(nl_.get(), message.get()); @@ -133,7 +139,8 @@ bool TaskstatsSocket::GetStats(int pid, int type, TaskStatistics& stats) { return false; } - std::unique_ptr<nl_cb, decltype(&nl_cb_put)> callbacks(nl_cb_alloc(NL_CB_DEFAULT), nl_cb_put); + std::unique_ptr<nl_cb, decltype(&nl_cb_put)> callbacks( + nl_cb_alloc(NL_CB_DEFAULT), nl_cb_put); nl_cb_set(callbacks.get(), NL_CB_VALID, NL_CB_CUSTOM, &ParseTaskStats, static_cast<void*>(&taskstats_request)); @@ -181,7 +188,8 @@ TaskStatistics::TaskStatistics(const taskstats& taskstats_stats) { reclaim_delay_count_ = taskstats_stats.freepages_count; reclaim_delay_ns_ = taskstats_stats.freepages_delay_total; - total_delay_ns_ = cpu_delay_ns_ + block_io_delay_ns_ + swap_in_delay_ns_ + reclaim_delay_ns_; + total_delay_ns_ = + cpu_delay_ns_ + block_io_delay_ns_ + swap_in_delay_ns_ + reclaim_delay_ns_; cpu_time_real_ = taskstats_stats.cpu_run_real_total; cpu_time_virtual_ = taskstats_stats.cpu_run_virtual_total; @@ -199,9 +207,9 @@ TaskStatistics::TaskStatistics(const taskstats& taskstats_stats) { void TaskStatistics::AddPidToTgid(const TaskStatistics& pid_statistics) { // tgid statistics already contain delay values totalled across all pids // only add IO statistics - read_bytes_ += pid_statistics.read_bytes_; - write_bytes_ += pid_statistics.write_bytes_; - read_write_bytes_ += pid_statistics.read_write_bytes_; + read_bytes_ += pid_statistics.read_bytes_; + write_bytes_ += pid_statistics.write_bytes_; + read_write_bytes_ += pid_statistics.read_write_bytes_; cancelled_write_bytes_ += pid_statistics.cancelled_write_bytes_; if (pid_ == pid_statistics.pid_) { comm_ = pid_statistics.comm_; @@ -216,22 +224,22 @@ void TaskStatistics::AddPidToTgid(const TaskStatistics& pid_statistics) { // Store new statistics and return the delta from the old statistics TaskStatistics TaskStatistics::Update(const TaskStatistics& new_statistics) { TaskStatistics delta = new_statistics; - delta.minflt_ -= minflt_; - delta.majflt_ -= majflt_; - delta.cpu_delay_count_ -= cpu_delay_count_; - delta.cpu_delay_ns_ -= cpu_delay_ns_; - delta.block_io_delay_count_ -= block_io_delay_count_; - delta.block_io_delay_ns_ -= block_io_delay_ns_; - delta.swap_in_delay_count_ -= swap_in_delay_count_; - delta.swap_in_delay_ns_ -= swap_in_delay_ns_; - delta.reclaim_delay_count_ -= reclaim_delay_count_; - delta.reclaim_delay_ns_ -= reclaim_delay_ns_; - delta.total_delay_ns_ -= total_delay_ns_; - delta.cpu_time_real_ -= cpu_time_real_; - delta.cpu_time_virtual_ -= cpu_time_virtual_; - delta.read_bytes_ -= read_bytes_; - delta.write_bytes_ -= write_bytes_; - delta.read_write_bytes_ -= read_write_bytes_; + delta.minflt_ -= minflt_; + delta.majflt_ -= majflt_; + delta.cpu_delay_count_ -= cpu_delay_count_; + delta.cpu_delay_ns_ -= cpu_delay_ns_; + delta.block_io_delay_count_ -= block_io_delay_count_; + delta.block_io_delay_ns_ -= block_io_delay_ns_; + delta.swap_in_delay_count_ -= swap_in_delay_count_; + delta.swap_in_delay_ns_ -= swap_in_delay_ns_; + delta.reclaim_delay_count_ -= reclaim_delay_count_; + delta.reclaim_delay_ns_ -= reclaim_delay_ns_; + delta.total_delay_ns_ -= total_delay_ns_; + delta.cpu_time_real_ -= cpu_time_real_; + delta.cpu_time_virtual_ -= cpu_time_virtual_; + delta.read_bytes_ -= read_bytes_; + delta.write_bytes_ -= write_bytes_; + delta.read_write_bytes_ -= read_write_bytes_; delta.cancelled_write_bytes_ -= cancelled_write_bytes_; *this = new_statistics; return delta; |