From: Sreedevi Joshi <sreedevi.jo...@intel.com> This is to fix mount.nfs over TCP generating the following circular dependency and possible DEADLOCK message. FEMAC driver has been converted to LLTX to avoid this issue. Tx lock is introduced in the FEMAC driver.
CPU0 CPU1 ---- ---- lock(clock-AF_INET); lock(_xmit_ETHER#2); lock(clock-AF_INET); lock(_xmit_ETHER#2); *** DEADLOCK *** Signed-off-by: Sreedevi Joshi <sreedevi.jo...@intel.com> --- drivers/net/ethernet/lsi/lsi_acp_net.c | 12 ++++++++++++ drivers/net/ethernet/lsi/lsi_acp_net.h | 1 + 2 files changed, 13 insertions(+) diff --git a/drivers/net/ethernet/lsi/lsi_acp_net.c b/drivers/net/ethernet/lsi/lsi_acp_net.c index 1973e04..8ea1ca1 100644 --- a/drivers/net/ethernet/lsi/lsi_acp_net.c +++ b/drivers/net/ethernet/lsi/lsi_acp_net.c @@ -895,6 +895,7 @@ static irqreturn_t appnic_isr(int irq, void *device_id) struct appnic_device *pdata = netdev_priv(dev); unsigned long dma_interrupt_status; unsigned long flags; + unsigned long flags1; /* Acquire the lock. */ spin_lock_irqsave(&pdata->dev_lock, flags); @@ -910,7 +911,9 @@ static irqreturn_t appnic_isr(int irq, void *device_id) if (TX_INTERRUPT(dma_interrupt_status)) { /* transmition complete */ pdata->transmit_interrupts++; + spin_lock_irqsave(&pdata->tx_lock, flags1); handle_transmit_interrupt(dev); + spin_unlock_irqrestore(&pdata->tx_lock, flags1); } if (RX_INTERRUPT(dma_interrupt_status)) { @@ -1046,6 +1049,10 @@ static int appnic_hard_start_xmit(struct sk_buff *skb, int length; int buf_per_desc; union appnic_queue_pointer queue; + unsigned long flags; + + if (!spin_trylock_irqsave(&pdata->tx_lock, flags)) + return NETDEV_TX_LOCKED; length = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len; buf_per_desc = pdata->tx_buf_sz / pdata->tx_num_desc; @@ -1124,9 +1131,11 @@ static int appnic_hard_start_xmit(struct sk_buff *skb, pdata->out_of_tx_descriptors++; pr_err("%s: No transmit descriptors available!\n", LSI_DRV_NAME); + spin_unlock_irqrestore(&pdata->tx_lock, flags); return NETDEV_TX_BUSY; } + spin_unlock_irqrestore(&pdata->tx_lock, flags); /* Free the socket buffer. */ dev_kfree_skb(skb); @@ -1525,6 +1534,7 @@ int appnic_init(struct net_device *dev) /* Initialize the spinlocks. */ spin_lock_init(&pdata->dev_lock); + spin_lock_init(&pdata->tx_lock); /* Take MAC out of reset. */ @@ -1650,6 +1660,8 @@ int appnic_init(struct net_device *dev) dev->netdev_ops = &appnic_netdev_ops; dev->ethtool_ops = &appnic_ethtool_ops; + dev->features |= NETIF_F_LLTX; + memset((void *) &pdata->napi, 0, sizeof(struct napi_struct)); netif_napi_add(dev, &pdata->napi, diff --git a/drivers/net/ethernet/lsi/lsi_acp_net.h b/drivers/net/ethernet/lsi/lsi_acp_net.h index ac891cf..b2622b4 100644 --- a/drivers/net/ethernet/lsi/lsi_acp_net.h +++ b/drivers/net/ethernet/lsi/lsi_acp_net.h @@ -190,6 +190,7 @@ struct appnic_device { /* Spin Lock */ spinlock_t dev_lock; + spinlock_t tx_lock; /* PHY */ struct mii_bus *mii_bus; -- 1.7.9.5 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto