[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID:
<DS3PR21MB573519683081B9E6B1463BFFCE87A@DS3PR21MB5735.namprd21.prod.outlook.com>
Date: Tue, 6 Jan 2026 21:50:32 +0000
From: Long Li <longli@...rosoft.com>
To: Haiyang Zhang <haiyangz@...ux.microsoft.com>,
"linux-hyperv@...r.kernel.org" <linux-hyperv@...r.kernel.org>,
"netdev@...r.kernel.org" <netdev@...r.kernel.org>, KY Srinivasan
<kys@...rosoft.com>, Haiyang Zhang <haiyangz@...rosoft.com>, Wei Liu
<wei.liu@...nel.org>, Dexuan Cui <DECUI@...rosoft.com>, Andrew Lunn
<andrew+netdev@...n.ch>, "David S. Miller" <davem@...emloft.net>, Eric
Dumazet <edumazet@...gle.com>, Jakub Kicinski <kuba@...nel.org>, Paolo Abeni
<pabeni@...hat.com>, Konstantin Taranov <kotaranov@...rosoft.com>, Simon
Horman <horms@...nel.org>, Erni Sri Satya Vennela
<ernis@...ux.microsoft.com>, Shradha Gupta
<shradhagupta@...ux.microsoft.com>, Saurabh Sengar
<ssengar@...ux.microsoft.com>, Aditya Garg <gargaditya@...ux.microsoft.com>,
Dipayaan Roy <dipayanroy@...ux.microsoft.com>, Shiraz Saleem
<shirazsaleem@...rosoft.com>, "linux-kernel@...r.kernel.org"
<linux-kernel@...r.kernel.org>, "linux-rdma@...r.kernel.org"
<linux-rdma@...r.kernel.org>
CC: Paul Rosswurm <paulros@...rosoft.com>
Subject: RE: [PATCH V2,net-next, 1/2] net: mana: Add support for coalesced RX
packets on CQE
> Subject: [PATCH V2,net-next, 1/2] net: mana: Add support for coalesced RX
> packets on CQE
>
> From: Haiyang Zhang <haiyangz@...rosoft.com>
>
> Our NIC can have up to 4 RX packets on 1 CQE. To support this feature, check
> and process the type CQE_RX_COALESCED_4. The default setting is disabled,
> to avoid possible regression on latency.
>
> And add ethtool handler to switch this feature. To turn it on, run:
> ethtool -C <nic> rx-frames 4
> To turn it off:
> ethtool -C <nic> rx-frames 1
>
> Signed-off-by: Haiyang Zhang <haiyangz@...rosoft.com>
Reviewed-by: Long Li <longli@...rosoft.com>
> ---
> V2:
> Updated extack msg, as recommended by Jakub Kicinski, and Simon Horman.
>
> ---
> drivers/net/ethernet/microsoft/mana/mana_en.c | 32 ++++++-----
> .../ethernet/microsoft/mana/mana_ethtool.c | 55 +++++++++++++++++++
> include/net/mana/mana.h | 2 +
> 3 files changed, 74 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c
> b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index 1ad154f9db1a..a46a1adf83bc 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -1330,7 +1330,7 @@ static int mana_cfg_vport_steering(struct
> mana_port_context *apc,
> req->update_hashkey = update_key;
> req->update_indir_tab = update_tab;
> req->default_rxobj = apc->default_rxobj;
> - req->cqe_coalescing_enable = 0;
> + req->cqe_coalescing_enable = apc->cqe_coalescing_enable;
>
> if (update_key)
> memcpy(&req->hashkey, apc->hashkey,
> MANA_HASH_KEY_SIZE); @@ -1864,11 +1864,12 @@ static struct sk_buff
> *mana_build_skb(struct mana_rxq *rxq, void *buf_va, }
>
> static void mana_rx_skb(void *buf_va, bool from_pool,
> - struct mana_rxcomp_oob *cqe, struct mana_rxq *rxq)
> + struct mana_rxcomp_oob *cqe, struct mana_rxq *rxq,
> + int i)
> {
> struct mana_stats_rx *rx_stats = &rxq->stats;
> struct net_device *ndev = rxq->ndev;
> - uint pkt_len = cqe->ppi[0].pkt_len;
> + uint pkt_len = cqe->ppi[i].pkt_len;
> u16 rxq_idx = rxq->rxq_idx;
> struct napi_struct *napi;
> struct xdp_buff xdp = {};
> @@ -1912,7 +1913,7 @@ static void mana_rx_skb(void *buf_va, bool
> from_pool,
> }
>
> if (cqe->rx_hashtype != 0 && (ndev->features & NETIF_F_RXHASH)) {
> - hash_value = cqe->ppi[0].pkt_hash;
> + hash_value = cqe->ppi[i].pkt_hash;
>
> if (cqe->rx_hashtype & MANA_HASH_L4)
> skb_set_hash(skb, hash_value, PKT_HASH_TYPE_L4);
> @@ -2047,9 +2048,11 @@ static void mana_process_rx_cqe(struct
> mana_rxq *rxq, struct mana_cq *cq,
> struct mana_recv_buf_oob *rxbuf_oob;
> struct mana_port_context *apc;
> struct device *dev = gc->dev;
> + bool coalesced = false;
> void *old_buf = NULL;
> u32 curr, pktlen;
> bool old_fp;
> + int i = 0;
>
> apc = netdev_priv(ndev);
>
> @@ -2064,9 +2067,8 @@ static void mana_process_rx_cqe(struct mana_rxq
> *rxq, struct mana_cq *cq,
> goto drop;
>
> case CQE_RX_COALESCED_4:
> - netdev_err(ndev, "RX coalescing is unsupported\n");
> - apc->eth_stats.rx_coalesced_err++;
> - return;
> + coalesced = true;
> + break;
>
> case CQE_RX_OBJECT_FENCE:
> complete(&rxq->fence_event);
> @@ -2079,14 +2081,10 @@ static void mana_process_rx_cqe(struct
> mana_rxq *rxq, struct mana_cq *cq,
> return;
> }
>
> - pktlen = oob->ppi[0].pkt_len;
> -
> - if (pktlen == 0) {
> - /* data packets should never have packetlength of zero */
> - netdev_err(ndev, "RX pkt len=0, rq=%u, cq=%u,
> rxobj=0x%llx\n",
> - rxq->gdma_id, cq->gdma_id, rxq->rxobj);
> +nextpkt:
> + pktlen = oob->ppi[i].pkt_len;
> + if (pktlen == 0)
> return;
> - }
>
> curr = rxq->buf_index;
> rxbuf_oob = &rxq->rx_oobs[curr];
> @@ -2097,12 +2095,15 @@ static void mana_process_rx_cqe(struct
> mana_rxq *rxq, struct mana_cq *cq,
> /* Unsuccessful refill will have old_buf == NULL.
> * In this case, mana_rx_skb() will drop the packet.
> */
> - mana_rx_skb(old_buf, old_fp, oob, rxq);
> + mana_rx_skb(old_buf, old_fp, oob, rxq, i);
>
> drop:
> mana_move_wq_tail(rxq->gdma_rq, rxbuf_oob-
> >wqe_inf.wqe_size_in_bu);
>
> mana_post_pkt_rxq(rxq);
> +
> + if (coalesced && (++i < MANA_RXCOMP_OOB_NUM_PPI))
> + goto nextpkt;
> }
>
> static void mana_poll_rx_cq(struct mana_cq *cq) @@ -3276,6 +3277,7 @@
> static int mana_probe_port(struct mana_context *ac, int port_idx,
> apc->port_handle = INVALID_MANA_HANDLE;
> apc->pf_filter_handle = INVALID_MANA_HANDLE;
> apc->port_idx = port_idx;
> + apc->cqe_coalescing_enable = 0;
>
> mutex_init(&apc->vport_mutex);
> apc->vport_use_count = 0;
> diff --git a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
> b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
> index 0e2f4343ac67..b2b9bfb50396 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_ethtool.c
> @@ -397,6 +397,58 @@ static void mana_get_channels(struct net_device
> *ndev,
> channel->combined_count = apc->num_queues; }
>
> +static int mana_get_coalesce(struct net_device *ndev,
> + struct ethtool_coalesce *ec,
> + struct kernel_ethtool_coalesce *kernel_coal,
> + struct netlink_ext_ack *extack) {
> + struct mana_port_context *apc = netdev_priv(ndev);
> +
> + ec->rx_max_coalesced_frames =
> + apc->cqe_coalescing_enable ?
> MANA_RXCOMP_OOB_NUM_PPI : 1;
> +
> + return 0;
> +}
> +
> +static int mana_set_coalesce(struct net_device *ndev,
> + struct ethtool_coalesce *ec,
> + struct kernel_ethtool_coalesce *kernel_coal,
> + struct netlink_ext_ack *extack) {
> + struct mana_port_context *apc = netdev_priv(ndev);
> + u8 saved_cqe_coalescing_enable;
> + int err;
> +
> + if (ec->rx_max_coalesced_frames != 1 &&
> + ec->rx_max_coalesced_frames != MANA_RXCOMP_OOB_NUM_PPI)
> {
> + NL_SET_ERR_MSG_FMT(extack,
> + "rx-frames must be 1 or %u, got %u",
> + MANA_RXCOMP_OOB_NUM_PPI,
> + ec->rx_max_coalesced_frames);
> + return -EINVAL;
> + }
> +
> + saved_cqe_coalescing_enable = apc->cqe_coalescing_enable;
> + apc->cqe_coalescing_enable =
> + ec->rx_max_coalesced_frames ==
> MANA_RXCOMP_OOB_NUM_PPI;
> +
> + if (!apc->port_is_up)
> + return 0;
> +
> + err = mana_config_rss(apc, TRI_STATE_TRUE, false, false);
> +
> + if (err) {
> + netdev_err(ndev, "Set rx-frames to %u failed:%d\n",
> + ec->rx_max_coalesced_frames, err);
> + NL_SET_ERR_MSG_FMT(extack, "Set rx-frames to %u failed",
> + ec->rx_max_coalesced_frames);
> +
> + apc->cqe_coalescing_enable = saved_cqe_coalescing_enable;
> + }
> +
> + return err;
> +}
> +
> static int mana_set_channels(struct net_device *ndev,
> struct ethtool_channels *channels) { @@ -517,6
> +569,7 @@ static int mana_get_link_ksettings(struct net_device *ndev, }
>
> const struct ethtool_ops mana_ethtool_ops = {
> + .supported_coalesce_params =
> ETHTOOL_COALESCE_RX_MAX_FRAMES,
> .get_ethtool_stats = mana_get_ethtool_stats,
> .get_sset_count = mana_get_sset_count,
> .get_strings = mana_get_strings,
> @@ -527,6 +580,8 @@ const struct ethtool_ops mana_ethtool_ops = {
> .set_rxfh = mana_set_rxfh,
> .get_channels = mana_get_channels,
> .set_channels = mana_set_channels,
> + .get_coalesce = mana_get_coalesce,
> + .set_coalesce = mana_set_coalesce,
> .get_ringparam = mana_get_ringparam,
> .set_ringparam = mana_set_ringparam,
> .get_link_ksettings = mana_get_link_ksettings,
> diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h index
> d7e089c6b694..51d26ebeff6c 100644
> --- a/include/net/mana/mana.h
> +++ b/include/net/mana/mana.h
> @@ -556,6 +556,8 @@ struct mana_port_context {
> bool port_is_up;
> bool port_st_save; /* Saved port state */
>
> + u8 cqe_coalescing_enable;
> +
> struct mana_ethtool_stats eth_stats;
>
> struct mana_ethtool_phy_stats phy_stats;
> --
> 2.34.1
Powered by blists - more mailing lists