Author: hselasky
Date: Fri Apr 29 11:10:43 2016
New Revision: 298774
URL: https://svnweb.freebsd.org/changeset/base/298774

Log:
  MFC r297966:
  Add missing port_up checks.
  
  When downing a mlxen network adapter we need to check the port_up variable
  to ensure we don't continue to transmit data or restart timers which can
  reside in freed memory.
  
  Sponsored by: Mellanox Technologies

Modified:
  stable/9/sys/ofed/drivers/net/mlx4/en_tx.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/ofed/drivers/net/mlx4/en_tx.c
==============================================================================
--- stable/9/sys/ofed/drivers/net/mlx4/en_tx.c  Fri Apr 29 11:06:24 2016        
(r298773)
+++ stable/9/sys/ofed/drivers/net/mlx4/en_tx.c  Fri Apr 29 11:10:43 2016        
(r298774)
@@ -458,7 +458,7 @@ void mlx4_en_tx_irq(struct mlx4_cq *mcq)
        struct mlx4_en_priv *priv = netdev_priv(cq->dev);
        struct mlx4_en_tx_ring *ring = priv->tx_ring[cq->ring];
 
-       if (!spin_trylock(&ring->comp_lock))
+       if (priv->port_up == 0 || !spin_trylock(&ring->comp_lock))
                return;
        mlx4_en_process_tx_cq(cq->dev, cq);
        mod_timer(&cq->timer, jiffies + 1);
@@ -474,6 +474,8 @@ void mlx4_en_poll_tx_cq(unsigned long da
 
        INC_PERF_COUNTER(priv->pstats.tx_poll);
 
+       if (priv->port_up == 0)
+               return;
        if (!spin_trylock(&ring->comp_lock)) {
                mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT);
                return;
@@ -495,6 +497,9 @@ static inline void mlx4_en_xmit_poll(str
        struct mlx4_en_cq *cq = priv->tx_cq[tx_ind];
        struct mlx4_en_tx_ring *ring = priv->tx_ring[tx_ind];
 
+       if (priv->port_up == 0)
+               return;
+
        /* If we don't have a pending timer, set one up to catch our recent
           post in case the interface becomes idle */
        if (!timer_pending(&cq->timer))
@@ -1042,7 +1047,9 @@ mlx4_en_tx_que(void *context, int pendin
        priv = dev->if_softc;
        tx_ind = cq->ring;
        ring = priv->tx_ring[tx_ind];
-        if (dev->if_drv_flags & IFF_DRV_RUNNING) {
+
+       if (priv->port_up != 0 &&
+           (dev->if_drv_flags & IFF_DRV_RUNNING) != 0) {
                mlx4_en_xmit_poll(priv, tx_ind);
                spin_lock(&ring->tx_lock);
                 if (!drbr_empty(dev, ring->br))
@@ -1059,6 +1066,11 @@ mlx4_en_transmit(struct ifnet *dev, stru
        struct mlx4_en_cq *cq;
        int i, err = 0;
 
+       if (priv->port_up == 0) {
+               m_freem(m);
+               return (ENETDOWN);
+       }
+
        /* Compute which queue to use */
        if (m->m_flags & M_FLOWID) {
                i = (m->m_pkthdr.flowid % 128) % priv->tx_ring_num;
@@ -1092,6 +1104,9 @@ mlx4_en_qflush(struct ifnet *dev)
        struct mlx4_en_tx_ring *ring;
        struct mbuf *m;
 
+       if (priv->port_up == 0)
+               return;
+
        for (int i = 0; i < priv->tx_ring_num; i++) {
                ring = priv->tx_ring[i];
                spin_lock(&ring->tx_lock);
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to