changeset 10577:538e1d73a729

6878578 while processing a fatal error recursive mutex panic encountered in nxge 6877282 while plumbing a hybrid vnet in the service domain panic occurs in nxge 6873178 assertion failed: nmp, file: ../../common/io/nxge/nxge_txdma.c, line: 688 6879284 Foxxy FEM hot plug issue with C10 NEM 6873102 guest domain panics when running network load tests with hybrid I/O 6856725 nxge may unmap memory while dblks are still referencing it
author Michael Speer <Michael.Speer@Sun.COM>
date Thu, 17 Sep 2009 17:09:42 -0700
parents 6b4d0968a170
children cfcdaad2f225
files usr/src/uts/common/io/nxge/nxge_espc.c usr/src/uts/common/io/nxge/nxge_hio.c usr/src/uts/common/io/nxge/nxge_hio_guest.c usr/src/uts/common/io/nxge/nxge_mac.c usr/src/uts/common/io/nxge/nxge_main.c usr/src/uts/common/io/nxge/nxge_rxdma.c usr/src/uts/common/io/nxge/nxge_txdma.c usr/src/uts/common/sys/nxge/nxge_hio.h
diffstat 8 files changed, 85 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/nxge/nxge_espc.c	Thu Sep 17 17:45:50 2009 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_espc.c	Thu Sep 17 17:09:42 2009 -0700
@@ -254,6 +254,8 @@
 	} else if (strncmp(nxgep->vpd_info.bd_model,
 	    NXGE_RFEM_BM_STR, strlen(NXGE_RFEM_BM_STR)) == 0) {
 		nxgep->hot_swappable_phy = B_TRUE;
+		nxgep->platform_type = P_NEPTUNE_GENERIC;
+		nxgep->niu_type = NEPTUNE_2_10GF;
 	}
 
 	/* If Alonso platform, replace "mif" for the last 2 ports phy-type */
--- a/usr/src/uts/common/io/nxge/nxge_hio.c	Thu Sep 17 17:45:50 2009 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_hio.c	Thu Sep 17 17:09:42 2009 -0700
@@ -132,9 +132,10 @@
 	int i;
 
 	nhd = (nxge_hio_data_t *)nxge->nxge_hw_p->hio;
-	if (nhd == 0) {
+	if (nhd == NULL) {
 		nhd = KMEM_ZALLOC(sizeof (*nhd), KM_SLEEP);
 		MUTEX_INIT(&nhd->lock, NULL, MUTEX_DRIVER, NULL);
+		nhd->type = NXGE_HIO_TYPE_SERVICE;
 		nxge->nxge_hw_p->hio = (uintptr_t)nhd;
 	}
 
@@ -966,8 +967,7 @@
  *	Any domain
  */
 int
-nxge_hio_init(
-	nxge_t *nxge)
+nxge_hio_init(nxge_t *nxge)
 {
 	nxge_hio_data_t *nhd;
 	int i, region;
@@ -976,6 +976,10 @@
 	if (nhd == 0) {
 		nhd = KMEM_ZALLOC(sizeof (*nhd), KM_SLEEP);
 		MUTEX_INIT(&nhd->lock, NULL, MUTEX_DRIVER, NULL);
+		if (isLDOMguest(nxge))
+			nhd->type = NXGE_HIO_TYPE_GUEST;
+		else
+			nhd->type = NXGE_HIO_TYPE_SERVICE;
 		nxge->nxge_hw_p->hio = (uintptr_t)nhd;
 	}
 
@@ -1917,15 +1921,12 @@
 }
 
 int
-nxge_hio_addres(
-	nxge_hio_vr_t *vr,
-	mac_ring_type_t type,
-	uint64_t *map)
+nxge_hio_addres(nxge_hio_vr_t *vr, mac_ring_type_t type, uint64_t *map)
 {
 	nxge_t		*nxge = (nxge_t *)vr->nxge;
 	nxge_grp_t	*group;
 	int		groupid;
-	int		i;
+	int		i, rv = 0;
 	int		max_dcs;
 
 	NXGE_DEBUG_MSG((nxge, HIO_CTL, "==> nxge_hio_addres"));
@@ -1958,8 +1959,6 @@
 
 	for (i = 0; i < max_dcs; i++) {
 		if (group->map & (1 << i)) {
-			int rv;
-
 			if ((rv = nxge_hio_dc_share(nxge, vr, type, i)) < 0) {
 				if (*map == 0) /* Couldn't get even one DC. */
 					return (-rv);
@@ -1970,8 +1969,13 @@
 		}
 	}
 
+	if ((*map == 0) || (rv != 0)) {
+		NXGE_DEBUG_MSG((nxge, HIO_CTL,
+		    "<== nxge_hio_addres: rv(%x)", rv));
+		return (EIO);
+	}
+
 	NXGE_DEBUG_MSG((nxge, HIO_CTL, "<== nxge_hio_addres"));
-
 	return (0);
 }
 
--- a/usr/src/uts/common/io/nxge/nxge_hio_guest.c	Thu Sep 17 17:45:50 2009 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_hio_guest.c	Thu Sep 17 17:09:42 2009 -0700
@@ -192,13 +192,21 @@
 
 	NXGE_DEBUG_MSG((nxge, HIO_CTL, "==> nxge_hio_vr_add"));
 
+	if (nhd->type == NXGE_HIO_TYPE_SERVICE) {
+		/*
+		 * Can't add VR to the service domain from which we came.
+		 */
+		ASSERT(nhd->type == NXGE_HIO_TYPE_GUEST);
+		return (DDI_FAILURE);
+	}
+
 	/*
 	 * Get our HV cookie.
 	 */
 	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, nxge->dip,
 	    0, "reg", &reg_val, &reg_len) != DDI_PROP_SUCCESS) {
 		NXGE_DEBUG_MSG((nxge, VPD_CTL, "`reg' property not found"));
-		return (NXGE_ERROR);
+		return (DDI_FAILURE);
 	}
 
 	cookie = (uint32_t)(reg_val[0]);
