Blame SOURCES/open-iscsi-2.0.876-54-iscsiuio-Add-inter-host-mutex-while-doing-xmit.patch

36b27b
From d469a2e15e8558cf8ba34db376b4b777177a016b Mon Sep 17 00:00:00 2001
36b27b
From: Chris Leech <cleech@redhat.com>
36b27b
Date: Fri, 22 Jun 2018 12:30:09 -0700
36b27b
Subject: [PATCH 1/1] iscsiuio: Add inter-host mutex while doing xmit
36b27b
36b27b
Bugzilla: ZZZ
36b27b
Upstream Status:
36b27b
Build Info: XXX
36b27b
Tested:
36b27b
36b27b
commit 9501dcaf5be474b4cb882a5e00f875f8c57e0e8e
36b27b
Author: Manish Rangankar <manish.rangankar@cavium.com>
36b27b
Date:   Wed Jun 20 02:33:36 2018 -0400
36b27b
36b27b
    iscsiuio: Add inter-host mutex while doing xmit
36b27b
36b27b
    This avoids the netlink buffer corruption when more than one host
36b27b
    try to xmit packet at the same time.
36b27b
36b27b
    Signed-off-by: Manish Rangankar <manish.rangankar@cavium.com>
36b27b
---
36b27b
 iscsiuio/src/unix/libs/cnic.c |  2 ++
36b27b
 iscsiuio/src/unix/libs/qedi.c | 38 +++++++++++++++++++++++++++++++++-----
36b27b
 iscsiuio/src/unix/nic.c       | 15 ++++++++++++---
36b27b
 iscsiuio/src/unix/nic_utils.c |  4 ++++
36b27b
 4 files changed, 51 insertions(+), 8 deletions(-)
