Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Apr 2016 14:01:28 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r297966 - head/sys/ofed/drivers/net/mlx4
Message-ID:  <201604141401.u3EE1SLj002213@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Thu Apr 14 14:01:28 2016
New Revision: 297966
URL: https://svnweb.freebsd.org/changeset/base/297966

Log:
  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
  MFC after:	1 week

Modified:
  head/sys/ofed/drivers/net/mlx4/en_tx.c

Modified: head/sys/ofed/drivers/net/mlx4/en_tx.c
==============================================================================
--- head/sys/ofed/drivers/net/mlx4/en_tx.c	Thu Apr 14 12:53:38 2016	(r297965)
+++ head/sys/ofed/drivers/net/mlx4/en_tx.c	Thu Apr 14 14:01:28 2016	(r297966)
@@ -457,7 +457,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);
@@ -473,6 +473,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;
@@ -494,6 +496,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))
@@ -1041,7 +1046,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))
@@ -1058,6 +1065,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;
@@ -1091,6 +1103,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?201604141401.u3EE1SLj002213>