Blame SOURCES/open-iscsi-2.0.874-31-iscsiuio-serialize-xmit_mutex-lock-to-prevent-iscsiuio-seg-fault.patch

36b27b
From: Chris Leech <cleech@redhat.com>
36b27b
Subject: iscsiuio: serialize xmit_mutex lock to prevent iscsiuio seg fault
36b27b
36b27b
Bugzilla: ZZZ
36b27b
Upstream Status:
36b27b
Build Info: XXX
36b27b
Tested:
36b27b
36b27b
commit a1be9c4ec348f87923f63ce2dbc23893a3b9e45c
36b27b
Author: Nilesh Javali <nilesh.javali@cavium.com>
36b27b
Date:   Thu May 18 23:04:20 2017 +0530
36b27b
36b27b
    iscsiuio: serialize xmit_mutex lock to prevent iscsiuio seg fault
36b27b
    
36b27b
    Signed-off-by: Nilesh Javali <nilesh.javali@cavium.com>
36b27b
---
36b27b
 iscsiuio/src/unix/libs/bnx2x.c | 24 +++++++++++-------------
36b27b
 iscsiuio/src/unix/libs/cnic.c  |  9 +++------
36b27b
 iscsiuio/src/unix/libs/qedi.c  | 19 +++++++++++--------
36b27b
 3 files changed, 25 insertions(+), 27 deletions(-)
36b27b
36b27b
diff --git a/iscsiuio/src/unix/libs/bnx2x.c b/iscsiuio/src/unix/libs/bnx2x.c
36b27b
index 19cbcecaacca..1e8f532edcdf 100644
36b27b
--- a/iscsiuio/src/unix/libs/bnx2x.c
36b27b
+++ b/iscsiuio/src/unix/libs/bnx2x.c
36b27b
@@ -1316,7 +1316,6 @@ void bnx2x_start_xmit(nic_t *nic, size_t len, u16_t vlan_id)
36b27b
 	if ((rx_bd->addr_hi == 0) && (rx_bd->addr_lo == 0)) {
36b27b
 		LOG_PACKET(PFX "%s: trying to transmit when device is closed",
36b27b
 			   nic->log_name);
36b27b
-		pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
 		return;
36b27b
 	}
36b27b
 
36b27b
@@ -1343,12 +1342,9 @@ void bnx2x_start_xmit(nic_t *nic, size_t len, u16_t vlan_id)
36b27b
 			       (bp->tx_bd_prod << 16));
36b27b
 		bnx2x_flush_doorbell(bp, bp->tx_doorbell);
36b27b
 	} else {
36b27b
-		/* If the doorbell is not rung, the packet will not
36b27b
-		   get sent.  Hence, the xmit_mutex lock will not
36b27b
-		   get freed.
36b27b
-		 */
36b27b
-		pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
+		LOG_ERR(PFX "Pkt transmission failed.");
36b27b
 	}
36b27b
+
36b27b
 	LOG_PACKET(PFX "%s: sent %d bytes using bp->tx_prod: %d",
36b27b
 		   nic->log_name, len, bp->tx_prod);
36b27b
 }
36b27b
@@ -1412,6 +1408,8 @@ int bnx2x_write(nic_t *nic, nic_interface_t *nic_iface, packet_t *pkt)
36b27b
 		   nic->log_name, pkt->buf_size,
36b27b
 		   bp->tx_cons, bp->tx_prod, bp->tx_bd_prod);
36b27b
 
36b27b
+	pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
+
36b27b
 	return 0;
36b27b
 }
36b27b
 
36b27b
@@ -1560,17 +1558,16 @@ static int bnx2x_clear_tx_intr(nic_t *nic)
36b27b
 	hw_cons = bp->get_tx_cons(bp);
36b27b
 
36b27b
 	if (bp->tx_cons == hw_cons) {
36b27b
-		if (bp->tx_cons == bp->tx_prod) {
36b27b
-			/* Make sure the xmit_mutex lock is unlock */
36b27b
-			if (pthread_mutex_trylock(&nic->xmit_mutex))
36b27b
-				LOG_ERR(PFX "bnx2x tx lock with prod == cons");
36b27b
-
36b27b
-			pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
+		if (bp->tx_cons == bp->tx_prod)
36b27b
 			return 0;
36b27b
-		}
36b27b
 		return -EAGAIN;
36b27b
 	}
36b27b
 
36b27b
+	if (pthread_mutex_trylock(&nic->xmit_mutex)) {
36b27b
+		LOG_ERR(PFX "%s: unable to get xmit_mutex.", nic->log_name);
36b27b
+		return -EINVAL;
36b27b
+	}
36b27b
+
36b27b
 	LOG_PACKET(PFX "%s: clearing tx interrupt [%d %d]",
36b27b
 		   nic->log_name, bp->tx_cons, hw_cons);
36b27b
 	bp->tx_cons = hw_cons;
36b27b
@@ -1600,6 +1597,7 @@ static int bnx2x_clear_tx_intr(nic_t *nic)
36b27b
 				   nic->log_name, pkt->buf_size,
36b27b
 				   bp->tx_cons, bp->tx_prod, bp->tx_bd_prod);
36b27b
 
36b27b
+			pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
 			return 0;
36b27b
 		}
