Skip to content

Commit

Permalink
cxgb4: expose stats fetched from firmware via debugfs
Browse files Browse the repository at this point in the history
Expose stats obtained from firmware via debugfs. These stats can't
be part of ethtool -S because the slow firmware mailbox can cause
packet drops under heavy load.

Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Rahul Lakkireddy authored and David S. Miller committed Jul 12, 2018
1 parent b351b16 commit 31e5f5c
Showing 1 changed file with 164 additions and 0 deletions.
164 changes: 164 additions & 0 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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.
Expand Down

0 comments on commit 31e5f5c

Please sign in to comment.