From: Chiqijun chiqijun@huawei.com
driver inclusion category: bugfix bugzilla: 4472
-----------------------------------------------------------------------
If the hinic driver fails to alloc memory during the packet receiving process, it will print two logs. When the system memory is probabilistically insufficient, the hinic device will print logs repeatedly, causing system oops. Use statistics instead of logging in the IO process.
Signed-off-by: Chiqijun chiqijun@huawei.com Reviewed-by: Wangxiaoyun cloud.wangxiaoyun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- .../net/ethernet/huawei/hinic/hinic_ethtool.c | 3 +++ drivers/net/ethernet/huawei/hinic/hinic_main.c | 3 ++- drivers/net/ethernet/huawei/hinic/hinic_rx.c | 18 ++++++++++-------- drivers/net/ethernet/huawei/hinic/hinic_rx.h | 3 +++ 4 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c index ff6a3d7fe9ad..9fa5af2dacce 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c @@ -114,10 +114,13 @@ static struct hinic_stats hinic_rx_queue_stats[] = { HINIC_RXQ_STAT(csum_errors), HINIC_RXQ_STAT(other_errors), HINIC_RXQ_STAT(dropped), + HINIC_RXQ_STAT(rx_buf_empty), };
static struct hinic_stats hinic_rx_queue_stats_extern[] = { HINIC_RXQ_STAT(alloc_skb_err), + HINIC_RXQ_STAT(alloc_rx_buf_err), + HINIC_RXQ_STAT(map_rx_buf_err), };
static struct hinic_stats hinic_tx_queue_stats[] = { diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index 26cd2929f60a..d0c4bdf7383c 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -137,7 +137,8 @@ MODULE_PARM_DESC(qp_coalesc_timer_high, "MSI-X adaptive high coalesce time, rang
#define HINIC_NIC_DEV_WQ_NAME "hinic_nic_dev_wq"
-#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_LINK) +#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_LINK | \ + NETIF_MSG_RX_ERR)
#define QID_MASKED(q_id, nic_dev) ((q_id) & ((nic_dev)->num_qps - 1))
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.c b/drivers/net/ethernet/huawei/hinic/hinic_rx.c index 0f597c38c02d..212a281200c4 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_rx.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.c @@ -69,8 +69,7 @@ static bool rx_alloc_mapped_page(struct hinic_rxq *rxq, /* alloc new page for storage */ page = alloc_pages_node(NUMA_NO_NODE, GFP_ATOMIC, nic_dev->page_order); if (unlikely(!page)) { - nicif_err(nic_dev, drv, netdev, "Alloc rxq: %d page failed\n", - rxq->q_id); + RXQ_STATS_INC(rxq, alloc_rx_buf_err); return false; }
@@ -82,7 +81,7 @@ static bool rx_alloc_mapped_page(struct hinic_rxq *rxq, * there isn't much point in holding memory we can't use */ if (unlikely(dma_mapping_error(&pdev->dev, dma))) { - nicif_err(nic_dev, drv, netdev, "Failed to map page to rx buffer\n"); + RXQ_STATS_INC(rxq, map_rx_buf_err); __free_pages(page, nic_dev->page_order); return false; } @@ -162,9 +161,8 @@ static int hinic_rx_fill_buffers(struct hinic_rxq *rxq) rxq->next_to_update); rxq->delta -= i; rxq->next_to_alloc = rxq->next_to_update; - } else { - nicif_err(nic_dev, drv, netdev, "Failed to allocate rx buffers, rxq id: %d\n", - rxq->q_id); + } else if (free_wqebbs == rxq->q_depth - 1) { + RXQ_STATS_INC(rxq, rx_buf_empty); }
return i; @@ -385,6 +383,7 @@ void hinic_rxq_get_stats(struct hinic_rxq *rxq, stats->csum_errors = rxq_stats->csum_errors; stats->other_errors = rxq_stats->other_errors; stats->dropped = rxq_stats->dropped; + stats->rx_buf_empty = rxq_stats->rx_buf_empty; } while (u64_stats_fetch_retry(&rxq_stats->syncp, start)); u64_stats_update_end(&stats->syncp); } @@ -400,6 +399,9 @@ void hinic_rxq_clean_stats(struct hinic_rxq_stats *rxq_stats) rxq_stats->dropped = 0;
rxq_stats->alloc_skb_err = 0; + rxq_stats->alloc_rx_buf_err = 0; + rxq_stats->map_rx_buf_err = 0; + rxq_stats->rx_buf_empty = 0; u64_stats_update_end(&rxq_stats->syncp); }
@@ -486,11 +488,11 @@ static void hinic_copy_lp_data(struct hinic_nic_dev *nic_dev,
if (nic_dev->lb_test_rx_idx == LP_PKT_CNT) { nic_dev->lb_test_rx_idx = 0; - nicif_warn(nic_dev, drv, netdev, "Loopback test warning, recive too more test pkt\n"); + nicif_warn(nic_dev, rx_err, netdev, "Loopback test warning, recive too more test pkt\n"); }
if (skb->len != nic_dev->lb_pkt_len) { - nicif_warn(nic_dev, drv, netdev, "Wrong packet length\n"); + nicif_warn(nic_dev, rx_err, netdev, "Wrong packet length\n"); nic_dev->lb_test_rx_idx++; return; } diff --git a/drivers/net/ethernet/huawei/hinic/hinic_rx.h b/drivers/net/ethernet/huawei/hinic/hinic_rx.h index 09f8784157cf..b6e8935c01d4 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_rx.h +++ b/drivers/net/ethernet/huawei/hinic/hinic_rx.h @@ -37,8 +37,11 @@ struct hinic_rxq_stats { u64 csum_errors; u64 other_errors; u64 dropped; + u64 rx_buf_empty;
u64 alloc_skb_err; + u64 alloc_rx_buf_err; + u64 map_rx_buf_err;
struct u64_stats_sync syncp; };