Mercurial > illumos > illumos-gate
changeset 3182:175d080807a8
6480791 NULL pointer dereference panic on guest domains.
6494132 ldoms ds module could use lint cleanup
author | jm22469 |
---|---|
date | Mon, 27 Nov 2006 16:54:30 -0800 |
parents | 65ef60e5a248 |
children | e066f975b8da |
files | usr/src/uts/sun4v/ds/Makefile usr/src/uts/sun4v/io/ds.c |
diffstat | 2 files changed, 54 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/sun4v/ds/Makefile Mon Nov 27 14:11:55 2006 -0800 +++ b/usr/src/uts/sun4v/ds/Makefile Mon Nov 27 16:54:30 2006 -0800 @@ -25,7 +25,7 @@ # # ident "%Z%%M% %I% %E% SMI" # -# This makefile drives the production of the zp kernel module. +# This makefile drives the production of the ds kernel module. # # sun4v implementation architecture dependent # @@ -76,7 +76,6 @@ # Please do not carry these forward to new Makefiles. # LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_SUSPICIOUS_COMPARISON # # Default build targets.
--- a/usr/src/uts/sun4v/io/ds.c Mon Nov 27 14:11:55 2006 -0800 +++ b/usr/src/uts/sun4v/io/ds.c Mon Nov 27 16:54:30 2006 -0800 @@ -83,6 +83,30 @@ #define DS_MAXSVCS_INIT 32 /* + * Lock Usage + * + * ds_svcs.rwlock + * + * See comment just above definition of ds_svcs structure above. + * + * ds_port mutex + * + * Protects the elements of each port structure. Must be acquired for + * access to any of the elements. + * + * ds_log mutex + * + * See comment above definition of ds_log structure. + * + * Multiple lock requirements: + * + * Some code will need to access both a ds_svc_t structure and + * a ds_port_t. In that case, the acquisition order must be: + * + * ds_svcs.rwlock -> port lock + */ + +/* * Taskq for internal task processing */ static taskq_t *ds_taskq; @@ -663,17 +687,11 @@ /* * Check the LDC event. */ - - mutex_enter(&port->lock); - - if (event & LDC_EVT_WRITE) { - DS_DBG("ds@%lx: LDC write event received, not supported\n", - port->id); - goto done; - } - if (event & (LDC_EVT_DOWN | LDC_EVT_RESET)) { + rw_enter(&ds_svcs.rwlock, RW_WRITER); + mutex_enter(&port->lock); + /* reset the port state */ ds_port_reset(port); (void) ldc_up(ldc_hdl); @@ -682,6 +700,7 @@ if ((rv = ldc_status(ldc_hdl, &ldc_state)) != 0) { cmn_err(CE_NOTE, "ds@%lx: ldc_status error (%d)\n", port->id, rv); + rw_exit(&ds_svcs.rwlock); goto done; } port->ldc.state = ldc_state; @@ -695,9 +714,12 @@ ASSERT((event & (LDC_EVT_UP | LDC_EVT_READ)) == 0); + rw_exit(&ds_svcs.rwlock); goto done; } + mutex_enter(&port->lock); + if (event & LDC_EVT_UP) { if ((rv = ldc_status(ldc_hdl, &ldc_state)) != 0) { cmn_err(CE_NOTE, "ds@%lx: ldc_status error (%d)\n", @@ -717,6 +739,12 @@ } } + if (event & LDC_EVT_WRITE) { + DS_DBG("ds@%lx: LDC write event received, not supported\n", + port->id); + goto done; + } + /* report any unknown LDC events */ if (event & ~(LDC_EVT_UP | LDC_EVT_READ)) { cmn_err(CE_NOTE, "ds@%lx: Unexpected LDC event received: " @@ -1131,7 +1159,7 @@ ack = (ds_reg_ack_t *)(buf + DS_HDR_SZ); - rw_enter(&ds_svcs.rwlock, RW_READER); + rw_enter(&ds_svcs.rwlock, RW_WRITER); /* lookup appropriate client */ if ((svc = ds_get_svc(ack->svc_handle)) == NULL) { @@ -1210,7 +1238,7 @@ nack = (ds_reg_nack_t *)(buf + DS_HDR_SZ); - rw_enter(&ds_svcs.rwlock, RW_READER); + rw_enter(&ds_svcs.rwlock, RW_WRITER); /* lookup appropriate client */ if ((svc = ds_get_svc(nack->svc_handle)) == NULL) { @@ -1301,7 +1329,7 @@ /* the request information */ req = (ds_unreg_req_t *)(buf + DS_HDR_SZ); - rw_enter(&ds_svcs.rwlock, RW_READER); + rw_enter(&ds_svcs.rwlock, RW_WRITER); /* lookup appropriate client */ if ((svc = ds_get_svc(req->svc_handle)) == NULL) { @@ -1352,7 +1380,7 @@ DS_DBG("ds@%lx: <unreg_ack: hdl=0x%09lx\n", port->id, ack->svc_handle); - rw_enter(&ds_svcs.rwlock, RW_READER); + rw_enter(&ds_svcs.rwlock, RW_WRITER); /* * Since the unregister request was initiated locally, @@ -1386,7 +1414,7 @@ DS_DBG("ds@%lx: <unreg_nack: hdl=0x%09lx\n", port->id, nack->svc_handle); - rw_enter(&ds_svcs.rwlock, RW_READER); + rw_enter(&ds_svcs.rwlock, RW_WRITER); /* * Since the unregister request was initiated locally, @@ -1467,7 +1495,7 @@ if (nack->result == DS_INV_HDL) { - rw_enter(&ds_svcs.rwlock, RW_READER); + rw_enter(&ds_svcs.rwlock, RW_WRITER); if ((svc = ds_get_svc(nack->svc_handle)) == NULL) { rw_exit(&ds_svcs.rwlock); @@ -1877,7 +1905,7 @@ int idx; ds_svc_t *svc; - ASSERT(RW_LOCK_HELD(&ds_svcs.rwlock)); + ASSERT(RW_WRITE_HELD(&ds_svcs.rwlock)); /* walk every table entry */ for (idx = 0; idx < ds_svcs.maxsvcs; idx++) { @@ -1958,6 +1986,8 @@ int idx; + ASSERT(RW_WRITE_HELD(&ds_svcs.rwlock)); + /* check the state of the service */ if (DS_SVC_ISFREE(svc) || (svc->state != DS_SVC_INACTIVE)) return (0); @@ -1999,6 +2029,8 @@ { ds_port_t *port = (ds_port_t *)arg; + ASSERT(RW_WRITE_HELD(&ds_svcs.rwlock)); + if (DS_SVC_ISFREE(svc)) { return (0); } @@ -2098,6 +2130,8 @@ static void ds_reset_svc(ds_svc_t *svc, ds_port_t *port) { + ASSERT(RW_WRITE_HELD(&ds_svcs.rwlock)); + svc->state = DS_SVC_INACTIVE; svc->ver_idx = 0; svc->ver.major = 0; @@ -2192,15 +2226,12 @@ static void ds_port_reset(ds_port_t *port) { + ASSERT(RW_WRITE_HELD(&ds_svcs.rwlock)); ASSERT(MUTEX_HELD(&port->lock)); /* connection went down, mark everything inactive */ - rw_enter(&ds_svcs.rwlock, RW_WRITER); - (void) ds_walk_svcs(ds_svc_unregister, port); - rw_exit(&ds_svcs.rwlock); - port->ver_idx = 0; port->ver.major = 0; port->ver.minor = 0; @@ -2417,8 +2448,6 @@ ds_log.size -= DS_LOG_ENTRY_SZ(head); ds_log.nentry--; - ASSERT((ds_log.size >= 0) && (ds_log.nentry >= 0)); - ds_log_entry_free(head); return (0); @@ -2444,8 +2473,6 @@ ds_log.size -= DS_LOG_ENTRY_SZ(head); - ASSERT((ds_log.size >= 0) && (ds_log.nentry >= 0)); - kmem_free(head->data, head->datasz); head->data = msg; head->datasz = sz; @@ -2604,11 +2631,11 @@ ds_svcs.nsvcs++; - rw_exit(&ds_svcs.rwlock); - /* attempt to register the service */ (void) ds_svc_register(svc, NULL); + rw_exit(&ds_svcs.rwlock); + DS_DBG("ds_cap_init: service '%s' assigned handle 0x%09lx\n", svc->cap.svc_id, svc->hdl);