Skip to content

Commit fea7b71

Browse files
alobakinanguy11
authored andcommitted
idpf: fix corrupted frames and skb leaks in singleq mode
idpf_ring::skb serves only for keeping an incomplete frame between several NAPI Rx polling cycles, as one cycle may end up before processing the end of packet descriptor. The pointer is taken from the ring onto the stack before entering the loop and gets written there after the loop exits. When inside the loop, only the onstack pointer is used. For some reason, the logics is broken in the singleq mode, where the pointer is taken from the ring each iteration. This means that if a frame got fragmented into several descriptors, each fragment will have its own skb, but only the last one will be passed up the stack (containing garbage), leaving the rest leaked. Then, on ifdown, rxq::skb is being freed only in the splitq mode, while it can point to a valid skb in singleq as well. This can lead to a yet another skb leak. Just don't touch the ring skb field inside the polling loop, letting the onstack skb pointer work as expected: build a new skb if it's the first frame descriptor and attach a frag otherwise. On ifdown, free rxq::skb unconditionally if the pointer is non-NULL. Fixes: a5ab9ee ("idpf: add singleq start_xmit and napi poll") Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Reviewed-by: Michal Kubiak <michal.kubiak@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Reviewed-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com> Tested-by: Scott Register <scott.register@intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
1 parent dff90e4 commit fea7b71

File tree

2 files changed

+1
-2
lines changed

2 files changed

+1
-2
lines changed

drivers/net/ethernet/intel/idpf/idpf_singleq_txrx.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,6 @@ static int idpf_rx_singleq_clean(struct idpf_queue *rx_q, int budget)
10441044
}
10451045

10461046
idpf_rx_sync_for_cpu(rx_buf, fields.size);
1047-
skb = rx_q->skb;
10481047
if (skb)
10491048
idpf_rx_add_frag(rx_buf, skb, fields.size);
10501049
else

drivers/net/ethernet/intel/idpf/idpf_txrx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ static void idpf_rx_desc_rel(struct idpf_queue *rxq, bool bufq, s32 q_model)
396396
if (!rxq)
397397
return;
398398

399-
if (!bufq && idpf_is_queue_model_split(q_model) && rxq->skb) {
399+
if (rxq->skb) {
400400
dev_kfree_skb_any(rxq->skb);
401401
rxq->skb = NULL;
402402
}

0 commit comments

Comments
 (0)