|
@@ -396,36 +396,44 @@ void be_parse_stats(struct be_adapter *adapter)
|
|
erx->rx_drops_no_fragments[rxo->q.id];
|
|
erx->rx_drops_no_fragments[rxo->q.id];
|
|
}
|
|
}
|
|
|
|
|
|
-void netdev_stats_update(struct be_adapter *adapter)
|
|
|
|
|
|
+static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev,
|
|
|
|
+ struct rtnl_link_stats64 *stats)
|
|
{
|
|
{
|
|
|
|
+ struct be_adapter *adapter = netdev_priv(netdev);
|
|
struct be_drv_stats *drvs = &adapter->drv_stats;
|
|
struct be_drv_stats *drvs = &adapter->drv_stats;
|
|
- struct net_device_stats *dev_stats = &adapter->netdev->stats;
|
|
|
|
struct be_rx_obj *rxo;
|
|
struct be_rx_obj *rxo;
|
|
struct be_tx_obj *txo;
|
|
struct be_tx_obj *txo;
|
|
- unsigned long pkts = 0, bytes = 0, mcast = 0, drops = 0;
|
|
|
|
|
|
+ u64 pkts, bytes;
|
|
|
|
+ unsigned int start;
|
|
int i;
|
|
int i;
|
|
|
|
|
|
for_all_rx_queues(adapter, rxo, i) {
|
|
for_all_rx_queues(adapter, rxo, i) {
|
|
- pkts += rx_stats(rxo)->rx_pkts;
|
|
|
|
- bytes += rx_stats(rxo)->rx_bytes;
|
|
|
|
- mcast += rx_stats(rxo)->rx_mcast_pkts;
|
|
|
|
- drops += rx_stats(rxo)->rx_drops_no_skbs;
|
|
|
|
|
|
+ const struct be_rx_stats *rx_stats = rx_stats(rxo);
|
|
|
|
+ do {
|
|
|
|
+ start = u64_stats_fetch_begin_bh(&rx_stats->sync);
|
|
|
|
+ pkts = rx_stats(rxo)->rx_pkts;
|
|
|
|
+ bytes = rx_stats(rxo)->rx_bytes;
|
|
|
|
+ } while (u64_stats_fetch_retry_bh(&rx_stats->sync, start));
|
|
|
|
+ stats->rx_packets += pkts;
|
|
|
|
+ stats->rx_bytes += bytes;
|
|
|
|
+ stats->multicast += rx_stats(rxo)->rx_mcast_pkts;
|
|
|
|
+ stats->rx_dropped += rx_stats(rxo)->rx_drops_no_skbs +
|
|
|
|
+ rx_stats(rxo)->rx_drops_no_frags;
|
|
}
|
|
}
|
|
- dev_stats->rx_packets = pkts;
|
|
|
|
- dev_stats->rx_bytes = bytes;
|
|
|
|
- dev_stats->multicast = mcast;
|
|
|
|
- dev_stats->rx_dropped = drops;
|
|
|
|
|
|
|
|
- pkts = bytes = 0;
|
|
|
|
for_all_tx_queues(adapter, txo, i) {
|
|
for_all_tx_queues(adapter, txo, i) {
|
|
- pkts += tx_stats(txo)->tx_pkts;
|
|
|
|
- bytes += tx_stats(txo)->tx_bytes;
|
|
|
|
|
|
+ const struct be_tx_stats *tx_stats = tx_stats(txo);
|
|
|
|
+ do {
|
|
|
|
+ start = u64_stats_fetch_begin_bh(&tx_stats->sync);
|
|
|
|
+ pkts = tx_stats(txo)->tx_pkts;
|
|
|
|
+ bytes = tx_stats(txo)->tx_bytes;
|
|
|
|
+ } while (u64_stats_fetch_retry_bh(&tx_stats->sync, start));
|
|
|
|
+ stats->tx_packets += pkts;
|
|
|
|
+ stats->tx_bytes += bytes;
|
|
}
|
|
}
|
|
- dev_stats->tx_packets = pkts;
|
|
|
|
- dev_stats->tx_bytes = bytes;
|
|
|
|
|
|
|
|
/* bad pkts received */
|
|
/* bad pkts received */
|
|
- dev_stats->rx_errors = drvs->rx_crc_errors +
|
|
|
|
|
|
+ stats->rx_errors = drvs->rx_crc_errors +
|
|
drvs->rx_alignment_symbol_errors +
|
|
drvs->rx_alignment_symbol_errors +
|
|
drvs->rx_in_range_errors +
|
|
drvs->rx_in_range_errors +
|
|
drvs->rx_out_range_errors +
|
|
drvs->rx_out_range_errors +
|
|
@@ -434,26 +442,24 @@ void netdev_stats_update(struct be_adapter *adapter)
|
|
drvs->rx_dropped_too_short +
|
|
drvs->rx_dropped_too_short +
|
|
drvs->rx_dropped_header_too_small +
|
|
drvs->rx_dropped_header_too_small +
|
|
drvs->rx_dropped_tcp_length +
|
|
drvs->rx_dropped_tcp_length +
|
|
- drvs->rx_dropped_runt +
|
|
|
|
- drvs->rx_tcp_checksum_errs +
|
|
|
|
- drvs->rx_ip_checksum_errs +
|
|
|
|
- drvs->rx_udp_checksum_errs;
|
|
|
|
|
|
+ drvs->rx_dropped_runt;
|
|
|
|
|
|
/* detailed rx errors */
|
|
/* detailed rx errors */
|
|
- dev_stats->rx_length_errors = drvs->rx_in_range_errors +
|
|
|
|
|
|
+ stats->rx_length_errors = drvs->rx_in_range_errors +
|
|
drvs->rx_out_range_errors +
|
|
drvs->rx_out_range_errors +
|
|
drvs->rx_frame_too_long;
|
|
drvs->rx_frame_too_long;
|
|
|
|
|
|
- dev_stats->rx_crc_errors = drvs->rx_crc_errors;
|
|
|
|
|
|
+ stats->rx_crc_errors = drvs->rx_crc_errors;
|
|
|
|
|
|
/* frame alignment errors */
|
|
/* frame alignment errors */
|
|
- dev_stats->rx_frame_errors = drvs->rx_alignment_symbol_errors;
|
|
|
|
|
|
+ stats->rx_frame_errors = drvs->rx_alignment_symbol_errors;
|
|
|
|
|
|
/* receiver fifo overrun */
|
|
/* receiver fifo overrun */
|
|
/* drops_no_pbuf is no per i/f, it's per BE card */
|
|
/* drops_no_pbuf is no per i/f, it's per BE card */
|
|
- dev_stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop +
|
|
|
|
|
|
+ stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop +
|
|
drvs->rx_input_fifo_overflow_drop +
|
|
drvs->rx_input_fifo_overflow_drop +
|
|
drvs->rx_drops_no_pbuf;
|
|
drvs->rx_drops_no_pbuf;
|
|
|
|
+ return stats;
|
|
}
|
|
}
|
|
|
|
|
|
void be_link_status_update(struct be_adapter *adapter, bool link_up)
|
|
void be_link_status_update(struct be_adapter *adapter, bool link_up)
|
|
@@ -479,12 +485,14 @@ static void be_tx_stats_update(struct be_tx_obj *txo,
|
|
{
|
|
{
|
|
struct be_tx_stats *stats = tx_stats(txo);
|
|
struct be_tx_stats *stats = tx_stats(txo);
|
|
|
|
|
|
|
|
+ u64_stats_update_begin(&stats->sync);
|
|
stats->tx_reqs++;
|
|
stats->tx_reqs++;
|
|
stats->tx_wrbs += wrb_cnt;
|
|
stats->tx_wrbs += wrb_cnt;
|
|
stats->tx_bytes += copied;
|
|
stats->tx_bytes += copied;
|
|
stats->tx_pkts += (gso_segs ? gso_segs : 1);
|
|
stats->tx_pkts += (gso_segs ? gso_segs : 1);
|
|
if (stopped)
|
|
if (stopped)
|
|
stats->tx_stops++;
|
|
stats->tx_stops++;
|
|
|
|
+ u64_stats_update_end(&stats->sync);
|
|
}
|
|
}
|
|
|
|
|
|
/* Determine number of WRB entries needed to xmit data in an skb */
|
|
/* Determine number of WRB entries needed to xmit data in an skb */
|
|
@@ -905,7 +913,8 @@ static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo)
|
|
struct be_rx_stats *stats = rx_stats(rxo);
|
|
struct be_rx_stats *stats = rx_stats(rxo);
|
|
ulong now = jiffies;
|
|
ulong now = jiffies;
|
|
ulong delta = now - stats->rx_jiffies;
|
|
ulong delta = now - stats->rx_jiffies;
|
|
- u32 eqd;
|
|
|
|
|
|
+ u64 pkts;
|
|
|
|
+ unsigned int start, eqd;
|
|
|
|
|
|
if (!rx_eq->enable_aic)
|
|
if (!rx_eq->enable_aic)
|
|
return;
|
|
return;
|
|
@@ -920,8 +929,13 @@ static void be_rx_eqd_update(struct be_adapter *adapter, struct be_rx_obj *rxo)
|
|
if (delta < HZ)
|
|
if (delta < HZ)
|
|
return;
|
|
return;
|
|
|
|
|
|
- stats->rx_pps = (stats->rx_pkts - stats->rx_pkts_prev) / (delta / HZ);
|
|
|
|
- stats->rx_pkts_prev = stats->rx_pkts;
|
|
|
|
|
|
+ do {
|
|
|
|
+ start = u64_stats_fetch_begin_bh(&stats->sync);
|
|
|
|
+ pkts = stats->rx_pkts;
|
|
|
|
+ } while (u64_stats_fetch_retry_bh(&stats->sync, start));
|
|
|
|
+
|
|
|
|
+ stats->rx_pps = (pkts - stats->rx_pkts_prev) / (delta / HZ);
|
|
|
|
+ stats->rx_pkts_prev = pkts;
|
|
stats->rx_jiffies = now;
|
|
stats->rx_jiffies = now;
|
|
eqd = stats->rx_pps / 110000;
|
|
eqd = stats->rx_pps / 110000;
|
|
eqd = eqd << 3;
|
|
eqd = eqd << 3;
|
|
@@ -942,6 +956,7 @@ static void be_rx_stats_update(struct be_rx_obj *rxo,
|
|
{
|
|
{
|
|
struct be_rx_stats *stats = rx_stats(rxo);
|
|
struct be_rx_stats *stats = rx_stats(rxo);
|
|
|
|
|
|
|
|
+ u64_stats_update_begin(&stats->sync);
|
|
stats->rx_compl++;
|
|
stats->rx_compl++;
|
|
stats->rx_bytes += rxcp->pkt_size;
|
|
stats->rx_bytes += rxcp->pkt_size;
|
|
stats->rx_pkts++;
|
|
stats->rx_pkts++;
|
|
@@ -949,6 +964,7 @@ static void be_rx_stats_update(struct be_rx_obj *rxo,
|
|
stats->rx_mcast_pkts++;
|
|
stats->rx_mcast_pkts++;
|
|
if (rxcp->err)
|
|
if (rxcp->err)
|
|
stats->rx_compl_err++;
|
|
stats->rx_compl_err++;
|
|
|
|
+ u64_stats_update_end(&stats->sync);
|
|
}
|
|
}
|
|
|
|
|
|
static inline bool csum_passed(struct be_rx_compl_info *rxcp)
|
|
static inline bool csum_passed(struct be_rx_compl_info *rxcp)
|
|
@@ -1878,8 +1894,9 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
|
|
netif_wake_subqueue(adapter->netdev, i);
|
|
netif_wake_subqueue(adapter->netdev, i);
|
|
}
|
|
}
|
|
|
|
|
|
- adapter->drv_stats.tx_events++;
|
|
|
|
|
|
+ u64_stats_update_begin(&tx_stats(txo)->sync_compl);
|
|
tx_stats(txo)->tx_compl += tx_compl;
|
|
tx_stats(txo)->tx_compl += tx_compl;
|
|
|
|
+ u64_stats_update_end(&tx_stats(txo)->sync_compl);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1893,6 +1910,7 @@ static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
|
|
napi_complete(napi);
|
|
napi_complete(napi);
|
|
|
|
|
|
be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
|
|
be_eq_notify(adapter, tx_eq->q.id, true, false, 0);
|
|
|
|
+ adapter->drv_stats.tx_events++;
|
|
return 1;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2843,6 +2861,7 @@ static struct net_device_ops be_netdev_ops = {
|
|
.ndo_set_rx_mode = be_set_multicast_list,
|
|
.ndo_set_rx_mode = be_set_multicast_list,
|
|
.ndo_set_mac_address = be_mac_addr_set,
|
|
.ndo_set_mac_address = be_mac_addr_set,
|
|
.ndo_change_mtu = be_change_mtu,
|
|
.ndo_change_mtu = be_change_mtu,
|
|
|
|
+ .ndo_get_stats64 = be_get_stats64,
|
|
.ndo_validate_addr = eth_validate_addr,
|
|
.ndo_validate_addr = eth_validate_addr,
|
|
.ndo_vlan_rx_add_vid = be_vlan_add_vid,
|
|
.ndo_vlan_rx_add_vid = be_vlan_add_vid,
|
|
.ndo_vlan_rx_kill_vid = be_vlan_rem_vid,
|
|
.ndo_vlan_rx_kill_vid = be_vlan_rem_vid,
|