36b27b
36b27b
diff --git a/iscsiuio/src/unix/libs/cnic.c b/iscsiuio/src/unix/libs/cnic.c
36b27b
index 32166edf243f..b953278e5eab 100644
36b27b
--- a/iscsiuio/src/unix/libs/cnic.c
36b27b
+++ b/iscsiuio/src/unix/libs/cnic.c
36b27b
@@ -106,6 +106,8 @@ static int cnic_arp_send(nic_t *nic, nic_interface_t *nic_iface, int fd,
36b27b
 	static const uint8_t multicast_mac[] = {
36b27b
 				0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
36b27b
 
36b27b
+	LOG_DEBUG(PFX "%s: host:%d - try getting xmit mutex cnic arp send",
36b27b
+		  nic->log_name, nic->host_no);
36b27b
 	rc = pthread_mutex_trylock(&nic->xmit_mutex);
36b27b
 	if (rc != 0) {
36b27b
 		LOG_DEBUG(PFX "%s: could not get xmit_mutex", nic->log_name);
36b27b
diff --git a/iscsiuio/src/unix/libs/qedi.c b/iscsiuio/src/unix/libs/qedi.c
36b27b
index 5bb0682c8bed..32cab48fed17 100644
36b27b
--- a/iscsiuio/src/unix/libs/qedi.c
36b27b
+++ b/iscsiuio/src/unix/libs/qedi.c
36b27b
@@ -74,6 +74,8 @@
36b27b
 
36b27b
 extern int nl_sock;
36b27b
 
36b27b
+static pthread_mutex_t host_mutex = PTHREAD_MUTEX_INITIALIZER;
36b27b
+
36b27b
 /*  Foward struct declarations */
36b27b
 struct nic_ops qedi_op;
36b27b
 
36b27b
@@ -812,15 +814,26 @@ static void qedi_prepare_xmit_packet(nic_t *nic,
36b27b
 	struct uip_vlan_eth_hdr *eth_vlan = (struct uip_vlan_eth_hdr *)pkt->buf;
36b27b
 	struct uip_eth_hdr *eth = (struct uip_eth_hdr *)bp->tx_pkt;
36b27b
 
36b27b
+	LOG_DEBUG(PFX "%s: pkt->buf_size=%d tpid=0x%x", nic->log_name,
36b27b
+		  pkt->buf_size, eth_vlan->tpid);
36b27b
+	
36b27b
 	if (eth_vlan->tpid == htons(UIP_ETHTYPE_8021Q)) {
36b27b
 		memcpy(bp->tx_pkt, pkt->buf, sizeof(struct uip_eth_hdr));
36b27b
 		eth->type = eth_vlan->type;
36b27b
 		pkt->buf_size -= (sizeof(struct uip_vlan_eth_hdr) -
36b27b
 				  sizeof(struct uip_eth_hdr));
36b27b
+
36b27b
+	LOG_DEBUG(PFX "%s: pkt->buf_size=%d type=0x%x", nic->log_name,
36b27b
+		  pkt->buf_size, eth->type);
36b27b
+	LOG_DEBUG(PFX "%s: pkt->buf_size - eth_hdr_size = %d", nic->log_name,
36b27b
+		  pkt->buf_size - sizeof(struct uip_eth_hdr));
36b27b
+
36b27b
 		memcpy(bp->tx_pkt + sizeof(struct uip_eth_hdr),
36b27b
 		       pkt->buf + sizeof(struct uip_vlan_eth_hdr),
36b27b
 		       pkt->buf_size - sizeof(struct uip_eth_hdr));
36b27b
 	} else {
36b27b
+		LOG_DEBUG(PFX "%s: NO VLAN pkt->buf_size=%d", nic->log_name,
36b27b
+			  pkt->buf_size);
36b27b
 		memcpy(bp->tx_pkt, pkt->buf, pkt->buf_size);
36b27b
 	}
36b27b
 
36b27b
@@ -876,11 +889,18 @@ void qedi_start_xmit(nic_t *nic, size_t len, u16_t vlan_id)
36b27b
 	path_data->handle = QEDI_PATH_HANDLE;
36b27b
 	path_data->vlan_id = vlan_id;
36b27b
 	uctrl->host_tx_pkt_len = len;
36b27b
+	LOG_DEBUG(PFX "%s: host_no:%d vlan_id=%d, tx_pkt_len=%d",
36b27b
+		  nic->log_name, ev->u.set_path.host_no, path_data->vlan_id, uctrl->host_tx_pkt_len);
36b27b
 
36b27b
+	LOG_DEBUG(PFX "%s: ACQUIRE HOST MUTEX", nic->log_name);
36b27b
+	pthread_mutex_lock(&host_mutex);
36b27b
 	rc = __kipc_call(nl_sock, ev, buflen);
36b27b
 	if (rc > 0) {
36b27b
 		bp->tx_prod++;
36b27b
 		uctrl->host_tx_prod++;
36b27b
+		LOG_DEBUG(PFX "%s: bp->tx_prod: %d, uctrl->host_tx_prod=%d",
36b27b
+			  nic->log_name, bp->tx_prod, uctrl->host_tx_prod);
36b27b
+
36b27b
 		msync(uctrl, sizeof(struct qedi_uio_ctrl), MS_SYNC);
36b27b
 		LOG_PACKET(PFX "%s: sent %d bytes using bp->tx_prod: %d",
36b27b
 			   nic->log_name, len, bp->tx_prod);
36b27b
@@ -888,6 +908,8 @@ void qedi_start_xmit(nic_t *nic, size_t len, u16_t vlan_id)
36b27b
 		LOG_ERR(PFX "Pkt transmission failed: %d", rc);
36b27b
 	}
36b27b
 
36b27b
+	LOG_DEBUG(PFX "%s: RELEASE HOST MUTEX", nic->log_name);
36b27b
+	pthread_mutex_unlock(&host_mutex);
36b27b
 	free(ubuf);
36b27b
 }
36b27b
 
36b27b
@@ -923,14 +945,18 @@ int qedi_write(nic_t *nic, nic_interface_t *nic_iface, packet_t *pkt)
36b27b
 		struct timespec sleep_req = {.tv_sec = 0, .tv_nsec = 5000000 },
36b27b
 		    sleep_rem;
36b27b
 
36b27b
+		LOG_DEBUG(PFX "%s: host:%d - calling clear_tx_intr from qedi_write",
36b27b
+			  nic->log_name, nic->host_no);
36b27b
 		if (qedi_clear_tx_intr(nic) == 0)
36b27b
 			break;
36b27b
 
36b27b
 		nanosleep(&sleep_req, &sleep_rem);
36b27b
 	}
36b27b
 
36b27b
+	LOG_DEBUG(PFX "%s: host:%d - try getting xmit mutex",
36b27b
+		   nic->log_name, nic->host_no);
36b27b
 	if (pthread_mutex_trylock(&nic->xmit_mutex) != 0) {
36b27b
-		LOG_PACKET(PFX "%s: Dropped previous transmitted packet",
36b27b
+		LOG_DEBUG(PFX "%s: Dropped previous transmitted packet",
36b27b
 			   nic->log_name);
36b27b
 		return -EINVAL;
36b27b
 	}
36b27b
@@ -944,7 +970,7 @@ int qedi_write(nic_t *nic, nic_interface_t *nic_iface, packet_t *pkt)
36b27b
 	nic->stats.tx.packets++;
36b27b
 	nic->stats.tx.bytes += uip->uip_len;
36b27b
 
36b27b
-	LOG_PACKET(PFX "%s: transmitted %d bytes dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bd_prod:%d",
36b27b
+	LOG_DEBUG(PFX "%s: transmitted %d bytes dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bd_prod:%d",
36b27b
 		   nic->log_name, pkt->buf_size,
36b27b
 		   bp->tx_cons, bp->tx_prod, bp->tx_bd_prod);
36b27b
 
36b27b
@@ -1071,7 +1097,7 @@ static int qedi_clear_tx_intr(nic_t *nic)
36b27b
 		return -EINVAL;
36b27b
 	}
36b27b
 
36b27b
-	LOG_PACKET(PFX "%s: clearing tx interrupt [%d %d]",
36b27b
+	LOG_DEBUG(PFX "%s: clearing tx interrupt [%d %d]",
36b27b
 		   nic->log_name, bp->tx_cons, hw_cons);
36b27b
 	bp->tx_cons = hw_cons;
36b27b
 
36b27b
@@ -1083,7 +1109,7 @@ static int qedi_clear_tx_intr(nic_t *nic)
36b27b
 		packet_t *pkt;
36b27b
 		int i;
36b27b
 
36b27b
-		LOG_PACKET(PFX "%s: sending queued tx packet", nic->log_name);
36b27b
+		LOG_DEBUG(PFX "%s: sending queued tx packet", nic->log_name);
36b27b
 		pkt = nic_dequeue_tx_packet(nic);
36b27b
 
36b27b
 		/* Got a TX packet buffer of the TX queue and put it onto
36b27b
@@ -1096,7 +1122,7 @@ static int qedi_clear_tx_intr(nic_t *nic)
36b27b
 					(pkt->nic_iface->vlan_priority << 12) |
36b27b
 					pkt->nic_iface->vlan_id);
36b27b
 
36b27b
-			LOG_PACKET(PFX "%s: transmitted queued packet %d bytes, dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bd_prod:%d",
36b27b
+			LOG_DEBUG(PFX "%s: transmitted queued packet %d bytes, dev->tx_cons: %d, dev->tx_prod: %d, dev->tx_bd_prod:%d",
36b27b
 				   nic->log_name, pkt->buf_size,
36b27b
 				   bp->tx_cons, bp->tx_prod, bp->tx_bd_prod);
36b27b
 
36b27b
@@ -1124,6 +1150,8 @@ static int qedi_clear_tx_intr(nic_t *nic)
36b27b
 		}
36b27b
 	}
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
diff --git a/iscsiuio/src/unix/nic.c b/iscsiuio/src/unix/nic.c
36b27b
index a5f714a91923..dfc2ad0a7a7b 100644
36b27b
--- a/iscsiuio/src/unix/nic.c
36b27b
+++ b/iscsiuio/src/unix/nic.c
36b27b
@@ -799,6 +799,8 @@ int nic_process_intr(nic_t *nic, int discard_check)
36b27b
 
36b27b
 		nic->intr_count = count;
36b27b
 
36b27b
+		LOG_DEBUG(PFX "%s: host:%d - calling clear_tx_intr from process_intr",
36b27b
+			   nic->log_name, nic->host_no);
36b27b
 		(*nic->ops->clear_tx_intr) (nic);
36b27b
 		ret = 1;
36b27b
 	}
36b27b
@@ -1036,9 +1038,11 @@ int process_packets(nic_t *nic,
36b27b
 		case UIP_ETHTYPE_IPv4:
36b27b
 		case UIP_ETHTYPE_ARP:
36b27b
 			af_type = AF_INET;
36b27b
+			LOG_DEBUG(PFX "%s: ARP or IPv4 vlan:0x%x ethertype:0x%x",
36b27b
+				   nic->log_name, vlan_id, type);
36b27b
 			break;
36b27b
 		default:
36b27b
-			LOG_PACKET(PFX "%s: Ignoring vlan:0x%x ethertype:0x%x",
36b27b
+			LOG_DEBUG(PFX "%s: Ignoring vlan:0x%x ethertype:0x%x",
36b27b
 				   nic->log_name, vlan_id, type);
36b27b
 			goto done;
36b27b
 		}
36b27b
@@ -1064,7 +1068,7 @@ int process_packets(nic_t *nic,
36b27b
 		if (nic_iface == NULL) {
36b27b
 			/* Matching nic_iface not found */
36b27b
 			pthread_mutex_unlock(&nic->nic_mutex);
36b27b
-			LOG_PACKET(PFX "%s: Couldn't find interface for "
36b27b
+			LOG_DEBUG(PFX "%s: Couldn't find interface for "
36b27b
 				   "VLAN: %d af_type %d",
36b27b
 				nic->log_name, vlan_id, af_type);
36b27b
 			rc = EINVAL;  /* Return the +error code */
36b27b
@@ -1118,6 +1122,8 @@ nic_iface_present:
36b27b
 				prepare_ipv4_packet(nic, nic_iface,
36b27b
 						    ustack, pkt);
36b27b
 
36b27b
+				LOG_DEBUG(PFX "%s: write called after arp_ipin, uip_len=%d",
36b27b
+					  nic->log_name, ustack->uip_len);
36b27b
 				(*nic->ops->write) (nic, nic_iface, pkt);
36b27b
 			}
36b27b
 
36b27b
@@ -1129,8 +1135,11 @@ nic_iface_present:
36b27b
 			 * in data that should be sent out on the
36b27b
 			 * network, the global variable uip_len
36b27b
 			 * is set to a value > 0. */
36b27b
-			if (pkt->buf_size > 0)
36b27b
+			if (pkt->buf_size > 0) {
36b27b
+				LOG_DEBUG(PFX "%s: write called after arp_arpin, bufsize=%d",
36b27b
+					   nic->log_name, pkt->buf_size);
36b27b
 				(*nic->ops->write) (nic, nic_iface, pkt);
36b27b
+			}
36b27b
 			break;
36b27b
 		}
36b27b
 		ustack->uip_len = 0;
36b27b
diff --git a/iscsiuio/src/unix/nic_utils.c b/iscsiuio/src/unix/nic_utils.c
36b27b
index 6e580f862eea..988905bca2a9 100644
36b27b
--- a/iscsiuio/src/unix/nic_utils.c
36b27b
+++ b/iscsiuio/src/unix/nic_utils.c
36b27b
@@ -1435,6 +1435,10 @@ nic_interface_t *nic_find_nic_iface(nic_t *nic,
36b27b
 	nic_interface_t *current_vlan = NULL;
36b27b
 
36b27b
 	while (current != NULL) {
36b27b
+		LOG_DEBUG(PFX "%s: incoming protocol: %d, vlan_id:%d iface_num: %d, request_type: %d",
36b27b
+			  nic->log_name, protocol, vlan_id, iface_num,  request_type);
36b27b
+		LOG_DEBUG(PFX "%s: host:%d iface_num: 0x%x VLAN: %d protocol: %d",
36b27b
+			  nic->log_name, nic->host_no, current->iface_num, current->vlan_id, current->protocol);
36b27b
 		if (current->protocol != protocol)
36b27b
 			goto next;
36b27b
 
36b27b
-- 
36b27b
2.14.4
36b27b