[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