@@ -209,7 +217,7 @@
 	if (hv_rv != 0) {
 		NXGE_ERROR_MSG((nxge, NXGE_ERR_CTL,
 		    "vr->getinfo() failed"));
-		return (NXGE_ERROR);
+		return (DDI_FAILURE);
 	}
 
 	/*
@@ -239,7 +247,7 @@
 		NXGE_ERROR_MSG((nxge, NXGE_ERR_CTL,
 		    "nxge_hio_vr_add(%d): cookie(0x%x)\n",
 		    nxge->instance, cookie));
-		return (NXGE_ERROR);
+		return (DDI_FAILURE);
 	}
 
 	vr = &nhd->vr[vr_index];
@@ -265,7 +273,7 @@
 	if (nxge_hio_intr_init(nxge) != NXGE_OK) {
 		NXGE_ERROR_MSG((nxge, NXGE_ERR_CTL,
 		    "nxge_hio_intr_init() failed"));
-		return (NXGE_ERROR);
+		return (DDI_FAILURE);
 	}
 
 	/*
@@ -282,7 +290,7 @@
 		if (hv_rv != 0) {
 			NXGE_ERROR_MSG((nxge, NXGE_ERR_CTL,
 			    "tx->get_map() failed"));
-			return (NXGE_ERROR);
+			return (DDI_FAILURE);
 		}
 		res_map_parse(nxge, NXGE_TRANSMIT_GROUP, tx_map);
 
@@ -297,7 +305,7 @@
 				if (dc == 0) {
 					NXGE_ERROR_MSG((nxge, NXGE_ERR_CTL,
 					    "DC add failed"));
-					return (NXGE_ERROR);
+					return (DDI_FAILURE);
 				}
 				dc->channel = (nxge_channel_t)i;
 			}
@@ -315,7 +323,7 @@
 		if (hv_rv != 0) {
 			NXGE_ERROR_MSG((nxge, NXGE_ERR_CTL,
 			    "rx->get_map() failed"));
-			return (NXGE_ERROR);
+			return (DDI_FAILURE);
 		}
 		res_map_parse(nxge, NXGE_RECEIVE_GROUP, rx_map);
 
@@ -330,7 +338,7 @@
 				if (dc == 0) {
 					NXGE_ERROR_MSG((nxge, NXGE_ERR_CTL,
 					    "DC add failed"));
-					return (NXGE_ERROR);
+					return (DDI_FAILURE);
 				}
 				dc->channel = (nxge_channel_t)i;
 			}
@@ -341,14 +349,14 @@
 	if (status != NXGE_OK) {
 		cmn_err(CE_WARN, "nxge(%d): nxge_mac_register failed\n",
 		    nxge->instance);
-		return (status);
+		return (DDI_FAILURE);
 	}
 
 	nxge->hio_vr = vr;	/* For faster lookups. */
 
 	NXGE_DEBUG_MSG((nxge, HIO_CTL, "<== nxge_hio_vr_add"));
 
