net: lpc_eth: free skbs in start_xmit
Transmitted skbs can be freed immediately in lpc_eth_hard_start_xmit() instead of at TX completion, since driver copies the frames in DMA area. Signed-off-by: Eric Dumazet <edumazet@google.com> Tested-by: Roland Stigge <stigge@antcom.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
79504d708d
commit
a7e2eaadd0
@ -440,7 +440,7 @@ struct netdata_local {
|
|||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
void __iomem *net_base;
|
void __iomem *net_base;
|
||||||
u32 msg_enable;
|
u32 msg_enable;
|
||||||
struct sk_buff *skb[ENET_TX_DESC];
|
unsigned int skblen[ENET_TX_DESC];
|
||||||
unsigned int last_tx_idx;
|
unsigned int last_tx_idx;
|
||||||
unsigned int num_used_tx_buffs;
|
unsigned int num_used_tx_buffs;
|
||||||
struct mii_bus *mii_bus;
|
struct mii_bus *mii_bus;
|
||||||
@ -903,12 +903,11 @@ err_out:
|
|||||||
static void __lpc_handle_xmit(struct net_device *ndev)
|
static void __lpc_handle_xmit(struct net_device *ndev)
|
||||||
{
|
{
|
||||||
struct netdata_local *pldat = netdev_priv(ndev);
|
struct netdata_local *pldat = netdev_priv(ndev);
|
||||||
struct sk_buff *skb;
|
|
||||||
u32 txcidx, *ptxstat, txstat;
|
u32 txcidx, *ptxstat, txstat;
|
||||||
|
|
||||||
txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base));
|
txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base));
|
||||||
while (pldat->last_tx_idx != txcidx) {
|
while (pldat->last_tx_idx != txcidx) {
|
||||||
skb = pldat->skb[pldat->last_tx_idx];
|
unsigned int skblen = pldat->skblen[pldat->last_tx_idx];
|
||||||
|
|
||||||
/* A buffer is available, get buffer status */
|
/* A buffer is available, get buffer status */
|
||||||
ptxstat = &pldat->tx_stat_v[pldat->last_tx_idx];
|
ptxstat = &pldat->tx_stat_v[pldat->last_tx_idx];
|
||||||
@ -945,9 +944,8 @@ static void __lpc_handle_xmit(struct net_device *ndev)
|
|||||||
} else {
|
} else {
|
||||||
/* Update stats */
|
/* Update stats */
|
||||||
ndev->stats.tx_packets++;
|
ndev->stats.tx_packets++;
|
||||||
ndev->stats.tx_bytes += skb->len;
|
ndev->stats.tx_bytes += skblen;
|
||||||
}
|
}
|
||||||
dev_kfree_skb_irq(skb);
|
|
||||||
|
|
||||||
txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base));
|
txcidx = readl(LPC_ENET_TXCONSUMEINDEX(pldat->net_base));
|
||||||
}
|
}
|
||||||
@ -1132,7 +1130,7 @@ static int lpc_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
|||||||
memcpy(pldat->tx_buff_v + txidx * ENET_MAXF_SIZE, skb->data, len);
|
memcpy(pldat->tx_buff_v + txidx * ENET_MAXF_SIZE, skb->data, len);
|
||||||
|
|
||||||
/* Save the buffer and increment the buffer counter */
|
/* Save the buffer and increment the buffer counter */
|
||||||
pldat->skb[txidx] = skb;
|
pldat->skblen[txidx] = len;
|
||||||
pldat->num_used_tx_buffs++;
|
pldat->num_used_tx_buffs++;
|
||||||
|
|
||||||
/* Start transmit */
|
/* Start transmit */
|
||||||
@ -1147,6 +1145,7 @@ static int lpc_eth_hard_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
|||||||
|
|
||||||
spin_unlock_irq(&pldat->lock);
|
spin_unlock_irq(&pldat->lock);
|
||||||
|
|
||||||
|
dev_kfree_skb(skb);
|
||||||
return NETDEV_TX_OK;
|
return NETDEV_TX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user