diff mbox series

[net-next,v3,1/5] gve: XDP support GQI-QPL: helper function changes

Message ID 20230313202640.4113427-2-pkaligineedi@google.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series gve: Add XDP support for GQI-QPL format | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 18 this patch: 18
netdev/cc_maintainers warning 8 maintainers not CCed: pabeni@redhat.com shailend@google.com edumazet@google.com csully@google.com bigeasy@linutronix.de colin.i.king@gmail.com yangyingliang@huawei.com tglx@linutronix.de
netdev/build_clang success Errors and warnings before: 21 this patch: 21
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 18 this patch: 18
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 370 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Praveen Kaligineedi March 13, 2023, 8:26 p.m. UTC
This patch adds/modifies helper functions needed to add XDP
support.

Signed-off-by: Praveen Kaligineedi <pkaligineedi@google.com>
Reviewed-by: Jeroen de Borst <jeroendb@google.com>

---
Changed in v2:
- No changes

Changed in v3:
- No changes
---

 drivers/net/ethernet/google/gve/gve.h         |  5 +++
 drivers/net/ethernet/google/gve/gve_ethtool.c | 26 +++++++----
 drivers/net/ethernet/google/gve/gve_main.c    | 27 +++++++-----
 drivers/net/ethernet/google/gve/gve_rx.c      |  2 +-
 drivers/net/ethernet/google/gve/gve_rx_dqo.c  |  2 +-
 drivers/net/ethernet/google/gve/gve_tx.c      | 43 +++++++++++--------
 drivers/net/ethernet/google/gve/gve_utils.c   |  6 +--
 drivers/net/ethernet/google/gve/gve_utils.h   |  3 +-
 8 files changed, 70 insertions(+), 44 deletions(-)

Comments

Michal Kubiak March 15, 2023, 5:13 p.m. UTC | #1
On Mon, Mar 13, 2023 at 01:26:36PM -0700, Praveen Kaligineedi wrote:
> This patch adds/modifies helper functions needed to add XDP
> support.
> 
> Signed-off-by: Praveen Kaligineedi <pkaligineedi@google.com>
> Reviewed-by: Jeroen de Borst <jeroendb@google.com>
> 

Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>

Thanks,
Michal

