Commit 2368957a authored by David S. Miller's avatar David S. Miller

Merge branch 'cxgb4-move-stats-fetched-from-firmware-to-debugfs'

Rahul Lakkireddy says:

====================
cxgb4: move stats fetched from firmware to debugfs

Some stats are fetched via slow firmware mailbox, which can cause
packet drops under heavy load. So, this series removes these stats
from ethtool -S and expose them via debugfs.

Patch 1 removes stats fetched via firmware from ethtool -S.
Patch 2 exposes stats removed in Patch 1 via debugfs.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b32b0881 31e5f5c3
......@@ -2962,6 +2962,169 @@ static const struct file_operations chcr_stats_debugfs_fops = {
.llseek = seq_lseek,
.release = single_release,
};
#define PRINT_ADAP_STATS(string, value) \
seq_printf(seq, "%-25s %-20llu\n", (string), \
(unsigned long long)(value))
#define PRINT_CH_STATS(string, value) \
do { \
seq_printf(seq, "%-25s ", (string)); \
for (i = 0; i < adap->params.arch.nchan; i++) \
seq_printf(seq, "%-20llu ", \
(unsigned long long)stats.value[i]); \
seq_printf(seq, "\n"); \
} while (0)
#define PRINT_CH_STATS2(string, value) \
do { \
seq_printf(seq, "%-25s ", (string)); \
for (i = 0; i < adap->params.arch.nchan; i++) \
seq_printf(seq, "%-20llu ", \
(unsigned long long)stats[i].value); \
seq_printf(seq, "\n"); \
} while (0)
static void show_tcp_stats(struct seq_file *seq)
{
struct adapter *adap = seq->private;
struct tp_tcp_stats v4, v6;
spin_lock(&adap->stats_lock);
t4_tp_get_tcp_stats(adap, &v4, &v6, false);
spin_unlock(&adap->stats_lock);
PRINT_ADAP_STATS("tcp_ipv4_out_rsts:", v4.tcp_out_rsts);
PRINT_ADAP_STATS("tcp_ipv4_in_segs:", v4.tcp_in_segs);
PRINT_ADAP_STATS("tcp_ipv4_out_segs:", v4.tcp_out_segs);
PRINT_ADAP_STATS("tcp_ipv4_retrans_segs:", v4.tcp_retrans_segs);
PRINT_ADAP_STATS("tcp_ipv6_out_rsts:", v6.tcp_out_rsts);
PRINT_ADAP_STATS("tcp_ipv6_in_segs:", v6.tcp_in_segs);
PRINT_ADAP_STATS("tcp_ipv6_out_segs:", v6.tcp_out_segs);
PRINT_ADAP_STATS("tcp_ipv6_retrans_segs:", v6.tcp_retrans_segs);
}
static void show_ddp_stats(struct seq_file *seq)
{
struct adapter *adap = seq->private;
struct tp_usm_stats stats;
spin_lock(&adap->stats_lock);
t4_get_usm_stats(adap, &stats, false);
spin_unlock(&adap->stats_lock);
PRINT_ADAP_STATS("usm_ddp_frames:", stats.frames);
PRINT_ADAP_STATS("usm_ddp_octets:", stats.octets);
PRINT_ADAP_STATS("usm_ddp_drops:", stats.drops);
}
static void show_rdma_stats(struct seq_file *seq)
{
struct adapter *adap = seq->private;
struct tp_rdma_stats stats;
spin_lock(&adap->stats_lock);
t4_tp_get_rdma_stats(adap, &stats, false);
spin_unlock(&adap->stats_lock);
PRINT_ADAP_STATS("rdma_no_rqe_mod_defer:", stats.rqe_dfr_mod);
PRINT_ADAP_STATS("rdma_no_rqe_pkt_defer:", stats.rqe_dfr_pkt);
}
static void show_tp_err_adapter_stats(struct seq_file *seq)
{
struct adapter *adap = seq->private;
struct tp_err_stats stats;
spin_lock(&adap->stats_lock);
t4_tp_get_err_stats(adap, &stats, false);
spin_unlock(&adap->stats_lock);
PRINT_ADAP_STATS("tp_err_ofld_no_neigh:", stats.ofld_no_neigh);
PRINT_ADAP_STATS("tp_err_ofld_cong_defer:", stats.ofld_cong_defer);
}
static void show_cpl_stats(struct seq_file *seq)
{
struct adapter *adap = seq->private;
struct tp_cpl_stats stats;
u8 i;
spin_lock(&adap->stats_lock);
t4_tp_get_cpl_stats(adap, &stats, false);
spin_unlock(&adap->stats_lock);
PRINT_CH_STATS("tp_cpl_requests:", req);
PRINT_CH_STATS("tp_cpl_responses:", rsp);
}
static void show_tp_err_channel_stats(struct seq_file *seq)
{
struct adapter *adap = seq->private;
struct tp_err_stats stats;
u8 i;
spin_lock(&adap->stats_lock);
t4_tp_get_err_stats(adap, &stats, false);
spin_unlock(&adap->stats_lock);
PRINT_CH_STATS("tp_mac_in_errs:", mac_in_errs);
PRINT_CH_STATS("tp_hdr_in_errs:", hdr_in_errs);
PRINT_CH_STATS("tp_tcp_in_errs:", tcp_in_errs);
PRINT_CH_STATS("tp_tcp6_in_errs:", tcp6_in_errs);
PRINT_CH_STATS("tp_tnl_cong_drops:", tnl_cong_drops);
PRINT_CH_STATS("tp_tnl_tx_drops:", tnl_tx_drops);
PRINT_CH_STATS("tp_ofld_vlan_drops:", ofld_vlan_drops);
PRINT_CH_STATS("tp_ofld_chan_drops:", ofld_chan_drops);
}
static void show_fcoe_stats(struct seq_file *seq)
{
struct adapter *adap = seq->private;
struct tp_fcoe_stats stats[NCHAN];
u8 i;
spin_lock(&adap->stats_lock);
for (i = 0; i < adap->params.arch.nchan; i++)
t4_get_fcoe_stats(adap, i, &stats[i], false);
spin_unlock(&adap->stats_lock);
PRINT_CH_STATS2("fcoe_octets_ddp", octets_ddp);
PRINT_CH_STATS2("fcoe_frames_ddp", frames_ddp);
PRINT_CH_STATS2("fcoe_frames_drop", frames_drop);
}
#undef PRINT_CH_STATS2
#undef PRINT_CH_STATS
#undef PRINT_ADAP_STATS
static int tp_stats_show(struct seq_file *seq, void *v)
{
struct adapter *adap = seq->private;
seq_puts(seq, "\n--------Adapter Stats--------\n");
show_tcp_stats(seq);
show_ddp_stats(seq);
show_rdma_stats(seq);
show_tp_err_adapter_stats(seq);
seq_puts(seq, "\n-------- Channel Stats --------\n");
if (adap->params.arch.nchan == NCHAN)
seq_printf(seq, "%-25s %-20s %-20s %-20s %-20s\n",
" ", "channel 0", "channel 1",
"channel 2", "channel 3");
else
seq_printf(seq, "%-25s %-20s %-20s\n",
" ", "channel 0", "channel 1");
show_cpl_stats(seq);
show_tp_err_channel_stats(seq);
show_fcoe_stats(seq);
return 0;
}
DEFINE_SIMPLE_DEBUGFS_FILE(tp_stats);
/* Add an array of Debug FS files.
*/
void add_debugfs_files(struct adapter *adap,
......@@ -3038,6 +3201,7 @@ int t4_setup_debugfs(struct adapter *adap)
{ "blocked_fl", &blocked_fl_fops, 0600, 0 },
{ "meminfo", &meminfo_fops, 0400, 0 },
{ "crypto", &chcr_stats_debugfs_fops, 0400, 0 },
{ "tp_stats", &tp_stats_debugfs_fops, 0400, 0 },
};
/* Debug FS nodes common to all T5 and later adapters.
......
......@@ -115,42 +115,10 @@ static char adapter_stats_strings[][ETH_GSTRING_LEN] = {
"db_drop ",
"db_full ",
"db_empty ",
"tcp_ipv4_out_rsts ",
"tcp_ipv4_in_segs ",
"tcp_ipv4_out_segs ",
"tcp_ipv4_retrans_segs ",
"tcp_ipv6_out_rsts ",
"tcp_ipv6_in_segs ",
"tcp_ipv6_out_segs ",
"tcp_ipv6_retrans_segs ",
"usm_ddp_frames ",
"usm_ddp_octets ",
"usm_ddp_drops ",
"rdma_no_rqe_mod_defer ",
"rdma_no_rqe_pkt_defer ",
"tp_err_ofld_no_neigh ",
"tp_err_ofld_cong_defer ",
"write_coal_success ",
"write_coal_fail ",
};
static char channel_stats_strings[][ETH_GSTRING_LEN] = {
"--------Channel--------- ",
"tp_cpl_requests ",
"tp_cpl_responses ",
"tp_mac_in_errs ",
"tp_hdr_in_errs ",
"tp_tcp_in_errs ",
"tp_tcp6_in_errs ",
"tp_tnl_cong_drops ",
"tp_tnl_tx_drops ",
"tp_ofld_vlan_drops ",
"tp_ofld_chan_drops ",
"fcoe_octets_ddp ",
"fcoe_frames_ddp ",
"fcoe_frames_drop ",
};
static char loopback_stats_strings[][ETH_GSTRING_LEN] = {
"-------Loopback----------- ",
"octets_ok ",
......@@ -187,7 +155,6 @@ static int get_sset_count(struct net_device *dev, int sset)
case ETH_SS_STATS:
return ARRAY_SIZE(stats_strings) +
ARRAY_SIZE(adapter_stats_strings) +
ARRAY_SIZE(channel_stats_strings) +
ARRAY_SIZE(loopback_stats_strings);
case ETH_SS_PRIV_FLAGS:
return ARRAY_SIZE(cxgb4_priv_flags_strings);
......@@ -252,9 +219,6 @@ static void get_strings(struct net_device *dev, u32 stringset, u8 *data)
memcpy(data, adapter_stats_strings,
sizeof(adapter_stats_strings));
data += sizeof(adapter_stats_strings);
memcpy(data, channel_stats_strings,
sizeof(channel_stats_strings));
data += sizeof(channel_stats_strings);
memcpy(data, loopback_stats_strings,
sizeof(loopback_stats_strings));
} else if (stringset == ETH_SS_PRIV_FLAGS) {
......@@ -280,41 +244,10 @@ struct adapter_stats {
u64 db_drop;
u64 db_full;
u64 db_empty;
u64 tcp_v4_out_rsts;
u64 tcp_v4_in_segs;
u64 tcp_v4_out_segs;
u64 tcp_v4_retrans_segs;
u64 tcp_v6_out_rsts;
u64 tcp_v6_in_segs;
u64 tcp_v6_out_segs;
u64 tcp_v6_retrans_segs;
u64 frames;
u64 octets;
u64 drops;
u64 rqe_dfr_mod;
u64 rqe_dfr_pkt;
u64 ofld_no_neigh;
u64 ofld_cong_defer;
u64 wc_success;
u64 wc_fail;
};
struct channel_stats {
u64 cpl_req;
u64 cpl_rsp;
u64 mac_in_errs;
u64 hdr_in_errs;
u64 tcp_in_errs;
u64 tcp6_in_errs;
u64 tnl_cong_drops;
u64 tnl_tx_drops;
u64 ofld_vlan_drops;
u64 ofld_chan_drops;
u64 octets_ddp;
u64 frames_ddp;
u64 frames_drop;
};
static void collect_sge_port_stats(const struct adapter *adap,
const struct port_info *p,
struct queue_port_stats *s)
......@@ -337,45 +270,14 @@ static void collect_sge_port_stats(const struct adapter *adap,
static void collect_adapter_stats(struct adapter *adap, struct adapter_stats *s)
{
struct tp_tcp_stats v4, v6;
struct tp_rdma_stats rdma_stats;
struct tp_err_stats err_stats;
struct tp_usm_stats usm_stats;
u64 val1, val2;
memset(s, 0, sizeof(*s));
spin_lock(&adap->stats_lock);
t4_tp_get_tcp_stats(adap, &v4, &v6, false);
t4_tp_get_rdma_stats(adap, &rdma_stats, false);
t4_get_usm_stats(adap, &usm_stats, false);
t4_tp_get_err_stats(adap, &err_stats, false);
spin_unlock(&adap->stats_lock);
s->db_drop = adap->db_stats.db_drop;
s->db_full = adap->db_stats.db_full;
s->db_empty = adap->db_stats.db_empty;
s->tcp_v4_out_rsts = v4.tcp_out_rsts;
s->tcp_v4_in_segs = v4.tcp_in_segs;
s->tcp_v4_out_segs = v4.tcp_out_segs;
s->tcp_v4_retrans_segs = v4.tcp_retrans_segs;
s->tcp_v6_out_rsts = v6.tcp_out_rsts;
s->tcp_v6_in_segs = v6.tcp_in_segs;
s->tcp_v6_out_segs = v6.tcp_out_segs;
s->tcp_v6_retrans_segs = v6.tcp_retrans_segs;
if (is_offload(adap)) {
s->frames = usm_stats.frames;
s->octets = usm_stats.octets;
s->drops = usm_stats.drops;
s->rqe_dfr_mod = rdma_stats.rqe_dfr_mod;
s->rqe_dfr_pkt = rdma_stats.rqe_dfr_pkt;
}
s->ofld_no_neigh = err_stats.ofld_no_neigh;
s->ofld_cong_defer = err_stats.ofld_cong_defer;
if (!is_t4(adap->params.chip)) {
int v;
......@@ -389,36 +291,6 @@ static void collect_adapter_stats(struct adapter *adap, struct adapter_stats *s)
}
}
static void collect_channel_stats(struct adapter *adap, struct channel_stats *s,
u8 i)
{
struct tp_cpl_stats cpl_stats;
struct tp_err_stats err_stats;
struct tp_fcoe_stats fcoe_stats;
memset(s, 0, sizeof(*s));
spin_lock(&adap->stats_lock);
t4_tp_get_cpl_stats(adap, &cpl_stats, false);
t4_tp_get_err_stats(adap, &err_stats, false);
t4_get_fcoe_stats(adap, i, &fcoe_stats, false);
spin_unlock(&adap->stats_lock);
s->cpl_req = cpl_stats.req[i];
s->cpl_rsp = cpl_stats.rsp[i];
s->mac_in_errs = err_stats.mac_in_errs[i];
s->hdr_in_errs = err_stats.hdr_in_errs[i];
s->tcp_in_errs = err_stats.tcp_in_errs[i];
s->tcp6_in_errs = err_stats.tcp6_in_errs[i];
s->tnl_cong_drops = err_stats.tnl_cong_drops[i];
s->tnl_tx_drops = err_stats.tnl_tx_drops[i];
s->ofld_vlan_drops = err_stats.ofld_vlan_drops[i];
s->ofld_chan_drops = err_stats.ofld_chan_drops[i];
s->octets_ddp = fcoe_stats.octets_ddp;
s->frames_ddp = fcoe_stats.frames_ddp;
s->frames_drop = fcoe_stats.frames_drop;
}
static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
u64 *data)
{
......@@ -438,11 +310,6 @@ static void get_stats(struct net_device *dev, struct ethtool_stats *stats,
collect_adapter_stats(adapter, (struct adapter_stats *)data);
data += sizeof(struct adapter_stats) / sizeof(u64);
*data++ = (u64)pi->port_id;
collect_channel_stats(adapter, (struct channel_stats *)data,
pi->port_id);
data += sizeof(struct channel_stats) / sizeof(u64);
*data++ = (u64)pi->port_id;
memset(&s, 0, sizeof(s));
t4_get_lb_stats(adapter, pi->port_id, &s);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment