Skip to content

Commit 86d8c07

Browse files
saschahauerdavem330
authored andcommitted
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>
1 parent fa0f5aa commit 86d8c07

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

drivers/net/ethernet/ti/davinci_emac.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
115115
#define EMAC_DEF_TX_CH (0) /* Default 0th channel */
116116
#define EMAC_DEF_RX_CH (0) /* Default 0th channel */
117117
#define EMAC_DEF_RX_NUM_DESC (128)
118+
#define EMAC_DEF_TX_NUM_DESC (128)
118119
#define EMAC_DEF_MAX_TX_CH (1) /* Max TX channels configured */
119120
#define EMAC_DEF_MAX_RX_CH (1) /* Max RX channels configured */
120121
#define EMAC_POLL_WEIGHT (64) /* Default NAPI poll weight */
@@ -336,6 +337,7 @@ struct emac_priv {
336337
u32 mac_hash2;
337338
u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS];
338339
u32 rx_addr_type;
340+
atomic_t cur_tx;
339341
const char *phy_id;
340342
struct phy_device *phydev;
341343
spinlock_t lock;
@@ -1044,6 +1046,9 @@ static void emac_tx_handler(void *token, int len, int status)
10441046
{
10451047
struct sk_buff *skb = token;
10461048
struct net_device *ndev = skb->dev;
1049+
struct emac_priv *priv = netdev_priv(ndev);
1050+
1051+
atomic_dec(&priv->cur_tx);
10471052

10481053
if (unlikely(netif_queue_stopped(ndev)))
10491054
netif_start_queue(ndev);
@@ -1092,6 +1097,9 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
10921097
goto fail_tx;
10931098
}
10941099

1100+
if (atomic_inc_return(&priv->cur_tx) >= EMAC_DEF_TX_NUM_DESC)
1101+
netif_stop_queue(ndev);
1102+
10951103
return NETDEV_TX_OK;
10961104

10971105
fail_tx:

0 commit comments

Comments
 (0)