Date: Fri, 29 Apr 2016 11:06:24 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r298773 - stable/10/sys/ofed/drivers/net/mlx4 Message-ID: <201604291106.u3TB6Ow2036929@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hselasky Date: Fri Apr 29 11:06:24 2016 New Revision: 298773 URL: https://svnweb.freebsd.org/changeset/base/298773 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/10/sys/ofed/drivers/net/mlx4/en_tx.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/ofed/drivers/net/mlx4/en_tx.c ============================================================================== --- stable/10/sys/ofed/drivers/net/mlx4/en_tx.c Fri Apr 29 11:01:06 2016 (r298772) +++ stable/10/sys/ofed/drivers/net/mlx4/en_tx.c Fri Apr 29 11:06:24 2016 (r298773) @@ -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)) @@ -1038,7 +1043,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)) @@ -1055,6 +1062,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_HASHTYPE_GET(m) != M_HASHTYPE_NONE) { i = (m->m_pkthdr.flowid % 128) % priv->tx_ring_num; @@ -1088,6 +1100,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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201604291106.u3TB6Ow2036929>