Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add per-queue stats to bessctl #1007

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
49 changes: 25 additions & 24 deletions core/drivers/pmd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -418,9 +418,6 @@ void PMDPort::DeInit() {
}

void PMDPort::CollectStats(bool reset) {
packet_dir_t dir;
queue_t qid;

if (reset) {
rte_eth_stats_reset(dpdk_port_id_);
return;
Expand All @@ -443,31 +440,35 @@ void PMDPort::CollectStats(bool reset) {

port_stats_.inc.dropped = stats.imissed;

// i40e/net_e1000_igb PMD drivers, ixgbevf and net_bonding vdevs don't support
// per-queue stats
if (driver_ == "net_i40e" || driver_ == "net_i40e_vf" ||
driver_ == "net_ixgbe_vf" || driver_ == "net_bonding" ||
driver_ == "net_e1000_igb") {
// NOTE:
// - if link is down, tx bytes won't increase
// - if destination MAC address is incorrect, rx pkts won't increase
// NOTE: depending on DPDK PMD drivers,
// - if link is down, tx bytes may not increase
// - if destination is zero MAC address, rx pkts may not increase

uint64_t any = 0;

for (queue_t qid = 0; qid < num_queues[PACKET_DIR_INC]; qid++) {
auto &qstats = queue_stats_[PACKET_DIR_INC][qid];
any |= (qstats.packets = stats.q_ipackets[qid]);
any |= (qstats.bytes = stats.q_ibytes[qid]);
any |= (qstats.dropped = stats.q_errors[qid]);
}

for (queue_t qid = 0; qid < num_queues[PACKET_DIR_OUT]; qid++) {
auto &qstats = queue_stats_[PACKET_DIR_OUT][qid];
any |= (qstats.packets = stats.q_opackets[qid]);
any |= (qstats.bytes = stats.q_obytes[qid]);
}

// Some PMD drivers, such as i40e, ixgbevf and net_bonding, do not support
// per-queue stats. There doesn't seem to be a reliable way to detect whether
// the driver really supports per-queue stats or not. Instead, if all queue
// stats counters are 0, we assume that it only supports per-port stats
// Note that this heuristic is safe from potential double counting.
if (!any) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

port_stats_.inc.packets = stats.ipackets;
port_stats_.inc.bytes = stats.ibytes;
port_stats_.out.packets = stats.opackets;
port_stats_.out.bytes = stats.obytes;
} else {
dir = PACKET_DIR_INC;
for (qid = 0; qid < num_queues[dir]; qid++) {
queue_stats_[dir][qid].packets = stats.q_ipackets[qid];
queue_stats_[dir][qid].bytes = stats.q_ibytes[qid];
queue_stats_[dir][qid].dropped = stats.q_errors[qid];
}

dir = PACKET_DIR_OUT;
for (qid = 0; qid < num_queues[dir]; qid++) {
queue_stats_[dir][qid].packets = stats.q_opackets[qid];
queue_stats_[dir][qid].bytes = stats.q_obytes[qid];
}
}
}

Expand Down