36b27b
 
36b27b
diff --git a/iscsiuio/src/unix/libs/cnic.c b/iscsiuio/src/unix/libs/cnic.c
36b27b
index 5d60f898ad57..a009f25f0814 100644
36b27b
--- a/iscsiuio/src/unix/libs/cnic.c
36b27b
+++ b/iscsiuio/src/unix/libs/cnic.c
36b27b
@@ -141,6 +141,7 @@ static int cnic_arp_send(nic_t *nic, nic_interface_t *nic_iface, int fd,
36b27b
 	memcpy(&addr.s_addr, &dst_ip, sizeof(addr.s_addr));
36b27b
 	LOG_DEBUG(PFX "%s: Sent cnic arp request for IP: %s",
36b27b
 		  nic->log_name, addr_str);
36b27b
+	pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
 
36b27b
 	return 0;
36b27b
 }
36b27b
@@ -204,6 +205,8 @@ static int cnic_neigh_soliciation_send(nic_t *nic,
36b27b
 	LOG_DEBUG(PFX "%s: Sent cnic ICMPv6 neighbor request %s",
36b27b
 		  nic->log_name, addr_str);
36b27b
 
36b27b
+	pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
+
36b27b
 	return 0;
36b27b
 }
36b27b
 
36b27b
@@ -433,9 +436,6 @@ done:
36b27b
 		rc = -EIO;
36b27b
 	}
36b27b
 
36b27b
-	if (status != 0 || rc != 0)
36b27b
-		pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
-
36b27b
 	if (ev) {
36b27b
 		cnic_nl_neigh_rsp(nic, fd, ev, path, mac_addr,
36b27b
 				  nic_iface, status, AF_INET);
36b27b
@@ -632,9 +632,6 @@ done:
36b27b
 		rc = -EIO;
36b27b
 	}
36b27b
 
36b27b
-	if (status != 0 || rc != 0)
36b27b
-		pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
-
36b27b
 	if (ev) {
36b27b
 		cnic_nl_neigh_rsp(nic, fd, ev, path, mac_addr,
36b27b
 				  nic_iface, status, AF_INET6);
36b27b
diff --git a/iscsiuio/src/unix/libs/qedi.c b/iscsiuio/src/unix/libs/qedi.c
36b27b
index c2096e59dad1..c6ff6e7724a3 100644
36b27b
--- a/iscsiuio/src/unix/libs/qedi.c
36b27b
+++ b/iscsiuio/src/unix/libs/qedi.c
36b27b
@@ -887,7 +887,6 @@ void qedi_start_xmit(nic_t *nic, size_t len, u16_t vlan_id)
36b27b
 			   nic->log_name, len, bp->tx_prod);
36b27b
 	} else {
36b27b
 		LOG_ERR(PFX "Pkt transmission failed: %d", rc);
36b27b
-		pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
 	}
36b27b
 
36b27b
 	free(ubuf);
36b27b
@@ -950,6 +949,10 @@ int qedi_write(nic_t *nic, nic_interface_t *nic_iface, packet_t *pkt)
36b27b
 		   nic->log_name, pkt->buf_size,
36b27b
 		   bp->tx_cons, bp->tx_prod, bp->tx_bd_prod);
36b27b
 
36b27b
+	LOG_DEBUG(PFX "%s: host:%d - releasing xmit mutex",
36b27b
+		  nic->log_name, nic->host_no);
36b27b
+	pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
+
36b27b
 	return 0;
36b27b
 }
36b27b
 
36b27b
@@ -1059,17 +1062,16 @@ static int qedi_clear_tx_intr(nic_t *nic)
36b27b
 	hw_cons = uctrl->hw_tx_cons;
36b27b
 
36b27b
 	if (bp->tx_cons == hw_cons) {
36b27b
-		if (bp->tx_cons == bp->tx_prod) {
36b27b
-			/* Make sure the xmit_mutex lock is unlock */
36b27b
-			if (pthread_mutex_trylock(&nic->xmit_mutex))
36b27b
-				LOG_ERR(PFX "qedi tx lock with prod == cons");
36b27b
-
36b27b
-			pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
+		if (bp->tx_cons == bp->tx_prod)
36b27b
 			return 0;
36b27b
-		}
36b27b
 		return -EAGAIN;
36b27b
 	}
36b27b
 
36b27b
+	if (pthread_mutex_trylock(&nic->xmit_mutex)) {
36b27b
+		LOG_ERR(PFX "%s: unable to get xmit_mutex.", nic->log_name);
36b27b
+		return -EINVAL;
36b27b
+	}
36b27b
+
36b27b
 	LOG_PACKET(PFX "%s: clearing tx interrupt [%d %d]",
36b27b
 		   nic->log_name, bp->tx_cons, hw_cons);
36b27b
 	bp->tx_cons = hw_cons;
36b27b
@@ -1099,6 +1101,7 @@ static int qedi_clear_tx_intr(nic_t *nic)
36b27b
 				   nic->log_name, pkt->buf_size,
36b27b
 				   bp->tx_cons, bp->tx_prod, bp->tx_bd_prod);
36b27b
 
36b27b
+			pthread_mutex_unlock(&nic->xmit_mutex);
36b27b
 			return 0;
36b27b
 		}
36b27b