changeset 9916:1b3679ce7b31

6815015 DS invalid handle warning messages seen on creating a large number of domains. 6847264 panic BAD TRAP with PM multidomain ldoms load/stress test (PM_13)
author Mike Christensen <Michael.Christensen@Sun.COM>
date Fri, 19 Jun 2009 11:57:00 -0700
parents bc9126487a5f
children 4de88cdeac3d
files usr/src/uts/sun4v/io/ds_common.c usr/src/uts/sun4v/io/ds_drv.c usr/src/uts/sun4v/sys/ds_impl.h
diffstat 3 files changed, 43 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/sun4v/io/ds_common.c	Fri Jun 19 11:32:47 2009 -0700
+++ b/usr/src/uts/sun4v/io/ds_common.c	Fri Jun 19 11:57:00 2009 -0700
@@ -407,6 +407,7 @@
 	char	ebuf[DS_EBUFSIZE];
 
 	ASSERT(port->state >= DS_PORT_LDC_INIT);
+	ASSERT(MUTEX_HELD(&port->lock));
 
 	DS_DBG_LDC(CE_NOTE, "ds@%lx: %s: ldc_id=%ld" DS_EOL, PORTID(port),
 	    __func__, port->ldc.id);
@@ -429,6 +430,10 @@
 		return (rv);
 	}
 
+	port->ldc.id = (uint64_t)-1;
+	port->ldc.hdl = NULL;
+	port->ldc.state = 0;
+
 	return (rv);
 }
 
@@ -459,7 +464,13 @@
 
 		nbytes = bytes_left;
 
-		if ((rv = ldc_read(port->ldc.hdl, msgp, &nbytes)) != 0) {
+		mutex_enter(&port->lock);
+		if (port->ldc.state == LDC_UP) {
+			rv = ldc_read(port->ldc.hdl, msgp, &nbytes);
+		} else
+			rv = ENXIO;
+		mutex_exit(&port->lock);
+		if (rv != 0) {
 			if (rv == ECONNRESET) {
 				break;
 			} else if (rv != EAGAIN) {
@@ -537,7 +548,15 @@
 
 	mutex_enter(&port->rcv_lock);
 
-	while (((rv = ldc_chkq(port->ldc.hdl, &hasdata)) == 0) && hasdata) {
+	for (;;) {
+		mutex_enter(&port->lock);
+		if (port->ldc.state == LDC_UP) {
+			rv = ldc_chkq(port->ldc.hdl, &hasdata);
+		} else
+			rv = ENXIO;
+		mutex_exit(&port->lock);
+		if (rv != 0 || !hasdata)
+			break;
 
 		DS_DBG(CE_NOTE, "ds@%lx: %s: reading next message" DS_EOL,
 		    PORTID(port), __func__);
@@ -680,7 +699,13 @@
 	mutex_enter(&port->tx_lock);
 
 	do {
-		if ((rv = ldc_write(port->ldc.hdl, currp, &msglen)) != 0) {
+		mutex_enter(&port->lock);
+		if (port->ldc.state == LDC_UP) {
+			rv = ldc_write(port->ldc.hdl, currp, &msglen);
+		} else
+			rv = ENXIO;
+		mutex_exit(&port->lock);
+		if (rv != 0) {
 			if (rv == ECONNRESET) {
 				mutex_exit(&port->tx_lock);
 				ds_handle_down_reset_events(port);
@@ -1397,6 +1422,7 @@
 	char		*msg;
 	size_t		msglen;
 	size_t		explen = DS_MSG_LEN(ds_unreg_req_t);
+	boolean_t	is_up;
 
 	/* sanity check the incoming message */
 	if (len != explen) {
@@ -1415,10 +1441,15 @@
 	    ((svc = ds_find_clnt_svc_by_hdl_port(req->svc_handle, port))
 	    == NULL && ((svc = ds_get_svc(req->svc_handle)) == NULL ||
 	    svc->port != port))) {
+		mutex_exit(&ds_svcs.lock);
+		mutex_enter(&port->lock);
+		is_up = (port->ldc.state == LDC_UP);
+		mutex_exit(&port->lock);
+		if (!is_up)
+			return;
 		cmn_err(CE_WARN, "ds@%lx: <unreg_req: invalid handle 0x%llx"
 		    DS_EOL, PORTID(port), (u_longlong_t)req->svc_handle);
 		ds_send_unreg_nack(port, req->svc_handle);
-		mutex_exit(&ds_svcs.lock);
 		return;
 	}
 
@@ -2731,17 +2762,12 @@
 }
 
 void
-ds_port_common_fini(ds_port_t *port, int is_fini)
+ds_port_common_fini(ds_port_t *port)
 {
+	ASSERT(MUTEX_HELD(&port->lock));
+
 	port->state = DS_PORT_FREE;
 
-	if (is_fini && (port->flags & DS_PORT_MUTEX_INITED) != 0) {
-		mutex_destroy(&port->lock);
-		mutex_destroy(&port->tx_lock);
-		mutex_destroy(&port->rcv_lock);
-		port->flags &= ~DS_PORT_MUTEX_INITED;
-	}
-
 	DS_PORTSET_DEL(ds_allports, port->id);
 
 	ds_sys_port_fini(port);
--- a/usr/src/uts/sun4v/io/ds_drv.c	Fri Jun 19 11:32:47 2009 -0700
+++ b/usr/src/uts/sun4v/io/ds_drv.c	Fri Jun 19 11:57:00 2009 -0700
@@ -817,6 +817,7 @@
 	return (0);
 }
 
+/* ARGSUSED */
 int
 ds_remove_port(uint64_t port_id, int is_fini)
 {
@@ -839,8 +840,6 @@
 		(void) ds_ldc_fini(port);
 	}
 
-	mutex_exit(&port->lock);
-
 	if (port->domain_name) {
 		DS_FREE(port->domain_name, strlen(port->domain_name) + 1);
 		port->domain_name = NULL;
@@ -848,7 +847,9 @@
 	port->domain_hdl = DS_DHDL_INVALID;
 
 	/* clean up the port structure */
-	ds_port_common_fini(port, is_fini);
+	ds_port_common_fini(port);
+
+	mutex_exit(&port->lock);
 	return (0);
 }
 
--- a/usr/src/uts/sun4v/sys/ds_impl.h	Fri Jun 19 11:32:47 2009 -0700
+++ b/usr/src/uts/sun4v/sys/ds_impl.h	Fri Jun 19 11:57:00 2009 -0700
@@ -468,7 +468,7 @@
 
 /* port utilities */
 void ds_port_common_init(ds_port_t *port);
-void ds_port_common_fini(ds_port_t *port, int is_fini);
+void ds_port_common_fini(ds_port_t *port);
 
 /* misc utilities */
 ds_vers_check_t ds_vers_isvalid(ds_ver_t *vers, int nvers);