-	return (NXGE_OK);
+	return (DDI_SUCCESS);
 }
 
 /*
--- a/usr/src/uts/common/io/nxge/nxge_mac.c	Thu Sep 17 17:45:50 2009 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_mac.c	Thu Sep 17 17:09:42 2009 -0700
@@ -312,6 +312,10 @@
 	 */
 	if (nxgep->mac.portmode == PORT_HSP_MODE) {
 		nxgep->hot_swappable_phy = B_TRUE;
+		if (portn > 1) {
+			return (NXGE_ERROR);
+		}
+
 		/*
 		 * If this is the 2nd NIU port, then check 2 addresses
 		 * to take care of the Goa NEM card. Port 1 can have addr 17
--- a/usr/src/uts/common/io/nxge/nxge_main.c	Thu Sep 17 17:45:50 2009 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_main.c	Thu Sep 17 17:09:42 2009 -0700
@@ -128,10 +128,12 @@
 nxge_rxbuf_threshold_t nxge_rx_threshold_lo = NXGE_RX_COPY_3;
 
 /* Use kmem_alloc() to allocate data buffers. */
-#if defined(_BIG_ENDIAN)
+#if defined(__sparc)
 uint32_t	nxge_use_kmem_alloc = 1;
+#elif defined(__i386)
+uint32_t	nxge_use_kmem_alloc = 0;
 #else
-uint32_t	nxge_use_kmem_alloc = 0;
+uint32_t	nxge_use_kmem_alloc = 1;
 #endif
 
 rtrace_t npi_rtracebuf;
@@ -822,11 +824,12 @@
 	if (isLDOMguest(nxgep)) {
 		/* Find our VR & channel sets. */
 		status = nxge_hio_vr_add(nxgep);
-		if (status != NXGE_OK) {
-			NXGE_DEBUG_MSG((nxgep, DDI_CTL,
+		if (status != DDI_SUCCESS) {
+			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
 			    "nxge_hio_vr_add failed"));
 			(void) hsvc_unregister(&nxgep->niu_hsvc);
 			nxgep->niu_hsvc_available = B_FALSE;
+			goto nxge_attach_fail;
 		}
 		goto nxge_attach_exit;
 	}
@@ -6530,6 +6533,8 @@
 	p_nxge_hw_list_t	hw_p;
 	dev_info_t 		*p_dip;
 
+	ASSERT(nxgep != NULL);
+
 	NXGE_DEBUG_MSG((nxgep, MOD_CTL, "==> nxge_init_common_device"));
 
 	p_dip = nxgep->p_dip;
@@ -6644,6 +6649,8 @@
 	p_nxge_hw_pt_cfg_t	p_cfgp;
 	dev_info_t 		*p_dip;
 
+	ASSERT(nxgep != NULL);
+
 	NXGE_DEBUG_MSG((nxgep, MOD_CTL, "==> nxge_uninit_common_device"));
 	if (nxgep->nxge_hw_p == NULL) {
 		NXGE_DEBUG_MSG((nxgep, MOD_CTL,
--- a/usr/src/uts/common/io/nxge/nxge_rxdma.c	Thu Sep 17 17:45:50 2009 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_rxdma.c	Thu Sep 17 17:09:42 2009 -0700
@@ -18,6 +18,7 @@
  *
  * CDDL HEADER END
  */
+
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
@@ -4268,12 +4269,13 @@
 
 	if (isLDOMguest(nxgep)) {
 		/* Add interrupt handler for this channel. */
-		if (nxge_hio_intr_add(nxgep, VP_BOUND_RX, channel)
-		    != NXGE_OK) {
+		status = nxge_hio_intr_add(nxgep, VP_BOUND_RX, channel);
+		if (status != NXGE_OK) {
 			NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
 			    " nxge_rxdma_start_channel: "
 			    " nxge_hio_intr_add failed (0x%08x channel %d)",
-		    status, channel));
+			    status, channel));
+			return (status);
 		}
 	}
 
@@ -4556,7 +4558,6 @@
 	rbrp = (p_rx_rbr_ring_t)nxgep->rx_rbr_rings->rbr_rings[channel];
 	rcrp = (p_rx_rcr_ring_t)nxgep->rx_rcr_rings->rcr_rings[channel];
 
-	MUTEX_ENTER(&rcrp->lock);
 	MUTEX_ENTER(&rbrp->lock);
 	MUTEX_ENTER(&rbrp->post_lock);
 
@@ -4651,20 +4652,17 @@
 
 	MUTEX_EXIT(&rbrp->post_lock);
 	MUTEX_EXIT(&rbrp->lock);
-	MUTEX_EXIT(&rcrp->lock);
 
 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
 	    "Recovery Successful, RxDMAChannel#%d Restored",
 	    channel));
 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_rxdma_fatal_err_recover"));
