diff options
Diffstat (limited to 'net/xdp/xsk.c')
| -rw-r--r-- | net/xdp/xsk.c | 16 | 
1 files changed, 9 insertions, 7 deletions
| diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index 19ac872a6624..09002387987e 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -538,12 +538,6 @@ static int xsk_generic_xmit(struct sock *sk)  			goto out;  		} -		skb = xsk_build_skb(xs, &desc); -		if (IS_ERR(skb)) { -			err = PTR_ERR(skb); -			goto out; -		} -  		/* This is the backpressure mechanism for the Tx path.  		 * Reserve space in the completion queue and only proceed  		 * if there is space in it. This avoids having to implement @@ -552,11 +546,19 @@ static int xsk_generic_xmit(struct sock *sk)  		spin_lock_irqsave(&xs->pool->cq_lock, flags);  		if (xskq_prod_reserve(xs->pool->cq)) {  			spin_unlock_irqrestore(&xs->pool->cq_lock, flags); -			kfree_skb(skb);  			goto out;  		}  		spin_unlock_irqrestore(&xs->pool->cq_lock, flags); +		skb = xsk_build_skb(xs, &desc); +		if (IS_ERR(skb)) { +			err = PTR_ERR(skb); +			spin_lock_irqsave(&xs->pool->cq_lock, flags); +			xskq_prod_cancel(xs->pool->cq); +			spin_unlock_irqrestore(&xs->pool->cq_lock, flags); +			goto out; +		} +  		err = __dev_direct_xmit(skb, xs->queue_id);  		if  (err == NETDEV_TX_BUSY) {  			/* Tell user-space to retry the send */ |