From nobody Sun Feb 8 22:00:49 2026 Received: from canpmsgout09.his.huawei.com (canpmsgout09.his.huawei.com [113.46.200.224]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7E1083019B2; Fri, 14 Nov 2025 09:23:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.224 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763112201; cv=none; b=qxNx3S3yxh68RKilNQaoBDd/u3hs6LuR8Rm/Pb1b6r66pC5rcFTyMxLXBQDNyuofPzl0zdSnq5SE3IPN9kJCYhOQW4y+GvuDqemidQ+F6WXSgL+K9yAwLpCh7EhMLRxbTLFW6Z6JXuS+Vwn9tWFqncO6BYJH8uF0g4mbPXQyFr0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763112201; c=relaxed/simple; bh=qhA9HrVIyGp0rmSliY21AI+PexOFbnsS0md6s/x5L+E=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=B7cfnnqUpNjJQWxfYKDLNZJg1tuZrQAuM8RelPUv3/N0OiTXRULqc8xcslgv0pzgQDHLVtdWXg2vowk0khwPkpLh+Cpk1MUoAexM8NZHlM4HgVVCUPEJ0Gtpa8VcDe7hah8Vu7lTpgcZwushC8fQekQomiHHpKHlKV1jlvT21ns= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=fqyGTAkT; arc=none smtp.client-ip=113.46.200.224 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="fqyGTAkT" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=JxI/9OTgPKE8lW7Ar+EpvZl1IaGpbnnrdXqbr/0/GKg=; b=fqyGTAkT82mLn2s2B/oekByWKPiGqmdByJtdpAQ9x30oQudJL5g8xSIBK7Rv657Hu5iEYjfeL RQsGbgED2+HqB5fU+tMLBN7unXZfAOlrxF/6hkOI2lPWXkmMHyUBekEAknbvd+v8WtdokWgbGpg ITOf9iu2/5vzaY/Jn/0LZ0g= Received: from mail.maildlp.com (unknown [172.19.88.214]) by canpmsgout09.his.huawei.com (SkyGuard) with ESMTPS id 4d7BTq0QrVz1cyR3; Fri, 14 Nov 2025 17:21:35 +0800 (CST) Received: from kwepemk100013.china.huawei.com (unknown [7.202.194.61]) by mail.maildlp.com (Postfix) with ESMTPS id 18F8A1A016C; Fri, 14 Nov 2025 17:23:16 +0800 (CST) Received: from localhost.localdomain (10.90.31.46) by kwepemk100013.china.huawei.com (7.202.194.61) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Fri, 14 Nov 2025 17:23:15 +0800 From: Jijie Shao To: , , , , , CC: , , , , , , , , , , Subject: [PATCH net-next 1/3] net: hibmcge: Add tracepoint function to print some fields of rx_desc Date: Fri, 14 Nov 2025 17:22:20 +0800 Message-ID: <20251114092222.2071583-2-shaojijie@huawei.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20251114092222.2071583-1-shaojijie@huawei.com> References: <20251114092222.2071583-1-shaojijie@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To kwepemk100013.china.huawei.com (7.202.194.61) Content-Type: text/plain; charset="utf-8" From: Tao Lan Add tracepoint function to print some fields of rx_desc Signed-off-by: Tao Lan Signed-off-by: Jijie Shao --- .../net/ethernet/hisilicon/hibmcge/Makefile | 1 + .../net/ethernet/hisilicon/hibmcge/hbg_reg.h | 4 + .../ethernet/hisilicon/hibmcge/hbg_trace.h | 84 +++++++++++++++++++ .../net/ethernet/hisilicon/hibmcge/hbg_txrx.c | 4 + 4 files changed, 93 insertions(+) create mode 100644 drivers/net/ethernet/hisilicon/hibmcge/hbg_trace.h diff --git a/drivers/net/ethernet/hisilicon/hibmcge/Makefile b/drivers/net/= ethernet/hisilicon/hibmcge/Makefile index 1a9da564b306..d6610ba16855 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/Makefile +++ b/drivers/net/ethernet/hisilicon/hibmcge/Makefile @@ -3,6 +3,7 @@ # Makefile for the HISILICON BMC GE network device drivers. # =20 +ccflags-y +=3D -I$(src) obj-$(CONFIG_HIBMCGE) +=3D hibmcge.o =20 hibmcge-objs =3D hbg_main.o hbg_hw.o hbg_mdio.o hbg_irq.o hbg_txrx.o hbg_e= thtool.o \ diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h b/drivers/net= /ethernet/hisilicon/hibmcge/hbg_reg.h index a39d1e796e4a..30b3903c8f2d 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_reg.h @@ -252,6 +252,8 @@ struct hbg_rx_desc { =20 #define HBG_RX_DESC_W2_PKT_LEN_M GENMASK(31, 16) #define HBG_RX_DESC_W2_PORT_NUM_M GENMASK(15, 12) +#define HBG_RX_DESC_W3_IP_OFFSET_M GENMASK(23, 16) +#define HBG_RX_DESC_W3_VLAN_M GENMASK(15, 0) #define HBG_RX_DESC_W4_IP_TCP_UDP_M GENMASK(31, 30) #define HBG_RX_DESC_W4_IPSEC_B BIT(29) #define HBG_RX_DESC_W4_IP_VERSION_B BIT(28) @@ -269,6 +271,8 @@ struct hbg_rx_desc { #define HBG_RX_DESC_W4_L3_ERR_CODE_M GENMASK(12, 9) #define HBG_RX_DESC_W4_L2_ERR_B BIT(8) #define HBG_RX_DESC_W4_IDX_MATCH_B BIT(7) +#define HBG_RX_DESC_W4_PARSE_MODE_M GENMASK(6, 5) +#define HBG_RX_DESC_W5_VALID_SIZE_M GENMASK(15, 0) =20 enum hbg_l3_err_code { HBG_L3_OK =3D 0, diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_trace.h b/drivers/n= et/ethernet/hisilicon/hibmcge/hbg_trace.h new file mode 100644 index 000000000000..b70fd960da8d --- /dev/null +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_trace.h @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* Copyright (c) 2025 Hisilicon Limited. */ + +/* This must be outside ifdef _HBG_TRACE_H */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM hibmcge + +#if !defined(_HBG_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) +#define _HBG_TRACE_H_ + +#include +#include +#include +#include +#include "hbg_reg.h" + +TRACE_EVENT(hbg_rx_desc, + TP_PROTO(struct hbg_priv *priv, u32 index, + struct hbg_rx_desc *rx_desc), + TP_ARGS(priv, index, rx_desc), + + TP_STRUCT__entry(__field(u32, index) + __field(u8, port_num) + __field(u8, ip_offset) + __field(u8, parse_mode) + __field(u8, l4_error_code) + __field(u8, l3_error_code) + __field(u8, l2_error_code) + __field(u16, packet_len) + __field(u16, valid_size) + __field(u16, vlan) + __string(pciname, pci_name(priv->pdev)) + __string(devname, priv->netdev->name) + ), + + TP_fast_assign(__entry->index =3D index, + __entry->packet_len =3D + FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, + rx_desc->word2); + __entry->port_num =3D + FIELD_GET(HBG_RX_DESC_W2_PORT_NUM_M, + rx_desc->word2); + __entry->ip_offset =3D + FIELD_GET(HBG_RX_DESC_W3_IP_OFFSET_M, + rx_desc->word3); + __entry->vlan =3D + FIELD_GET(HBG_RX_DESC_W3_VLAN_M, + rx_desc->word3); + __entry->parse_mode =3D + FIELD_GET(HBG_RX_DESC_W4_PARSE_MODE_M, + rx_desc->word4); + __entry->l4_error_code =3D + FIELD_GET(HBG_RX_DESC_W4_L4_ERR_CODE_M, + rx_desc->word4); + __entry->l3_error_code =3D + FIELD_GET(HBG_RX_DESC_W4_L3_ERR_CODE_M, + rx_desc->word4); + __entry->l2_error_code =3D + FIELD_GET(HBG_RX_DESC_W4_L2_ERR_B, + rx_desc->word4); + __entry->valid_size =3D + FIELD_GET(HBG_RX_DESC_W5_VALID_SIZE_M, + rx_desc->word5); + __assign_str(pciname); + __assign_str(devname); + ), + + TP_printk("%s %s index:%u, port num:%u, len:%u, valid size:%u, ip_off= set:%u, vlan:0x%04x, parse mode:%u, l4_err:0x%x, l3_err:0x%x, l2_err:0x%x", + __get_str(pciname), __get_str(devname), __entry->index, + __entry->port_num, __entry->packet_len, + __entry->valid_size, __entry->ip_offset, __entry->vlan, + __entry->parse_mode, __entry->l4_error_code, + __entry->l3_error_code, __entry->l2_error_code + ) +); + +#endif /* _HBG_TRACE_H_ */ + +/* This must be outside ifdef _HBG_TRACE_H */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE hbg_trace +#include diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c b/drivers/ne= t/ethernet/hisilicon/hibmcge/hbg_txrx.c index 8d814c8f19ea..5f2e48f1dd25 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c @@ -7,6 +7,9 @@ #include "hbg_reg.h" #include "hbg_txrx.h" =20 +#define CREATE_TRACE_POINTS +#include "hbg_trace.h" + #define netdev_get_tx_ring(netdev) \ (&(((struct hbg_priv *)netdev_priv(netdev))->tx_ring)) =20 @@ -429,6 +432,7 @@ static int hbg_napi_rx_poll(struct napi_struct *napi, i= nt budget) break; rx_desc =3D (struct hbg_rx_desc *)buffer->skb->data; pkt_len =3D FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2); + trace_hbg_rx_desc(priv, ring->ntc, rx_desc); =20 if (unlikely(!hbg_rx_pkt_check(priv, rx_desc, buffer->skb))) { hbg_buffer_free(buffer); --=20 2.33.0 From nobody Sun Feb 8 22:00:49 2026 Received: from canpmsgout09.his.huawei.com (canpmsgout09.his.huawei.com [113.46.200.224]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F10D2FBE02; Fri, 14 Nov 2025 09:23:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.224 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763112201; cv=none; b=dHfzpsR7ZqoA+oTDm4O0m1TAy/JuTE0pOl6ZvJAQOR1tvkdDjYtGJ4rMbHSb7RFM/Clgg7TZI7TcZEHxDVe0dRFiKq3Dqkoek22pwwNjQ8RIprq4mwn1euTcVAWqa5xUKS1PVarC7KFA7PQRc6GHfCl5IiWk3wfIhM04S4IciQs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763112201; c=relaxed/simple; bh=ju5owjvu0VX4i8wx7oDwNYqk2/lw7ZaH7ZQofWhxsR4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gNAtH7ZcTJheHtIIrgC1I25CjGBN7E6+p1vrfk4WkiWYiUM864YqvNSVmd8Zm/mnlxz8lUvwpCHw2MPT6wufhweWxKmfdMtkc1R7Ma1AtT0i1IbJKlZG7GSJ1Qpgn1M461r2TEw8VN9/GI93oD+WWqAIWuOiBULwdiE8aw20zlA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=0DUYdpt8; arc=none smtp.client-ip=113.46.200.224 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="0DUYdpt8" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=edwiiQt5CblhIFOI2q5eeGhAoeEx3vefP2XkXj3E38A=; b=0DUYdpt8SqvqfACD/LFZi/hVi/wRkEr3ZeWhKJ8hCQVEYt6QXoUilPsDSO/ox+t98sEHELXcV +Br4G5kU+Jh8B2XJAnbW0D/4QZQvTi6Jelh9/GRUyjZVtuowdj7cvFdu/JXyM69U0yLgLSMsvKc foGO1slyU1/u+3YgxHohCMc= Received: from mail.maildlp.com (unknown [172.19.88.234]) by canpmsgout09.his.huawei.com (SkyGuard) with ESMTPS id 4d7BTq3jTrz1cyPl; Fri, 14 Nov 2025 17:21:35 +0800 (CST) Received: from kwepemk100013.china.huawei.com (unknown [7.202.194.61]) by mail.maildlp.com (Postfix) with ESMTPS id 8FCB41400CF; Fri, 14 Nov 2025 17:23:16 +0800 (CST) Received: from localhost.localdomain (10.90.31.46) by kwepemk100013.china.huawei.com (7.202.194.61) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Fri, 14 Nov 2025 17:23:15 +0800 From: Jijie Shao To: , , , , , CC: , , , , , , , , , , Subject: [PATCH net-next 2/3] net: hibmcge: reduce packet drop under stress testing Date: Fri, 14 Nov 2025 17:22:21 +0800 Message-ID: <20251114092222.2071583-3-shaojijie@huawei.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20251114092222.2071583-1-shaojijie@huawei.com> References: <20251114092222.2071583-1-shaojijie@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To kwepemk100013.china.huawei.com (7.202.194.61) Content-Type: text/plain; charset="utf-8" Under stress test scenarios, hibmcge driver may not receive packets in a timely manner, which can lead to the buffer of the hardware queue being exhausted, resulting in packet drop. This patch doubles the software queue depth and uses half of the buffer to fill the hardware queue before receiving packets, thus preventing packet loss caused by the hardware queue buffer being exhausted. Signed-off-by: Jijie Shao --- .../net/ethernet/hisilicon/hibmcge/hbg_txrx.c | 47 +++++++++++++++---- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c b/drivers/ne= t/ethernet/hisilicon/hibmcge/hbg_txrx.c index 5f2e48f1dd25..ea691d564161 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c @@ -377,7 +377,8 @@ static int hbg_rx_fill_one_buffer(struct hbg_priv *priv) struct hbg_buffer *buffer; int ret; =20 - if (hbg_queue_is_full(ring->ntc, ring->ntu, ring)) + if (hbg_queue_is_full(ring->ntc, ring->ntu, ring) || + hbg_fifo_is_full(priv, ring->dir)) return 0; =20 buffer =3D &ring->queue[ring->ntu]; @@ -396,6 +397,26 @@ static int hbg_rx_fill_one_buffer(struct hbg_priv *pri= v) return 0; } =20 +static int hbg_rx_fill_buffers(struct hbg_priv *priv) +{ + u32 remained =3D hbg_hw_get_fifo_used_num(priv, HBG_DIR_RX); + u32 max_count =3D priv->dev_specs.rx_fifo_num; + u32 refill_count; + int ret; + + if (unlikely(remained >=3D max_count)) + return 0; + + refill_count =3D max_count - remained; + while (refill_count--) { + ret =3D hbg_rx_fill_one_buffer(priv); + if (unlikely(ret)) + break; + } + + return ret; +} + static bool hbg_sync_data_from_hw(struct hbg_priv *priv, struct hbg_buffer *buffer) { @@ -420,6 +441,7 @@ static int hbg_napi_rx_poll(struct napi_struct *napi, i= nt budget) u32 packet_done =3D 0; u32 pkt_len; =20 + hbg_rx_fill_buffers(priv); while (packet_done < budget) { if (unlikely(hbg_queue_is_empty(ring->ntc, ring->ntu, ring))) break; @@ -497,6 +519,16 @@ static int hbg_ring_init(struct hbg_priv *priv, struct= hbg_ring *ring, u32 i, len; =20 len =3D hbg_get_spec_fifo_max_num(priv, dir) + 1; + /* To improve receiving performance under high-stress scenarios, + * in the `hbg_napi_rx_poll()`, we first use the other half of + * the buffer to receive packets from the hardware via the + * `hbg_rx_fill_buffers()`, and then process the packets in the + * original half of the buffer to avoid packet loss caused by + * hardware overflow as much as possible. + */ + if (dir =3D=3D HBG_DIR_RX) + len +=3D hbg_get_spec_fifo_max_num(priv, dir); + ring->queue =3D dma_alloc_coherent(&priv->pdev->dev, len * sizeof(*ring->queue), &ring->queue_dma, GFP_KERNEL); @@ -545,21 +577,16 @@ static int hbg_tx_ring_init(struct hbg_priv *priv) static int hbg_rx_ring_init(struct hbg_priv *priv) { int ret; - u32 i; =20 ret =3D hbg_ring_init(priv, &priv->rx_ring, hbg_napi_rx_poll, HBG_DIR_RX); if (ret) return ret; =20 - for (i =3D 0; i < priv->rx_ring.len - 1; i++) { - ret =3D hbg_rx_fill_one_buffer(priv); - if (ret) { - hbg_ring_uninit(&priv->rx_ring); - return ret; - } - } + ret =3D hbg_rx_fill_buffers(priv); + if (ret) + hbg_ring_uninit(&priv->rx_ring); =20 - return 0; + return ret; } =20 int hbg_txrx_init(struct hbg_priv *priv) --=20 2.33.0 From nobody Sun Feb 8 22:00:49 2026 Received: from canpmsgout10.his.huawei.com (canpmsgout10.his.huawei.com [113.46.200.225]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B636D309EE1; Fri, 14 Nov 2025 09:23:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.225 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763112207; cv=none; b=kT/MNwtzX1kRui9TCOBK5t/x7221MPF3VnkzJcGLtF2I1RkA8WMYrAPwR83ALrLISP4IIAWJC9Ksc2jKC2J4qNboREDNePoBmSpxEOPqUcyAkWDHbOJGLu8jRT7EnukUUZCx8yjbGpI6n7z9y4C8n+CfV+aO3XOzqJ94t9fUtWg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763112207; c=relaxed/simple; bh=y6Bhnw8A+7hb0zMxFQ+p18ifH21QdDsCMZT5Q0VGIGc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=sJhwTkGjdkoraBCPQIYmNqAGhQnzcHBHpEQHTWq3rZ46QDqIscscDhzWKA903yWVLWyrBxK55eJHla1Yi35kVzifqKHaI5vYBogmuCfXHsHJVzdkkXC9jGWdsmNnfGwzYS0XSmODHfzLMBw7DST4lRboq6kt4horfRB7N0gMVB4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=yzyDi5Tb; arc=none smtp.client-ip=113.46.200.225 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="yzyDi5Tb" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=YH4NmnPyTR38Qhd0hfRC5HRVvESSJJhOyXz473L3zW8=; b=yzyDi5TbEd7XrP7ZWCVXpsGqEnZqVYu/XSA1IAG9P/n31I4RJldZtZGPRUkDhs8Q29fk5J6Ui CmcdNcdoF486JsnDO0k/Xgd0h3u4inCcmfxc1iA5zOjChW3z3EMs30Diwo2owlCLHKuT7Yx1Qt8 xUgvEoe++uprffpKCgmGXD4= Received: from mail.maildlp.com (unknown [172.19.88.234]) by canpmsgout10.his.huawei.com (SkyGuard) with ESMTPS id 4d7BTt0YMMz1K9Bc; Fri, 14 Nov 2025 17:21:38 +0800 (CST) Received: from kwepemk100013.china.huawei.com (unknown [7.202.194.61]) by mail.maildlp.com (Postfix) with ESMTPS id 272021400CF; Fri, 14 Nov 2025 17:23:17 +0800 (CST) Received: from localhost.localdomain (10.90.31.46) by kwepemk100013.china.huawei.com (7.202.194.61) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.11; Fri, 14 Nov 2025 17:23:16 +0800 From: Jijie Shao To: , , , , , CC: , , , , , , , , , , Subject: [PATCH net-next 3/3] net: hibmcge: support pagepool for rx Date: Fri, 14 Nov 2025 17:22:22 +0800 Message-ID: <20251114092222.2071583-4-shaojijie@huawei.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20251114092222.2071583-1-shaojijie@huawei.com> References: <20251114092222.2071583-1-shaojijie@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To kwepemk100013.china.huawei.com (7.202.194.61) Content-Type: text/plain; charset="utf-8" Support pagepool for rx, retaining the original packet receiving process. Signed-off-by: Jijie Shao --- drivers/net/ethernet/hisilicon/Kconfig | 1 + .../ethernet/hisilicon/hibmcge/hbg_common.h | 23 ++- .../ethernet/hisilicon/hibmcge/hbg_debugfs.c | 2 + .../net/ethernet/hisilicon/hibmcge/hbg_main.c | 7 + .../net/ethernet/hisilicon/hibmcge/hbg_txrx.c | 170 ++++++++++++++++-- 5 files changed, 185 insertions(+), 18 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/Kconfig b/drivers/net/ethernet/= hisilicon/Kconfig index 38875c196cb6..18eca7d12c20 100644 --- a/drivers/net/ethernet/hisilicon/Kconfig +++ b/drivers/net/ethernet/hisilicon/Kconfig @@ -151,6 +151,7 @@ config HIBMCGE select FIXED_PHY select MOTORCOMM_PHY select REALTEK_PHY + select PAGE_POOL help If you wish to compile a kernel for a BMC with HIBMC-xx_gmac then you should answer Y to this. This makes this driver suitable for u= se diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h b/drivers/= net/ethernet/hisilicon/hibmcge/hbg_common.h index 2097e4c2b3d7..39cc18686f7e 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_common.h @@ -7,6 +7,7 @@ #include #include #include +#include #include "hbg_reg.h" =20 #define HBG_STATUS_DISABLE 0x0 @@ -52,8 +53,24 @@ struct hbg_buffer { dma_addr_t state_dma; =20 struct sk_buff *skb; - dma_addr_t skb_dma; - u32 skb_len; + struct page *page; + u32 page_offset; + + union { + void *skb_data_addr; + void *page_addr; + void *pkt_addr; + }; + union { + dma_addr_t skb_dma; + dma_addr_t page_dma; + dma_addr_t pkt_dma; + }; + union { + u32 skb_len; + u32 page_size; + u32 pkt_len; + }; =20 enum hbg_dir dir; struct hbg_ring *ring; @@ -78,6 +95,7 @@ struct hbg_ring { struct hbg_priv *priv; struct napi_struct napi; char *tout_log_buf; /* tx timeout log buffer */ + struct page_pool *page_pool; }; =20 enum hbg_hw_event_type { @@ -101,6 +119,7 @@ struct hbg_dev_specs { =20 u32 max_frame_len; u32 rx_buf_size; + bool page_pool_enabled; }; =20 struct hbg_irq_info { diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_debugfs.c b/drivers= /net/ethernet/hisilicon/hibmcge/hbg_debugfs.c index 01ad82d2f5cc..d963913def81 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_debugfs.c @@ -122,6 +122,8 @@ static int hbg_dbg_nic_state(struct seq_file *s, void *= unused) np_link_fail =3D !hbg_reg_read_field(priv, HBG_REG_AN_NEG_STATE_ADDR, HBG_REG_AN_NEG_STATE_NP_LINK_OK_B); seq_printf(s, "np_link fail state: %s\n", str_true_false(np_link_fail)); + seq_printf(s, "page_pool enabled: %s\n", + str_true_false(priv->dev_specs.page_pool_enabled)); =20 return 0; } diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c b/drivers/ne= t/ethernet/hisilicon/hibmcge/hbg_main.c index 068da2fd1fea..9d8b80db9f8b 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c @@ -19,6 +19,10 @@ #define HBG_SUPPORT_FEATURES (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \ NETIF_F_RXCSUM) =20 +static bool page_pool_enabled =3D true; +module_param(page_pool_enabled, bool, 0400); +MODULE_PARM_DESC(page_pool_enabled, "set page_pool enabled, default is tru= e"); + static void hbg_all_irq_enable(struct hbg_priv *priv, bool enabled) { const struct hbg_irq_info *info; @@ -367,6 +371,9 @@ static int hbg_init(struct hbg_priv *priv) { int ret; =20 + if (IS_ENABLED(CONFIG_PAGE_POOL)) + priv->dev_specs.page_pool_enabled =3D page_pool_enabled; + ret =3D hbg_hw_event_notify(priv, HBG_HW_EVENT_INIT); if (ret) return ret; diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c b/drivers/ne= t/ethernet/hisilicon/hibmcge/hbg_txrx.c index ea691d564161..b71f277419fa 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c @@ -31,6 +31,11 @@ typeof(ring) _ring =3D (ring); \ _ring->p =3D hbg_queue_next_prt(_ring->p, _ring); }) =20 +#define hbg_get_page_order(ring) ({ \ + typeof(ring) _ring =3D (ring); \ + get_order(hbg_spec_max_frame_len(_ring->priv, _ring->dir)); }) +#define hbg_get_page_size(ring) (PAGE_SIZE << hbg_get_page_order((ring))) + #define HBG_TX_STOP_THRS 2 #define HBG_TX_START_THRS (2 * HBG_TX_STOP_THRS) =20 @@ -136,6 +141,7 @@ static void hbg_buffer_free_skb(struct hbg_buffer *buff= er) =20 dev_kfree_skb_any(buffer->skb); buffer->skb =3D NULL; + buffer->skb_data_addr =3D NULL; } =20 static int hbg_buffer_alloc_skb(struct hbg_buffer *buffer) @@ -148,7 +154,44 @@ static int hbg_buffer_alloc_skb(struct hbg_buffer *buf= fer) return -ENOMEM; =20 buffer->skb_len =3D len; - memset(buffer->skb->data, 0, HBG_PACKET_HEAD_SIZE); + buffer->skb_data_addr =3D buffer->skb->data; + return 0; +} + +static void hbg_buffer_free_page(struct hbg_buffer *buffer) +{ + struct hbg_ring *ring =3D buffer->ring; + + if (unlikely(!ring->page_pool || !buffer->page)) + return; + + page_pool_put_full_page(ring->page_pool, buffer->page, false); + + buffer->page =3D NULL; + buffer->page_dma =3D 0; + buffer->page_addr =3D NULL; + buffer->page_size =3D 0; + buffer->page_offset =3D 0; +} + +static int hbg_buffer_alloc_page(struct hbg_buffer *buffer) +{ + struct hbg_ring *ring =3D buffer->ring; + u32 len =3D hbg_get_page_size(ring); + u32 offset; + + if (unlikely(!ring->page_pool)) + return 0; + + buffer->page =3D page_pool_dev_alloc_frag(ring->page_pool, &offset, len); + if (unlikely(!buffer->page)) + return -ENOMEM; + + buffer->page_dma =3D page_pool_get_dma_addr(buffer->page) + offset; + buffer->page_addr =3D page_address(buffer->page) + offset; + buffer->page_size =3D len; + buffer->page_offset =3D offset; + return 0; } =20 @@ -371,6 +414,36 @@ static bool hbg_rx_pkt_check(struct hbg_priv *priv, st= ruct hbg_rx_desc *desc, return true; } =20 +static int hbg_alloc_mapping_buffer(struct hbg_buffer *buffer) +{ + struct hbg_ring *ring =3D buffer->ring; + int ret; + + if (ring->page_pool) + return hbg_buffer_alloc_page(buffer); + + ret =3D hbg_buffer_alloc_skb(buffer); + if (unlikely(ret)) + return ret; + + ret =3D hbg_dma_map(buffer); + if (unlikely(ret)) + hbg_buffer_free_skb(buffer); + + return ret; +} + +static void hbg_free_mapping_buffer(struct hbg_buffer *buffer) +{ + struct hbg_ring *ring =3D buffer->ring; + + if (ring->page_pool) + return hbg_buffer_free_page(buffer); + + hbg_dma_unmap(buffer); + hbg_buffer_free_skb(buffer); +} + static int hbg_rx_fill_one_buffer(struct hbg_priv *priv) { struct hbg_ring *ring =3D &priv->rx_ring; @@ -382,17 +455,15 @@ static int hbg_rx_fill_one_buffer(struct hbg_priv *pr= iv) return 0; =20 buffer =3D &ring->queue[ring->ntu]; - ret =3D hbg_buffer_alloc_skb(buffer); + ret =3D hbg_alloc_mapping_buffer(buffer); if (unlikely(ret)) return ret; =20 - ret =3D hbg_dma_map(buffer); - if (unlikely(ret)) { - hbg_buffer_free_skb(buffer); - return ret; - } + memset(buffer->pkt_addr, 0, HBG_PACKET_HEAD_SIZE); + dma_sync_single_for_device(&priv->pdev->dev, buffer->pkt_dma, + HBG_PACKET_HEAD_SIZE, DMA_TO_DEVICE); =20 - hbg_hw_fill_buffer(priv, buffer->skb_dma); + hbg_hw_fill_buffer(priv, buffer->pkt_dma); hbg_queue_move_next(ntu, ring); return 0; } @@ -425,13 +496,29 @@ static bool hbg_sync_data_from_hw(struct hbg_priv *pr= iv, /* make sure HW write desc complete */ dma_rmb(); =20 - dma_sync_single_for_cpu(&priv->pdev->dev, buffer->skb_dma, - buffer->skb_len, DMA_FROM_DEVICE); + dma_sync_single_for_cpu(&priv->pdev->dev, buffer->pkt_dma, + buffer->pkt_len, DMA_FROM_DEVICE); =20 - rx_desc =3D (struct hbg_rx_desc *)buffer->skb->data; + rx_desc =3D (struct hbg_rx_desc *)buffer->pkt_addr; return FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2) !=3D 0; } =20 +static int hbg_build_skb(struct hbg_buffer *buffer) +{ + if (!buffer->ring->page_pool) { + hbg_dma_unmap(buffer); + return 0; + } + + net_prefetch(buffer->page_addr); + buffer->skb =3D napi_build_skb(buffer->page_addr, buffer->page_size); + if (unlikely(!buffer->skb)) + return -ENOMEM; + + skb_mark_for_recycle(buffer->skb); + return 0; +} + static int hbg_napi_rx_poll(struct napi_struct *napi, int budget) { struct hbg_ring *ring =3D container_of(napi, struct hbg_ring, napi); @@ -447,21 +534,25 @@ static int hbg_napi_rx_poll(struct napi_struct *napi,= int budget) break; =20 buffer =3D &ring->queue[ring->ntc]; - if (unlikely(!buffer->skb)) + if (unlikely(!buffer->pkt_addr)) goto next_buffer; =20 if (unlikely(!hbg_sync_data_from_hw(priv, buffer))) break; - rx_desc =3D (struct hbg_rx_desc *)buffer->skb->data; + rx_desc =3D (struct hbg_rx_desc *)buffer->pkt_addr; pkt_len =3D FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2); trace_hbg_rx_desc(priv, ring->ntc, rx_desc); =20 + if (unlikely(hbg_build_skb(buffer))) { + hbg_free_mapping_buffer(buffer); + goto next_buffer; + } + if (unlikely(!hbg_rx_pkt_check(priv, rx_desc, buffer->skb))) { - hbg_buffer_free(buffer); + hbg_free_mapping_buffer(buffer); goto next_buffer; } =20 - hbg_dma_unmap(buffer); skb_reserve(buffer->skb, HBG_PACKET_HEAD_SIZE + NET_IP_ALIGN); skb_put(buffer->skb, pkt_len); buffer->skb->protocol =3D eth_type_trans(buffer->skb, @@ -470,6 +561,8 @@ static int hbg_napi_rx_poll(struct napi_struct *napi, i= nt budget) dev_sw_netstats_rx_add(priv->netdev, pkt_len); napi_gro_receive(napi, buffer->skb); buffer->skb =3D NULL; + buffer->page =3D NULL; + buffer->pkt_addr =3D NULL; =20 next_buffer: hbg_rx_fill_one_buffer(priv); @@ -484,6 +577,15 @@ static int hbg_napi_rx_poll(struct napi_struct *napi, = int budget) return packet_done; } =20 +static void hbg_ring_page_pool_destory(struct hbg_ring *ring) +{ + if (!ring->page_pool) + return; + + page_pool_destroy(ring->page_pool); + ring->page_pool =3D NULL; +} + static void hbg_ring_uninit(struct hbg_ring *ring) { struct hbg_buffer *buffer; @@ -497,11 +599,12 @@ static void hbg_ring_uninit(struct hbg_ring *ring) =20 for (i =3D 0; i < ring->len; i++) { buffer =3D &ring->queue[i]; - hbg_buffer_free(buffer); + hbg_free_mapping_buffer(buffer); buffer->ring =3D NULL; buffer->priv =3D NULL; } =20 + hbg_ring_page_pool_destory(ring); dma_free_coherent(&ring->priv->pdev->dev, ring->len * sizeof(*ring->queue), ring->queue, ring->queue_dma); @@ -511,6 +614,33 @@ static void hbg_ring_uninit(struct hbg_ring *ring) ring->priv =3D NULL; } =20 +static int hbg_ring_page_pool_init(struct hbg_priv *priv, struct hbg_ring = *ring) +{ + u32 buf_size =3D hbg_spec_max_frame_len(priv, ring->dir); + struct page_pool_params pp_params =3D { + .flags =3D PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV, + .order =3D hbg_get_page_order(ring), + .pool_size =3D ring->len * buf_size / hbg_get_page_size(ring), + .nid =3D dev_to_node(&priv->pdev->dev), + .dev =3D &priv->pdev->dev, + .napi =3D &ring->napi, + .dma_dir =3D DMA_FROM_DEVICE, + .offset =3D 0, + .max_len =3D hbg_get_page_size(ring), + }; + int ret =3D 0; + + ring->page_pool =3D page_pool_create(&pp_params); + if (IS_ERR(ring->page_pool)) { + ret =3D PTR_ERR(ring->page_pool); + dev_err(&priv->pdev->dev, + "failed to create page pool, ret =3D %d\n", ret); + ring->page_pool =3D NULL; + } + + return ret; +} + static int hbg_ring_init(struct hbg_priv *priv, struct hbg_ring *ring, int (*napi_poll)(struct napi_struct *, int), enum hbg_dir dir) @@ -582,6 +712,14 @@ static int hbg_rx_ring_init(struct hbg_priv *priv) if (ret) return ret; =20 + if (priv->dev_specs.page_pool_enabled) { + ret =3D hbg_ring_page_pool_init(priv, &priv->rx_ring); + if (ret) { + hbg_ring_uninit(&priv->rx_ring); + return ret; + } + } + ret =3D hbg_rx_fill_buffers(priv); if (ret) hbg_ring_uninit(&priv->rx_ring); --=20 2.33.0