aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-01-03 00:27:47 -0500
committerDavid S. Miller <davem@davemloft.net>2012-01-03 13:50:49 -0500
commit86d8c07ff2448eb4e860e50f34ef6ee78e45c40c (patch)
treef9ea58e3a3f5c9bcff28e36feb9b444d78fb0e9c
parentfa0f5aa74316c636427ac92dad0bc5714c34ca17 (diff)
net/davinci: do not use all descriptors for tx packets
The driver uses a shared pool for both rx and tx descriptors. During open it queues fixed number of 128 descriptors for receive packets. For each received packet it tries to queue another descriptor. If this fails the descriptor is lost for rx. The driver has no limitation on tx descriptors to use, so it can happen during a nmap / ping -f attack that the driver allocates all descriptors for tx and looses all rx descriptors. The driver stops working then. To fix this limit the number of tx descriptors used to half of the descriptors available, the rx path uses the other half. Tested on a custom board using nmap / ping -f to the board from two different hosts. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/ti/davinci_emac.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 815c7970261b..794ac30a577b 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -115,6 +115,7 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
115#define EMAC_DEF_TX_CH (0) /* Default 0th channel */ 115#define EMAC_DEF_TX_CH (0) /* Default 0th channel */
116#define EMAC_DEF_RX_CH (0) /* Default 0th channel */ 116#define EMAC_DEF_RX_CH (0) /* Default 0th channel */
117#define EMAC_DEF_RX_NUM_DESC (128) 117#define EMAC_DEF_RX_NUM_DESC (128)
118#define EMAC_DEF_TX_NUM_DESC (128)
118#define EMAC_DEF_MAX_TX_CH (1) /* Max TX channels configured */ 119#define EMAC_DEF_MAX_TX_CH (1) /* Max TX channels configured */
119#define EMAC_DEF_MAX_RX_CH (1) /* Max RX channels configured */ 120#define EMAC_DEF_MAX_RX_CH (1) /* Max RX channels configured */
120#define EMAC_POLL_WEIGHT (64) /* Default NAPI poll weight */ 121#define EMAC_POLL_WEIGHT (64) /* Default NAPI poll weight */
@@ -336,6 +337,7 @@ struct emac_priv {
336 u32 mac_hash2; 337 u32 mac_hash2;
337 u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS]; 338 u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS];
338 u32 rx_addr_type; 339 u32 rx_addr_type;
340 atomic_t cur_tx;
339 const char *phy_id; 341 const char *phy_id;
340 struct phy_device *phydev; 342 struct phy_device *phydev;
341 spinlock_t lock; 343 spinlock_t lock;
@@ -1044,6 +1046,9 @@ static void emac_tx_handler(void *token, int len, int status)
1044{ 1046{
1045 struct sk_buff *skb = token; 1047 struct sk_buff *skb = token;
1046 struct net_device *ndev = skb->dev; 1048 struct net_device *ndev = skb->dev;
1049 struct emac_priv *priv = netdev_priv(ndev);
1050
1051 atomic_dec(&priv->cur_tx);
1047 1052
1048 if (unlikely(netif_queue_stopped(ndev))) 1053 if (unlikely(netif_queue_stopped(ndev)))
1049 netif_start_queue(ndev); 1054 netif_start_queue(ndev);
@@ -1092,6 +1097,9 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
1092 goto fail_tx; 1097 goto fail_tx;
1093 } 1098 }
1094 1099
1100 if (atomic_inc_return(&priv->cur_tx) >= EMAC_DEF_TX_NUM_DESC)
1101 netif_stop_queue(ndev);
1102
1095 return NETDEV_TX_OK; 1103 return NETDEV_TX_OK;
1096 1104
1097fail_tx: 1105fail_tx: