Skip to content

Commit

Permalink
tg3: Fix 4k skb error recovery path
Browse files Browse the repository at this point in the history
On the error recovery resource unwind path, it is possible for the
driver to attempt to unmap a fragment that hadn't been mapped.  This
patch fixes the problem by correcting the "last" parameter supplied.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Matt Carlson authored and David S. Miller committed Nov 4, 2011
1 parent b9e4548 commit ba1142e
Showing 1 changed file with 8 additions and 8 deletions.
16 changes: 8 additions & 8 deletions drivers/net/ethernet/broadcom/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -6507,7 +6507,7 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last)
txb = &tnapi->tx_buffers[entry];
}

for (i = 0; i < last; i++) {
for (i = 0; i <= last; i++) {
const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];

entry = NEXT_TX(entry);
Expand Down Expand Up @@ -6568,7 +6568,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
if (tg3_tx_frag_set(tnapi, entry, budget, new_addr,
new_skb->len, base_flags,
mss, vlan)) {
tg3_tx_skb_unmap(tnapi, save_entry, 0);
tg3_tx_skb_unmap(tnapi, save_entry, -1);
dev_kfree_skb(new_skb);
ret = -1;
}
Expand Down Expand Up @@ -6758,11 +6758,10 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)

if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags |
((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0),
mss, vlan))
mss, vlan)) {
would_hit_hwbug = 1;

/* Now loop through additional data fragments, and queue them. */
if (skb_shinfo(skb)->nr_frags > 0) {
} else if (skb_shinfo(skb)->nr_frags > 0) {
u32 tmp_mss = mss;

if (!tg3_flag(tp, HW_TSO_1) &&
Expand Down Expand Up @@ -6831,7 +6830,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;

dma_error:
tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i);
tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, --i);
tnapi->tx_buffers[tnapi->tx_prod].skb = NULL;
drop:
dev_kfree_skb(skb);
Expand Down Expand Up @@ -7284,7 +7283,8 @@ static void tg3_free_rings(struct tg3 *tp)
if (!skb)
continue;

tg3_tx_skb_unmap(tnapi, i, skb_shinfo(skb)->nr_frags);
tg3_tx_skb_unmap(tnapi, i,
skb_shinfo(skb)->nr_frags - 1);

dev_kfree_skb_any(skb);
}
Expand Down Expand Up @@ -11523,7 +11523,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback)
break;
}

tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, 0);
tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, -1);
dev_kfree_skb(skb);

if (tx_idx != tnapi->tx_prod)
Expand Down

0 comments on commit ba1142e

Please sign in to comment.