[Devel] [PATCH RH8 2/4] net/drivers/i40e: suppress warning on skb linearization

Konstantin Khorenko khorenko at virtuozzo.com
Fri Jun 18 15:32:08 MSK 2021


On 06/18/2021 02:32 PM, Pavel Tikhomirov wrote:
> From: Jan Dakinevich <jan.dakinevich at virtuozzo.com>
>
> Preallocate required memory with reasoned flags and skip memory
> allocation step made by __pskb_pull_tail.
>
> https://pmc.acronis.com/browse/VSTOR-22811
> Signed-off-by: Jan Dakinevich <jan.dakinevich at virtuozzo.com>
> Acked-by: Konstantin Khorenko <khorenko at virtuozzo.com>
>
> khorenko@:
> * skb buffer is provided to DMA zone, so allocation cannot be switched to
>   kvmalloc(), so we just supress the warning here.
>
> * i40e_skb_linearize() code is taken from __pskb_pull_tail(),
>   except for the size: we omit "+128" preallocation here
>   because no future expansions are expected in this case.
>
> * there is another similar place: i40e_xmit_frame_ring() in i40evf/i40e_txrx.c,
>   but as we did not trigger the warning there and as we just shut up the warning,
>   we don't touch the second place in advance.
>
> https://jira.sw.ru/browse/PSBM-127846
> (cherry-picked from vz7 commit 9b2d96420858 ("net/drivers/i40e: suppress
> warning on skb linearization"))
> Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> ---
>  drivers/net/ethernet/intel/i40e/i40e_txrx.c | 19 ++++++++++++++++++-
>  1 file changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> index 1c56ec2421d4..edc094db762e 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
> @@ -3554,6 +3554,23 @@ static int i40e_xmit_xdp_ring(struct xdp_frame *xdpf,
>  	return I40E_XDP_TX;
>  }
>
> +
> +static int i40e_skb_linearize(struct sk_buff *skb)
> +{
> +	int eat = (skb->tail + skb->data_len) - skb->end;
> +
> +	/* workaround to avoid allocation without __GFP_ORDER_NOWARN inside
> +	 * __pskb_pull_tail()
> +	 */
> +	if (eat > 0 || skb_cloned(skb)) {
> +		if (pskb_expand_head(skb, 0, eat > 0 ? eat : 0,
> +				     GFP_ATOMIC | __GFP_ORDER_NOWARN))
> +			return -ENOMEM;

If we return not NULL here, then in case of out of memory we return NETDEV_TX_OK in i40e_xmit_frame_ring()
which is a bit unexpected.


void *__pskb_pull_tail(struct sk_buff *skb, int delta)
{
         /* If skb has not enough free space at tail, get new one
          * plus 128 bytes for future expansions. If we have enough
          * room at tail, reallocate without expansion only if skb is cloned.
          */
         int i, k, eat = (skb->tail + delta) - skb->end;

         if (eat > 0 || skb_cloned(skb)) {
                 if (pskb_expand_head(skb, 0, eat > 0 ? eat + 128 : 0,
                                      GFP_ATOMIC))
                         return NULL;
         }




> +	}
> +
> +	return __skb_linearize(skb);
> +}
> +
>  /**
>   * i40e_xmit_frame_ring - Sends buffer on Tx ring
>   * @skb:     send buffer
> @@ -3582,7 +3599,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
>
>  	count = i40e_xmit_descriptor_count(skb);
>  	if (i40e_chk_linearize(skb, count)) {
> -		if (__skb_linearize(skb)) {
> +		if (i40e_skb_linearize(skb)) {
>  			dev_kfree_skb_any(skb);
>  			return NETDEV_TX_OK;
>  		}
>


More information about the Devel mailing list