-
 	return (NXGE_OK);
+
 fail:
 	MUTEX_EXIT(&rbrp->post_lock);
 	MUTEX_EXIT(&rbrp->lock);
-	MUTEX_EXIT(&rcrp->lock);
 	NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Recovery failed"));
-
 	return (NXGE_ERROR | rs);
 }
 
@@ -4673,6 +4671,7 @@
 {
 	nxge_grp_set_t *set = &nxgep->rx_set;
 	nxge_status_t status = NXGE_OK;
+	p_rx_rcr_ring_t rcrp;
 	int rdc;
 
 	NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_rx_port_fatal_err_recover"));
@@ -4689,10 +4688,16 @@
 
 	for (rdc = 0; rdc < NXGE_MAX_RDCS; rdc++) {
 		if ((1 << rdc) & set->owned.map) {
-			if (nxge_rxdma_fatal_err_recover(nxgep, rdc)
-			    != NXGE_OK) {
-				NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
-				    "Could not recover channel %d", rdc));
+			rcrp = nxgep->rx_rcr_rings->rcr_rings[rdc];
+			if (rcrp != NULL) {
+				MUTEX_ENTER(&rcrp->lock);
+				if (nxge_rxdma_fatal_err_recover(nxgep,
+				    rdc) != NXGE_OK) {
+					NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
+					    "Could not recover "
+					    "channel %d", rdc));
+				}
+				MUTEX_EXIT(&rcrp->lock);
 			}
 		}
 	}
--- a/usr/src/uts/common/io/nxge/nxge_txdma.c	Thu Sep 17 17:45:50 2009 -0700
+++ b/usr/src/uts/common/io/nxge/nxge_txdma.c	Thu Sep 17 17:09:42 2009 -0700
@@ -209,11 +209,13 @@
 		nxgep->statsp->tdc_ksp[channel] = 0;
 	}
 
-	(void) nxge_txdma_stop_channel(nxgep, channel);
+	if (nxge_txdma_stop_channel(nxgep, channel) != NXGE_OK)
+		goto nxge_uninit_txdma_channel_exit;
+
 	nxge_unmap_txdma_channel(nxgep, channel);
 
-	NXGE_DEBUG_MSG((nxgep, MEM3_CTL,
-	    "<== nxge_uninit_txdma_channel"));
+nxge_uninit_txdma_channel_exit:
+	NXGE_DEBUG_MSG((nxgep, MEM3_CTL, "<== nxge_uninit_txdma_channel"));
 }
 
 void
@@ -684,6 +686,8 @@
 				    (mblk_len < stuff_len)) {
 					stuff_len -= mblk_len;
 					nmp = nmp->b_cont;
+					if (nmp)
+						mblk_len = MBLKL(nmp);
 				}
 				ASSERT(nmp);
 				up = (uint16_t *)(nmp->b_rptr + stuff_len);
@@ -2946,7 +2950,16 @@
 	 */
 	(void) nxge_txdma_stop_inj_err(nxgep, channel);
 
+	if (nxgep->tx_rings == NULL) {
+		status = NXGE_ERROR;
+		goto nxge_txdma_stop_channel_exit;
+	}
+
 	tx_ring_p = nxgep->tx_rings->rings[channel];
+	if (tx_ring_p == NULL) {
+		status = NXGE_ERROR;
+		goto nxge_txdma_stop_channel_exit;
+	}
 
 	/*
 	 * Reset TXDMA channel
--- a/usr/src/uts/common/sys/nxge/nxge_hio.h	Thu Sep 17 17:45:50 2009 -0700
+++ b/usr/src/uts/common/sys/nxge/nxge_hio.h	Thu Sep 17 17:09:42 2009 -0700
@@ -99,8 +99,8 @@
 #define	NXGE_VR_SR_MAX		8 /* There are 8 subregions (SR). */
 
 typedef enum {
-	NXGE_HIO_TYPE_SERVICE,	/* We are a service domain driver. */
-	NXGE_HIO_TYPE_GUEST	/* We are a guest domain driver. */
+	NXGE_HIO_TYPE_SERVICE = 0x80,	/* We are a service domain driver. */
+	NXGE_HIO_TYPE_GUEST		/* We are a guest domain driver. */
 } nxge_hio_type_t;
 
 typedef enum {