提交 938fa488 编写于 作者: R Rasesh Mody 提交者: David S. Miller

bna: SKB PCI UNMAP Fix

Change details:
 - Found a leak in sk_buff unmapping of PCI dma addresses where boundary
   conditions are not properly handled in freeing all Tx buffers. Freeing
   of all Tx buffers is done considering sk_buffs data and fragments can
   be mapped at the boundary.
Signed-off-by: NGurunatha Karaje <gkaraje@brocade.com>
Signed-off-by: NRasesh Mody <rmody@brocade.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 41eb5ba4
...@@ -137,39 +137,20 @@ bnad_free_all_txbufs(struct bnad *bnad, ...@@ -137,39 +137,20 @@ bnad_free_all_txbufs(struct bnad *bnad,
struct bnad_unmap_q *unmap_q = tcb->unmap_q; struct bnad_unmap_q *unmap_q = tcb->unmap_q;
struct bnad_skb_unmap *unmap_array; struct bnad_skb_unmap *unmap_array;
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
int i; int q;
unmap_array = unmap_q->unmap_array; unmap_array = unmap_q->unmap_array;
unmap_cons = 0; for (q = 0; q < unmap_q->q_depth; q++) {
while (unmap_cons < unmap_q->q_depth) { skb = unmap_array[q].skb;
skb = unmap_array[unmap_cons].skb; if (!skb)
if (!skb) {
unmap_cons++;
continue; continue;
}
unmap_array[unmap_cons].skb = NULL;
dma_unmap_single(&bnad->pcidev->dev,
dma_unmap_addr(&unmap_array[unmap_cons],
dma_addr), skb_headlen(skb),
DMA_TO_DEVICE);
dma_unmap_addr_set(&unmap_array[unmap_cons], dma_addr, 0); unmap_cons = q;
if (++unmap_cons >= unmap_q->q_depth) unmap_cons = bnad_pci_unmap_skb(&bnad->pcidev->dev, unmap_array,
break; unmap_cons, unmap_q->q_depth, skb,
skb_shinfo(skb)->nr_frags);
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
dma_unmap_page(&bnad->pcidev->dev,
dma_unmap_addr(&unmap_array[unmap_cons],
dma_addr),
skb_shinfo(skb)->frags[i].size,
DMA_TO_DEVICE);
dma_unmap_addr_set(&unmap_array[unmap_cons], dma_addr,
0);
if (++unmap_cons >= unmap_q->q_depth)
break;
}
dev_kfree_skb_any(skb); dev_kfree_skb_any(skb);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册