> ---
> Changed in v2:
> - No changes
> 
> Changed in v3:
> - No changes
> ---
> 
>  drivers/net/ethernet/google/gve/gve.h         |  5 +++
>  drivers/net/ethernet/google/gve/gve_ethtool.c | 26 +++++++----
>  drivers/net/ethernet/google/gve/gve_main.c    | 27 +++++++-----
>  drivers/net/ethernet/google/gve/gve_rx.c      |  2 +-
>  drivers/net/ethernet/google/gve/gve_rx_dqo.c  |  2 +-
>  drivers/net/ethernet/google/gve/gve_tx.c      | 43 +++++++++++--------
>  drivers/net/ethernet/google/gve/gve_utils.c   |  6 +--
>  drivers/net/ethernet/google/gve/gve_utils.h   |  3 +-
>  8 files changed, 70 insertions(+), 44 deletions(-)
> 
> diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h
> index 64eb0442c82f..f52f23198278 100644
> --- a/drivers/net/ethernet/google/gve/gve.h
> +++ b/drivers/net/ethernet/google/gve/gve.h
> @@ -855,6 +855,11 @@ static inline bool gve_is_gqi(struct gve_priv *priv)
>  		priv->queue_format == GVE_GQI_QPL_FORMAT;
>  }
>  
> +static inline u32 gve_num_tx_queues(struct gve_priv *priv)
> +{
> +	return priv->tx_cfg.num_queues;
> +}
> +
>  /* buffers */
>  int gve_alloc_page(struct gve_priv *priv, struct device *dev,
>  		   struct page **page, dma_addr_t *dma,
> diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c
> index ce574d097e28..5b6e31812fae 100644
> --- a/drivers/net/ethernet/google/gve/gve_ethtool.c
> +++ b/drivers/net/ethernet/google/gve/gve_ethtool.c
> @@ -81,8 +81,10 @@ static void gve_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
>  {
>  	struct gve_priv *priv = netdev_priv(netdev);
>  	char *s = (char *)data;
> +	int num_tx_queues;
>  	int i, j;
>  
> +	num_tx_queues = gve_num_tx_queues(priv);
>  	switch (stringset) {
>  	case ETH_SS_STATS:
>  		memcpy(s, *gve_gstrings_main_stats,
> @@ -97,7 +99,7 @@ static void gve_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
>  			}
>  		}
>  
> -		for (i = 0; i < priv->tx_cfg.num_queues; i++) {
> +		for (i = 0; i < num_tx_queues; i++) {
>  			for (j = 0; j < NUM_GVE_TX_CNTS; j++) {
>  				snprintf(s, ETH_GSTRING_LEN,
>  					 gve_gstrings_tx_stats[j], i);
> @@ -124,12 +126,14 @@ static void gve_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
>  static int gve_get_sset_count(struct net_device *netdev, int sset)
>  {
>  	struct gve_priv *priv = netdev_priv(netdev);
> +	int num_tx_queues;
>  
> +	num_tx_queues = gve_num_tx_queues(priv);
>  	switch (sset) {
>  	case ETH_SS_STATS:
>  		return GVE_MAIN_STATS_LEN + GVE_ADMINQ_STATS_LEN +
>  		       (priv->rx_cfg.num_queues * NUM_GVE_RX_CNTS) +
> -		       (priv->tx_cfg.num_queues * NUM_GVE_TX_CNTS);
> +		       (num_tx_queues * NUM_GVE_TX_CNTS);
>  	case ETH_SS_PRIV_FLAGS:
>  		return GVE_PRIV_FLAGS_STR_LEN;
>  	default:
> @@ -153,18 +157,20 @@ gve_get_ethtool_stats(struct net_device *netdev,
>  	struct gve_priv *priv;
>  	bool skip_nic_stats;
>  	unsigned int start;
> +	int num_tx_queues;
>  	int ring;
>  	int i, j;
>  
>  	ASSERT_RTNL();
>  
>  	priv = netdev_priv(netdev);
> +	num_tx_queues = gve_num_tx_queues(priv);
>  	report_stats = priv->stats_report->stats;
>  	rx_qid_to_stats_idx = kmalloc_array(priv->rx_cfg.num_queues,
>  					    sizeof(int), GFP_KERNEL);
>  	if (!rx_qid_to_stats_idx)
>  		return;
> -	tx_qid_to_stats_idx = kmalloc_array(priv->tx_cfg.num_queues,
> +	tx_qid_to_stats_idx = kmalloc_array(num_tx_queues,
>  					    sizeof(int), GFP_KERNEL);
>  	if (!tx_qid_to_stats_idx) {
>  		kfree(rx_qid_to_stats_idx);
> @@ -195,7 +201,7 @@ gve_get_ethtool_stats(struct net_device *netdev,
>  		}
>  	}
>  	for (tx_pkts = 0, tx_bytes = 0, tx_dropped = 0, ring = 0;
> -	     ring < priv->tx_cfg.num_queues; ring++) {
> +	     ring < num_tx_queues; ring++) {
>  		if (priv->tx) {
>  			do {
>  				start =
> @@ -232,7 +238,7 @@ gve_get_ethtool_stats(struct net_device *netdev,
>  	i = GVE_MAIN_STATS_LEN;
>  
>  	/* For rx cross-reporting stats, start from nic rx stats in report */
> -	base_stats_idx = GVE_TX_STATS_REPORT_NUM * priv->tx_cfg.num_queues +
> +	base_stats_idx = GVE_TX_STATS_REPORT_NUM * num_tx_queues +
>  		GVE_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues;
>  	max_stats_idx = NIC_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues +
>  		base_stats_idx;
> @@ -298,7 +304,7 @@ gve_get_ethtool_stats(struct net_device *netdev,
>  
>  	/* For tx cross-reporting stats, start from nic tx stats in report */
>  	base_stats_idx = max_stats_idx;
> -	max_stats_idx = NIC_TX_STATS_REPORT_NUM * priv->tx_cfg.num_queues +
> +	max_stats_idx = NIC_TX_STATS_REPORT_NUM * num_tx_queues +
>  		max_stats_idx;
>  	/* Preprocess the stats report for tx, map queue id to start index */
>  	skip_nic_stats = false;
> @@ -316,7 +322,7 @@ gve_get_ethtool_stats(struct net_device *netdev,
>  	}
>  	/* walk TX rings */
>  	if (priv->tx) {
> -		for (ring = 0; ring < priv->tx_cfg.num_queues; ring++) {
> +		for (ring = 0; ring < num_tx_queues; ring++) {
>  			struct gve_tx_ring *tx = &priv->tx[ring];
>  
>  			if (gve_is_gqi(priv)) {
> @@ -355,7 +361,7 @@ gve_get_ethtool_stats(struct net_device *netdev,
>  			}
>  		}
>  	} else {
> -		i += priv->tx_cfg.num_queues * NUM_GVE_TX_CNTS;
> +		i += num_tx_queues * NUM_GVE_TX_CNTS;
>  	}
>  
>  	kfree(rx_qid_to_stats_idx);
> @@ -502,7 +508,9 @@ static int gve_set_priv_flags(struct net_device *netdev, u32 flags)
>  {
>  	struct gve_priv *priv = netdev_priv(netdev);
>  	u64 ori_flags, new_flags;
> +	int num_tx_queues;
>  
> +	num_tx_queues = gve_num_tx_queues(priv);
>  	ori_flags = READ_ONCE(priv->ethtool_flags);
>  	new_flags = ori_flags;
>  
> @@ -522,7 +530,7 @@ static int gve_set_priv_flags(struct net_device *netdev, u32 flags)
>  	/* delete report stats timer. */
>  	if (!(flags & BIT(0)) && (ori_flags & BIT(0))) {
>  		int tx_stats_num = GVE_TX_STATS_REPORT_NUM *
> -			priv->tx_cfg.num_queues;
> +			num_tx_queues;
>  		int rx_stats_num = GVE_RX_STATS_REPORT_NUM *
>  			priv->rx_cfg.num_queues;
>  
> diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
> index 07111c241e0e..3cfdeeb74f60 100644
> --- a/drivers/net/ethernet/google/gve/gve_main.c
> +++ b/drivers/net/ethernet/google/gve/gve_main.c
> @@ -90,8 +90,10 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
>  	struct gve_priv *priv = netdev_priv(dev);
>  	unsigned int start;
>  	u64 packets, bytes;
> +	int num_tx_queues;
>  	int ring;
>  
> +	num_tx_queues = gve_num_tx_queues(priv);
>  	if (priv->rx) {
>  		for (ring = 0; ring < priv->rx_cfg.num_queues; ring++) {
>  			do {
> @@ -106,7 +108,7 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
>  		}
>  	}
>  	if (priv->tx) {
> -		for (ring = 0; ring < priv->tx_cfg.num_queues; ring++) {
> +		for (ring = 0; ring < num_tx_queues; ring++) {
>  			do {
>  				start =
>  				  u64_stats_fetch_begin(&priv->tx[ring].statss);
> @@ -180,7 +182,7 @@ static int gve_alloc_stats_report(struct gve_priv *priv)
>  	int tx_stats_num, rx_stats_num;
>  
>  	tx_stats_num = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) *
> -		       priv->tx_cfg.num_queues;
> +		       gve_num_tx_queues(priv);
>  	rx_stats_num = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
>  		       priv->rx_cfg.num_queues;
>  	priv->stats_report_len = struct_size(priv->stats_report, stats,
> @@ -622,20 +624,21 @@ static int gve_unregister_qpls(struct gve_priv *priv)
>  
>  static int gve_create_rings(struct gve_priv *priv)
>  {
> +	int num_tx_queues = gve_num_tx_queues(priv);
>  	int err;
>  	int i;
>  
> -	err = gve_adminq_create_tx_queues(priv, priv->tx_cfg.num_queues);
> +	err = gve_adminq_create_tx_queues(priv, num_tx_queues);
>  	if (err) {
>  		netif_err(priv, drv, priv->dev, "failed to create %d tx queues\n",
> -			  priv->tx_cfg.num_queues);
> +			  num_tx_queues);
>  		/* This failure will trigger a reset - no need to clean
>  		 * up
>  		 */
>  		return err;
>  	}
>  	netif_dbg(priv, drv, priv->dev, "created %d tx queues\n",
> -		  priv->tx_cfg.num_queues);
> +		  num_tx_queues);
>  
>  	err = gve_adminq_create_rx_queues(priv, priv->rx_cfg.num_queues);
>  	if (err) {
> @@ -675,7 +678,7 @@ static void add_napi_init_sync_stats(struct gve_priv *priv,
>  	int i;
>  
>  	/* Add tx napi & init sync stats*/
> -	for (i = 0; i < priv->tx_cfg.num_queues; i++) {
> +	for (i = 0; i < gve_num_tx_queues(priv); i++) {
>  		int ntfy_idx = gve_tx_idx_to_ntfy(priv, i);
>  
>  		u64_stats_init(&priv->tx[i].statss);
> @@ -753,9 +756,10 @@ static int gve_alloc_rings(struct gve_priv *priv)
>  
>  static int gve_destroy_rings(struct gve_priv *priv)
>  {
> +	int num_tx_queues = gve_num_tx_queues(priv);
>  	int err;
>  
> -	err = gve_adminq_destroy_tx_queues(priv, priv->tx_cfg.num_queues);
> +	err = gve_adminq_destroy_tx_queues(priv, num_tx_queues);
>  	if (err) {
>  		netif_err(priv, drv, priv->dev,
>  			  "failed to destroy tx queues\n");
> @@ -784,11 +788,12 @@ static void gve_rx_free_rings(struct gve_priv *priv)
>  
>  static void gve_free_rings(struct gve_priv *priv)
>  {
> +	int num_tx_queues = gve_num_tx_queues(priv);
>  	int ntfy_idx;
>  	int i;
>  
>  	if (priv->tx) {
> -		for (i = 0; i < priv->tx_cfg.num_queues; i++) {
> +		for (i = 0; i < num_tx_queues; i++) {
>  			ntfy_idx = gve_tx_idx_to_ntfy(priv, i);
>  			gve_remove_napi(priv, ntfy_idx);
>  		}
> @@ -1118,7 +1123,7 @@ static void gve_turndown(struct gve_priv *priv)
>  		return;
>  
>  	/* Disable napi to prevent more work from coming in */
> -	for (idx = 0; idx < priv->tx_cfg.num_queues; idx++) {
> +	for (idx = 0; idx < gve_num_tx_queues(priv); idx++) {
>  		int ntfy_idx = gve_tx_idx_to_ntfy(priv, idx);
>  		struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
>  
> @@ -1146,7 +1151,7 @@ static void gve_turnup(struct gve_priv *priv)
>  	netif_tx_start_all_queues(priv->dev);
>  
>  	/* Enable napi and unmask interrupts for all queues */
> -	for (idx = 0; idx < priv->tx_cfg.num_queues; idx++) {
> +	for (idx = 0; idx < gve_num_tx_queues(priv); idx++) {
>  		int ntfy_idx = gve_tx_idx_to_ntfy(priv, idx);
>  		struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
>  
> @@ -1306,7 +1311,7 @@ void gve_handle_report_stats(struct gve_priv *priv)
>  	be64_add_cpu(&priv->stats_report->written_count, 1);
>  	/* tx stats */
>  	if (priv->tx) {
> -		for (idx = 0; idx < priv->tx_cfg.num_queues; idx++) {
> +		for (idx = 0; idx < gve_num_tx_queues(priv); idx++) {
>  			u32 last_completion = 0;
>  			u32 tx_frames = 0;
>  
> diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c
> index 1f55137722b0..db1c74b1d7d3 100644
> --- a/drivers/net/ethernet/google/gve/gve_rx.c
> +++ b/drivers/net/ethernet/google/gve/gve_rx.c
> @@ -556,7 +556,7 @@ static struct sk_buff *gve_rx_skb(struct gve_priv *priv, struct gve_rx_ring *rx,
>  
>  	if (len <= priv->rx_copybreak && is_only_frag)  {
>  		/* Just copy small packets */
> -		skb = gve_rx_copy(netdev, napi, page_info, len, GVE_RX_PAD);
> +		skb = gve_rx_copy(netdev, napi, page_info, len);
>  		if (skb) {
>  			u64_stats_update_begin(&rx->statss);
>  			rx->rx_copied_pkt++;
> diff --git a/drivers/net/ethernet/google/gve/gve_rx_dqo.c b/drivers/net/ethernet/google/gve/gve_rx_dqo.c
> index 630f42a3037b..e57b73eb70f6 100644
> --- a/drivers/net/ethernet/google/gve/gve_rx_dqo.c
> +++ b/drivers/net/ethernet/google/gve/gve_rx_dqo.c
> @@ -568,7 +568,7 @@ static int gve_rx_dqo(struct napi_struct *napi, struct gve_rx_ring *rx,
>  
>  	if (eop && buf_len <= priv->rx_copybreak) {
>  		rx->ctx.skb_head = gve_rx_copy(priv->dev, napi,
> -					       &buf_state->page_info, buf_len, 0);
> +					       &buf_state->page_info, buf_len);
>  		if (unlikely(!rx->ctx.skb_head))
>  			goto error;
>  		rx->ctx.skb_tail = rx->ctx.skb_head;
> diff --git a/drivers/net/ethernet/google/gve/gve_tx.c b/drivers/net/ethernet/google/gve/gve_tx.c
> index 4888bf05fbed..0fb052ce9e0b 100644
> --- a/drivers/net/ethernet/google/gve/gve_tx.c
> +++ b/drivers/net/ethernet/google/gve/gve_tx.c
> @@ -374,18 +374,18 @@ static int gve_maybe_stop_tx(struct gve_priv *priv, struct gve_tx_ring *tx,
>  }
>  
>  static void gve_tx_fill_pkt_desc(union gve_tx_desc *pkt_desc,
> -				 struct sk_buff *skb, bool is_gso,
> +				 u16 csum_offset, u8 ip_summed, bool is_gso,
>  				 int l4_hdr_offset, u32 desc_cnt,
> -				 u16 hlen, u64 addr)
> +				 u16 hlen, u64 addr, u16 pkt_len)
>  {
>  	/* l4_hdr_offset and csum_offset are in units of 16-bit words */
>  	if (is_gso) {
>  		pkt_desc->pkt.type_flags = GVE_TXD_TSO | GVE_TXF_L4CSUM;
> -		pkt_desc->pkt.l4_csum_offset = skb->csum_offset >> 1;
> +		pkt_desc->pkt.l4_csum_offset = csum_offset >> 1;
>  		pkt_desc->pkt.l4_hdr_offset = l4_hdr_offset >> 1;
> -	} else if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
> +	} else if (likely(ip_summed == CHECKSUM_PARTIAL)) {
>  		pkt_desc->pkt.type_flags = GVE_TXD_STD | GVE_TXF_L4CSUM;
> -		pkt_desc->pkt.l4_csum_offset = skb->csum_offset >> 1;
> +		pkt_desc->pkt.l4_csum_offset = csum_offset >> 1;
>  		pkt_desc->pkt.l4_hdr_offset = l4_hdr_offset >> 1;
>  	} else {
>  		pkt_desc->pkt.type_flags = GVE_TXD_STD;
> @@ -393,7 +393,7 @@ static void gve_tx_fill_pkt_desc(union gve_tx_desc *pkt_desc,
>  		pkt_desc->pkt.l4_hdr_offset = 0;
>  	}
>  	pkt_desc->pkt.desc_cnt = desc_cnt;
> -	pkt_desc->pkt.len = cpu_to_be16(skb->len);
> +	pkt_desc->pkt.len = cpu_to_be16(pkt_len);
>  	pkt_desc->pkt.seg_len = cpu_to_be16(hlen);
>  	pkt_desc->pkt.seg_addr = cpu_to_be64(addr);
>  }
> @@ -412,15 +412,16 @@ static void gve_tx_fill_mtd_desc(union gve_tx_desc *mtd_desc,
>  }
>  
>  static void gve_tx_fill_seg_desc(union gve_tx_desc *seg_desc,
> -				 struct sk_buff *skb, bool is_gso,
> +				 u16 l3_offset, u16 gso_size,
> +				 bool is_gso_v6, bool is_gso,
>  				 u16 len, u64 addr)
>  {
>  	seg_desc->seg.type_flags = GVE_TXD_SEG;
>  	if (is_gso) {
> -		if (skb_is_gso_v6(skb))
> +		if (is_gso_v6)
>  			seg_desc->seg.type_flags |= GVE_TXSF_IPV6;
> -		seg_desc->seg.l3_offset = skb_network_offset(skb) >> 1;
> -		seg_desc->seg.mss = cpu_to_be16(skb_shinfo(skb)->gso_size);
> +		seg_desc->seg.l3_offset = l3_offset >> 1;
> +		seg_desc->seg.mss = cpu_to_be16(gso_size);
>  	}
>  	seg_desc->seg.seg_len = cpu_to_be16(len);
>  	seg_desc->seg.seg_addr = cpu_to_be64(addr);
> @@ -473,9 +474,10 @@ static int gve_tx_add_skb_copy(struct gve_priv *priv, struct gve_tx_ring *tx, st
>  	payload_nfrags = gve_tx_alloc_fifo(&tx->tx_fifo, skb->len - hlen,
>  					   &info->iov[payload_iov]);
>  
> -	gve_tx_fill_pkt_desc(pkt_desc, skb, is_gso, l4_hdr_offset,
> +	gve_tx_fill_pkt_desc(pkt_desc, skb->csum_offset, skb->ip_summed,
> +			     is_gso, l4_hdr_offset,
>  			     1 + mtd_desc_nr + payload_nfrags, hlen,
> -			     info->iov[hdr_nfrags - 1].iov_offset);
> +			     info->iov[hdr_nfrags - 1].iov_offset, skb->len);
>  
>  	skb_copy_bits(skb, 0,
>  		      tx->tx_fifo.base + info->iov[hdr_nfrags - 1].iov_offset,
> @@ -494,7 +496,9 @@ static int gve_tx_add_skb_copy(struct gve_priv *priv, struct gve_tx_ring *tx, st
>  		next_idx = (tx->req + 1 + mtd_desc_nr + i - payload_iov) & tx->mask;
>  		seg_desc = &tx->desc[next_idx];
>  
> -		gve_tx_fill_seg_desc(seg_desc, skb, is_gso,
> +		gve_tx_fill_seg_desc(seg_desc, skb_network_offset(skb),
> +				     skb_shinfo(skb)->gso_size,
> +				     skb_is_gso_v6(skb), is_gso,
>  				     info->iov[i].iov_len,
>  				     info->iov[i].iov_offset);
>  
> @@ -552,8 +556,9 @@ static int gve_tx_add_skb_no_copy(struct gve_priv *priv, struct gve_tx_ring *tx,
>  	if (mtd_desc_nr)
>  		num_descriptors++;
>  
> -	gve_tx_fill_pkt_desc(pkt_desc, skb, is_gso, l4_hdr_offset,
> -			     num_descriptors, hlen, addr);
> +	gve_tx_fill_pkt_desc(pkt_desc, skb->csum_offset, skb->ip_summed,
> +			     is_gso, l4_hdr_offset,
> +			     num_descriptors, hlen, addr, skb->len);
>  
>  	if (mtd_desc_nr) {
>  		idx = (idx + 1) & tx->mask;
> @@ -569,7 +574,9 @@ static int gve_tx_add_skb_no_copy(struct gve_priv *priv, struct gve_tx_ring *tx,
>  		addr += hlen;
>  		idx = (idx + 1) & tx->mask;
>  		seg_desc = &tx->desc[idx];
> -		gve_tx_fill_seg_desc(seg_desc, skb, is_gso, len, addr);
> +		gve_tx_fill_seg_desc(seg_desc, skb_network_offset(skb),
> +				     skb_shinfo(skb)->gso_size,
> +				     skb_is_gso_v6(skb), is_gso, len, addr);
>  	}
>  
>  	for (i = 0; i < shinfo->nr_frags; i++) {
> @@ -587,7 +594,9 @@ static int gve_tx_add_skb_no_copy(struct gve_priv *priv, struct gve_tx_ring *tx,
>  		dma_unmap_len_set(&tx->info[idx], len, len);
>  		dma_unmap_addr_set(&tx->info[idx], dma, addr);
>  
> -		gve_tx_fill_seg_desc(seg_desc, skb, is_gso, len, addr);
> +		gve_tx_fill_seg_desc(seg_desc, skb_network_offset(skb),
> +				     skb_shinfo(skb)->gso_size,
> +				     skb_is_gso_v6(skb), is_gso, len, addr);
>  	}
>  
>  	return num_descriptors;
> diff --git a/drivers/net/ethernet/google/gve/gve_utils.c b/drivers/net/ethernet/google/gve/gve_utils.c
> index 6ba46adaaee3..26e08d753270 100644
> --- a/drivers/net/ethernet/google/gve/gve_utils.c
> +++ b/drivers/net/ethernet/google/gve/gve_utils.c
> @@ -49,10 +49,10 @@ void gve_rx_add_to_block(struct gve_priv *priv, int queue_idx)
>  }
>  
>  struct sk_buff *gve_rx_copy(struct net_device *dev, struct napi_struct *napi,
> -			    struct gve_rx_slot_page_info *page_info, u16 len,
> -			    u16 padding)
> +			    struct gve_rx_slot_page_info *page_info, u16 len)
>  {
> -	void *va = page_info->page_address + padding + page_info->page_offset;
> +	void *va = page_info->page_address + page_info->page_offset +
> +		page_info->pad;
>  	struct sk_buff *skb;
>  
>  	skb = napi_alloc_skb(napi, len);
> diff --git a/drivers/net/ethernet/google/gve/gve_utils.h b/drivers/net/ethernet/google/gve/gve_utils.h
> index 79595940b351..324fd98a6112 100644
> --- a/drivers/net/ethernet/google/gve/gve_utils.h
> +++ b/drivers/net/ethernet/google/gve/gve_utils.h
> @@ -18,8 +18,7 @@ void gve_rx_remove_from_block(struct gve_priv *priv, int queue_idx);
>  void gve_rx_add_to_block(struct gve_priv *priv, int queue_idx);
>  
>  struct sk_buff *gve_rx_copy(struct net_device *dev, struct napi_struct *napi,
> -			    struct gve_rx_slot_page_info *page_info, u16 len,
> -			    u16 pad);
> +			    struct gve_rx_slot_page_info *page_info, u16 len);
>  
>  /* Decrement pagecnt_bias. Set it back to INT_MAX if it reached zero. */
>  void gve_dec_pagecnt_bias(struct gve_rx_slot_page_info *page_info);
> -- 
> 2.40.0.rc1.284.g88254d51c5-goog
>
diff mbox series

Patch

diff --git a/drivers/net/ethernet/google/gve/gve.h b/drivers/net/ethernet/google/gve/gve.h
index 64eb0442c82f..f52f23198278 100644
--- a/drivers/net/ethernet/google/gve/gve.h
+++ b/drivers/net/ethernet/google/gve/gve.h
@@ -855,6 +855,11 @@  static inline bool gve_is_gqi(struct gve_priv *priv)
 		priv->queue_format == GVE_GQI_QPL_FORMAT;
 }
 
+static inline u32 gve_num_tx_queues(struct gve_priv *priv)
+{
+	return priv->tx_cfg.num_queues;
+}
+
 /* buffers */
 int gve_alloc_page(struct gve_priv *priv, struct device *dev,
 		   struct page **page, dma_addr_t *dma,
diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c
index ce574d097e28..5b6e31812fae 100644
--- a/drivers/net/ethernet/google/gve/gve_ethtool.c
+++ b/drivers/net/ethernet/google/gve/gve_ethtool.c
@@ -81,8 +81,10 @@  static void gve_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 {
 	struct gve_priv *priv = netdev_priv(netdev);
 	char *s = (char *)data;
+	int num_tx_queues;
 	int i, j;
 
+	num_tx_queues = gve_num_tx_queues(priv);
 	switch (stringset) {
 	case ETH_SS_STATS:
 		memcpy(s, *gve_gstrings_main_stats,
@@ -97,7 +99,7 @@  static void gve_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 			}
 		}
 
-		for (i = 0; i < priv->tx_cfg.num_queues; i++) {
+		for (i = 0; i < num_tx_queues; i++) {
 			for (j = 0; j < NUM_GVE_TX_CNTS; j++) {
 				snprintf(s, ETH_GSTRING_LEN,
 					 gve_gstrings_tx_stats[j], i);
@@ -124,12 +126,14 @@  static void gve_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
 static int gve_get_sset_count(struct net_device *netdev, int sset)
 {
 	struct gve_priv *priv = netdev_priv(netdev);
+	int num_tx_queues;
 
+	num_tx_queues = gve_num_tx_queues(priv);
 	switch (sset) {
 	case ETH_SS_STATS:
 		return GVE_MAIN_STATS_LEN + GVE_ADMINQ_STATS_LEN +
 		       (priv->rx_cfg.num_queues * NUM_GVE_RX_CNTS) +
-		       (priv->tx_cfg.num_queues * NUM_GVE_TX_CNTS);
+		       (num_tx_queues * NUM_GVE_TX_CNTS);
 	case ETH_SS_PRIV_FLAGS:
 		return GVE_PRIV_FLAGS_STR_LEN;
 	default:
@@ -153,18 +157,20 @@  gve_get_ethtool_stats(struct net_device *netdev,
 	struct gve_priv *priv;
 	bool skip_nic_stats;
 	unsigned int start;
+	int num_tx_queues;
 	int ring;
 	int i, j;
 
 	ASSERT_RTNL();
 
 	priv = netdev_priv(netdev);
+	num_tx_queues = gve_num_tx_queues(priv);
 	report_stats = priv->stats_report->stats;
 	rx_qid_to_stats_idx = kmalloc_array(priv->rx_cfg.num_queues,
 					    sizeof(int), GFP_KERNEL);
 	if (!rx_qid_to_stats_idx)
 		return;
-	tx_qid_to_stats_idx = kmalloc_array(priv->tx_cfg.num_queues,
+	tx_qid_to_stats_idx = kmalloc_array(num_tx_queues,
 					    sizeof(int), GFP_KERNEL);
 	if (!tx_qid_to_stats_idx) {
 		kfree(rx_qid_to_stats_idx);
@@ -195,7 +201,7 @@  gve_get_ethtool_stats(struct net_device *netdev,
 		}
 	}
 	for (tx_pkts = 0, tx_bytes = 0, tx_dropped = 0, ring = 0;
-	     ring < priv->tx_cfg.num_queues; ring++) {
+	     ring < num_tx_queues; ring++) {
 		if (priv->tx) {
 			do {
 				start =
@@ -232,7 +238,7 @@  gve_get_ethtool_stats(struct net_device *netdev,
 	i = GVE_MAIN_STATS_LEN;
 
 	/* For rx cross-reporting stats, start from nic rx stats in report */
-	base_stats_idx = GVE_TX_STATS_REPORT_NUM * priv->tx_cfg.num_queues +
+	base_stats_idx = GVE_TX_STATS_REPORT_NUM * num_tx_queues +
 		GVE_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues;
 	max_stats_idx = NIC_RX_STATS_REPORT_NUM * priv->rx_cfg.num_queues +
 		base_stats_idx;
@@ -298,7 +304,7 @@  gve_get_ethtool_stats(struct net_device *netdev,
 
 	/* For tx cross-reporting stats, start from nic tx stats in report */
 	base_stats_idx = max_stats_idx;
-	max_stats_idx = NIC_TX_STATS_REPORT_NUM * priv->tx_cfg.num_queues +
+	max_stats_idx = NIC_TX_STATS_REPORT_NUM * num_tx_queues +
 		max_stats_idx;
 	/* Preprocess the stats report for tx, map queue id to start index */
 	skip_nic_stats = false;
@@ -316,7 +322,7 @@  gve_get_ethtool_stats(struct net_device *netdev,
 	}
 	/* walk TX rings */
 	if (priv->tx) {
-		for (ring = 0; ring < priv->tx_cfg.num_queues; ring++) {
+		for (ring = 0; ring < num_tx_queues; ring++) {
 			struct gve_tx_ring *tx = &priv->tx[ring];
 
 			if (gve_is_gqi(priv)) {
@@ -355,7 +361,7 @@  gve_get_ethtool_stats(struct net_device *netdev,
 			}
 		}
 	} else {
-		i += priv->tx_cfg.num_queues * NUM_GVE_TX_CNTS;
+		i += num_tx_queues * NUM_GVE_TX_CNTS;
 	}
 
 	kfree(rx_qid_to_stats_idx);
@@ -502,7 +508,9 @@  static int gve_set_priv_flags(struct net_device *netdev, u32 flags)
 {
 	struct gve_priv *priv = netdev_priv(netdev);
 	u64 ori_flags, new_flags;
+	int num_tx_queues;
 
+	num_tx_queues = gve_num_tx_queues(priv);
 	ori_flags = READ_ONCE(priv->ethtool_flags);
 	new_flags = ori_flags;
 
@@ -522,7 +530,7 @@  static int gve_set_priv_flags(struct net_device *netdev, u32 flags)
 	/* delete report stats timer. */
 	if (!(flags & BIT(0)) && (ori_flags & BIT(0))) {
 		int tx_stats_num = GVE_TX_STATS_REPORT_NUM *
-			priv->tx_cfg.num_queues;
+			num_tx_queues;
 		int rx_stats_num = GVE_RX_STATS_REPORT_NUM *
 			priv->rx_cfg.num_queues;
 
diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c
index 07111c241e0e..3cfdeeb74f60 100644
--- a/drivers/net/ethernet/google/gve/gve_main.c
+++ b/drivers/net/ethernet/google/gve/gve_main.c
@@ -90,8 +90,10 @@  static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
 	struct gve_priv *priv = netdev_priv(dev);
 	unsigned int start;
 	u64 packets, bytes;
+	int num_tx_queues;
 	int ring;
 
+	num_tx_queues = gve_num_tx_queues(priv);
 	if (priv->rx) {
 		for (ring = 0; ring < priv->rx_cfg.num_queues; ring++) {
 			do {
@@ -106,7 +108,7 @@  static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
 		}
 	}
 	if (priv->tx) {
-		for (ring = 0; ring < priv->tx_cfg.num_queues; ring++) {
+		for (ring = 0; ring < num_tx_queues; ring++) {
 			do {
 				start =
 				  u64_stats_fetch_begin(&priv->tx[ring].statss);
@@ -180,7 +182,7 @@  static int gve_alloc_stats_report(struct gve_priv *priv)
 	int tx_stats_num, rx_stats_num;
 
 	tx_stats_num = (GVE_TX_STATS_REPORT_NUM + NIC_TX_STATS_REPORT_NUM) *
-		       priv->tx_cfg.num_queues;
+		       gve_num_tx_queues(priv);
 	rx_stats_num = (GVE_RX_STATS_REPORT_NUM + NIC_RX_STATS_REPORT_NUM) *
 		       priv->rx_cfg.num_queues;
 	priv->stats_report_len = struct_size(priv->stats_report, stats,
@@ -622,20 +624,21 @@  static int gve_unregister_qpls(struct gve_priv *priv)
 
 static int gve_create_rings(struct gve_priv *priv)
 {
+	int num_tx_queues = gve_num_tx_queues(priv);
 	int err;
 	int i;
 
-	err = gve_adminq_create_tx_queues(priv, priv->tx_cfg.num_queues);
+	err = gve_adminq_create_tx_queues(priv, num_tx_queues);
 	if (err) {
 		netif_err(priv, drv, priv->dev, "failed to create %d tx queues\n",
-			  priv->tx_cfg.num_queues);
+			  num_tx_queues);
 		/* This failure will trigger a reset - no need to clean
 		 * up
 		 */
 		return err;
 	}
 	netif_dbg(priv, drv, priv->dev, "created %d tx queues\n",
-		  priv->tx_cfg.num_queues);
+		  num_tx_queues);
 
 	err = gve_adminq_create_rx_queues(priv, priv->rx_cfg.num_queues);
 	if (err) {
@@ -675,7 +678,7 @@  static void add_napi_init_sync_stats(struct gve_priv *priv,
 	int i;
 
 	/* Add tx napi & init sync stats*/
-	for (i = 0; i < priv->tx_cfg.num_queues; i++) {
+	for (i = 0; i < gve_num_tx_queues(priv); i++) {
 		int ntfy_idx = gve_tx_idx_to_ntfy(priv, i);
 
 		u64_stats_init(&priv->tx[i].statss);
@@ -753,9 +756,10 @@  static int gve_alloc_rings(struct gve_priv *priv)
 
 static int gve_destroy_rings(struct gve_priv *priv)
 {
+	int num_tx_queues = gve_num_tx_queues(priv);
 	int err;
 
-	err = gve_adminq_destroy_tx_queues(priv, priv->tx_cfg.num_queues);
+	err = gve_adminq_destroy_tx_queues(priv, num_tx_queues);
 	if (err) {
 		netif_err(priv, drv, priv->dev,
 			  "failed to destroy tx queues\n");
@@ -784,11 +788,12 @@  static void gve_rx_free_rings(struct gve_priv *priv)
 
 static void gve_free_rings(struct gve_priv *priv)
 {
+	int num_tx_queues = gve_num_tx_queues(priv);
 	int ntfy_idx;
 	int i;
 
 	if (priv->tx) {
-		for (i = 0; i < priv->tx_cfg.num_queues; i++) {
+		for (i = 0; i < num_tx_queues; i++) {
 			ntfy_idx = gve_tx_idx_to_ntfy(priv, i);
 			gve_remove_napi(priv, ntfy_idx);
 		}
@@ -1118,7 +1123,7 @@  static void gve_turndown(struct gve_priv *priv)
 		return;
 
 	/* Disable napi to prevent more work from coming in */
-	for (idx = 0; idx < priv->tx_cfg.num_queues; idx++) {
+	for (idx = 0; idx < gve_num_tx_queues(priv); idx++) {
 		int ntfy_idx = gve_tx_idx_to_ntfy(priv, idx);
 		struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
 
@@ -1146,7 +1151,7 @@  static void gve_turnup(struct gve_priv *priv)
 	netif_tx_start_all_queues(priv->dev);
 
 	/* Enable napi and unmask interrupts for all queues */
-	for (idx = 0; idx < priv->tx_cfg.num_queues; idx++) {
+	for (idx = 0; idx < gve_num_tx_queues(priv); idx++) {
 		int ntfy_idx = gve_tx_idx_to_ntfy(priv, idx);
 		struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx];
 
@@ -1306,7 +1311,7 @@  void gve_handle_report_stats(struct gve_priv *priv)
 	be64_add_cpu(&priv->stats_report->written_count, 1);
 	/* tx stats */
 	if (priv->tx) {
-		for (idx = 0; idx < priv->tx_cfg.num_queues; idx++) {
+		for (idx = 0; idx < gve_num_tx_queues(priv); idx++) {
 			u32 last_completion = 0;
 			u32 tx_frames = 0;
 
diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c
index 1f55137722b0..db1c74b1d7d3 100644
--- a/drivers/net/ethernet/google/gve/gve_rx.c
+++ b/drivers/net/ethernet/google/gve/gve_rx.c
@@ -556,7 +556,7 @@  static struct sk_buff *gve_rx_skb(struct gve_priv *priv, struct gve_rx_ring *rx,
 
 	if (len <= priv->rx_copybreak && is_only_frag)  {
 		/* Just copy small packets */
-		skb = gve_rx_copy(netdev, napi, page_info, len, GVE_RX_PAD);
+		skb = gve_rx_copy(netdev, napi, page_info, len);
 		if (skb) {
 			u64_stats_update_begin(&rx->statss);
 			rx->rx_copied_pkt++;
diff --git a/drivers/net/ethernet/google/gve/gve_rx_dqo.c b/drivers/net/ethernet/google/gve/gve_rx_dqo.c
index 630f42a3037b..e57b73eb70f6 100644
--- a/drivers/net/ethernet/google/gve/gve_rx_dqo.c
+++ b/drivers/net/ethernet/google/gve/gve_rx_dqo.c
@@ -568,7 +568,7 @@  static int gve_rx_dqo(struct napi_struct *napi, struct gve_rx_ring *rx,
 
 	if (eop && buf_len <= priv->rx_copybreak) {
 		rx->ctx.skb_head = gve_rx_copy(priv->dev, napi,
-					       &buf_state->page_info, buf_len, 0);
+					       &buf_state->page_info, buf_len);
 		if (unlikely(!rx->ctx.skb_head))
 			goto error;
 		rx->ctx.skb_tail = rx->ctx.skb_head;
diff --git a/drivers/net/ethernet/google/gve/gve_tx.c b/drivers/net/ethernet/google/gve/gve_tx.c
index 4888bf05fbed..0fb052ce9e0b 100644
--- a/drivers/net/ethernet/google/gve/gve_tx.c
+++ b/drivers/net/ethernet/google/gve/gve_tx.c
@@ -374,18 +374,18 @@  static int gve_maybe_stop_tx(struct gve_priv *priv, struct gve_tx_ring *tx,
 }
 
 static void gve_tx_fill_pkt_desc(union gve_tx_desc *pkt_desc,
-				 struct sk_buff *skb, bool is_gso,
+				 u16 csum_offset, u8 ip_summed, bool is_gso,
 				 int l4_hdr_offset, u32 desc_cnt,
-				 u16 hlen, u64 addr)
+				 u16 hlen, u64 addr, u16 pkt_len)
 {
 	/* l4_hdr_offset and csum_offset are in units of 16-bit words */
 	if (is_gso) {
 		pkt_desc->pkt.type_flags = GVE_TXD_TSO | GVE_TXF_L4CSUM;
-		pkt_desc->pkt.l4_csum_offset = skb->csum_offset >> 1;
+		pkt_desc->pkt.l4_csum_offset = csum_offset >> 1;
 		pkt_desc->pkt.l4_hdr_offset = l4_hdr_offset >> 1;
-	} else if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+	} else if (likely(ip_summed == CHECKSUM_PARTIAL)) {
 		pkt_desc->pkt.type_flags = GVE_TXD_STD | GVE_TXF_L4CSUM;
-		pkt_desc->pkt.l4_csum_offset = skb->csum_offset >> 1;
+		pkt_desc->pkt.l4_csum_offset = csum_offset >> 1;
 		pkt_desc->pkt.l4_hdr_offset = l4_hdr_offset >> 1;
 	} else {
 		pkt_desc->pkt.type_flags = GVE_TXD_STD;
@@ -393,7 +393,7 @@  static void gve_tx_fill_pkt_desc(union gve_tx_desc *pkt_desc,
 		pkt_desc->pkt.l4_hdr_offset = 0;
 	}
 	pkt_desc->pkt.desc_cnt = desc_cnt;
-	pkt_desc->pkt.len = cpu_to_be16(skb->len);
+	pkt_desc->pkt.len = cpu_to_be16(pkt_len);
 	pkt_desc->pkt.seg_len = cpu_to_be16(hlen);
 	pkt_desc->pkt.seg_addr = cpu_to_be64(addr);
 }
@@ -412,15 +412,16 @@  static void gve_tx_fill_mtd_desc(union gve_tx_desc *mtd_desc,
 }
 
 static void gve_tx_fill_seg_desc(union gve_tx_desc *seg_desc,
-				 struct sk_buff *skb, bool is_gso,
+				 u16 l3_offset, u16 gso_size,
+				 bool is_gso_v6, bool is_gso,
 				 u16 len, u64 addr)
 {
 	seg_desc->seg.type_flags = GVE_TXD_SEG;
 	if (is_gso) {
-		if (skb_is_gso_v6(skb))
+		if (is_gso_v6)
 			seg_desc->seg.type_flags |= GVE_TXSF_IPV6;
-		seg_desc->seg.l3_offset = skb_network_offset(skb) >> 1;
-		seg_desc->seg.mss = cpu_to_be16(skb_shinfo(skb)->gso_size);
+		seg_desc->seg.l3_offset = l3_offset >> 1;
+		seg_desc->seg.mss = cpu_to_be16(gso_size);
 	}
 	seg_desc->seg.seg_len = cpu_to_be16(len);
 	seg_desc->seg.seg_addr = cpu_to_be64(addr);
@@ -473,9 +474,10 @@  static int gve_tx_add_skb_copy(struct gve_priv *priv, struct gve_tx_ring *tx, st
 	payload_nfrags = gve_tx_alloc_fifo(&tx->tx_fifo, skb->len - hlen,
 					   &info->iov[payload_iov]);
 
-	gve_tx_fill_pkt_desc(pkt_desc, skb, is_gso, l4_hdr_offset,
+	gve_tx_fill_pkt_desc(pkt_desc, skb->csum_offset, skb->ip_summed,
+			     is_gso, l4_hdr_offset,
 			     1 + mtd_desc_nr + payload_nfrags, hlen,
-			     info->iov[hdr_nfrags - 1].iov_offset);
+			     info->iov[hdr_nfrags - 1].iov_offset, skb->len);
 
 	skb_copy_bits(skb, 0,
 		      tx->tx_fifo.base + info->iov[hdr_nfrags - 1].iov_offset,
@@ -494,7 +496,9 @@  static int gve_tx_add_skb_copy(struct gve_priv *priv, struct gve_tx_ring *tx, st
 		next_idx = (tx->req + 1 + mtd_desc_nr + i - payload_iov) & tx->mask;
 		seg_desc = &tx->desc[next_idx];
 
-		gve_tx_fill_seg_desc(seg_desc, skb, is_gso,
+		gve_tx_fill_seg_desc(seg_desc, skb_network_offset(skb),
+				     skb_shinfo(skb)->gso_size,
+				     skb_is_gso_v6(skb), is_gso,
 				     info->iov[i].iov_len,
 				     info->iov[i].iov_offset);
 
@@ -552,8 +556,9 @@  static int gve_tx_add_skb_no_copy(struct gve_priv *priv, struct gve_tx_ring *tx,
 	if (mtd_desc_nr)
 		num_descriptors++;
 
-	gve_tx_fill_pkt_desc(pkt_desc, skb, is_gso, l4_hdr_offset,
-			     num_descriptors, hlen, addr);
+	gve_tx_fill_pkt_desc(pkt_desc, skb->csum_offset, skb->ip_summed,
+			     is_gso, l4_hdr_offset,
+			     num_descriptors, hlen, addr, skb->len);
 
 	if (mtd_desc_nr) {
 		idx = (idx + 1) & tx->mask;
@@ -569,7 +574,9 @@  static int gve_tx_add_skb_no_copy(struct gve_priv *priv, struct gve_tx_ring *tx,
 		addr += hlen;
 		idx = (idx + 1) & tx->mask;
 		seg_desc = &tx->desc[idx];
-		gve_tx_fill_seg_desc(seg_desc, skb, is_gso, len, addr);
+		gve_tx_fill_seg_desc(seg_desc, skb_network_offset(skb),
+				     skb_shinfo(skb)->gso_size,
+				     skb_is_gso_v6(skb), is_gso, len, addr);
 	}
 
 	for (i = 0; i < shinfo->nr_frags; i++) {
@@ -587,7 +594,9 @@  static int gve_tx_add_skb_no_copy(struct gve_priv *priv, struct gve_tx_ring *tx,
 		dma_unmap_len_set(&tx->info[idx], len, len);
 		dma_unmap_addr_set(&tx->info[idx], dma, addr);
 
-		gve_tx_fill_seg_desc(seg_desc, skb, is_gso, len, addr);
+		gve_tx_fill_seg_desc(seg_desc, skb_network_offset(skb),
+				     skb_shinfo(skb)->gso_size,
+				     skb_is_gso_v6(skb), is_gso, len, addr);
 	}
 
 	return num_descriptors;
diff --git a/drivers/net/ethernet/google/gve/gve_utils.c b/drivers/net/ethernet/google/gve/gve_utils.c
index 6ba46adaaee3..26e08d753270 100644
--- a/drivers/net/ethernet/google/gve/gve_utils.c
+++ b/drivers/net/ethernet/google/gve/gve_utils.c
@@ -49,10 +49,10 @@  void gve_rx_add_to_block(struct gve_priv *priv, int queue_idx)
 }
 
 struct sk_buff *gve_rx_copy(struct net_device *dev, struct napi_struct *napi,
-			    struct gve_rx_slot_page_info *page_info, u16 len,
-			    u16 padding)
+			    struct gve_rx_slot_page_info *page_info, u16 len)
 {
-	void *va = page_info->page_address + padding + page_info->page_offset;
+	void *va = page_info->page_address + page_info->page_offset +
+		page_info->pad;
 	struct sk_buff *skb;
 
 	skb = napi_alloc_skb(napi, len);
diff --git a/drivers/net/ethernet/google/gve/gve_utils.h b/drivers/net/ethernet/google/gve/gve_utils.h
index 79595940b351..324fd98a6112 100644
--- a/drivers/net/ethernet/google/gve/gve_utils.h
+++ b/drivers/net/ethernet/google/gve/gve_utils.h
@@ -18,8 +18,7 @@  void gve_rx_remove_from_block(struct gve_priv *priv, int queue_idx);
 void gve_rx_add_to_block(struct gve_priv *priv, int queue_idx);
 
 struct sk_buff *gve_rx_copy(struct net_device *dev, struct napi_struct *napi,
-			    struct gve_rx_slot_page_info *page_info, u16 len,
-			    u16 pad);
+			    struct gve_rx_slot_page_info *page_info, u16 len);
 
 /* Decrement pagecnt_bias. Set it back to INT_MAX if it reached zero. */
 void gve_dec_pagecnt_bias(struct gve_rx_slot_page_info *page_info);