changeset 12964:1de2e15ec41a

6953050 fmd dumped multiple cores at topo_hdl_root.
author Hyon Kim <Hyon.Kim@Sun.COM>
date Wed, 28 Jul 2010 23:06:01 -0700
parents 58d8b4191f65
children 7a5c324190b8
files usr/src/cmd/fm/fmd/common/fmd_module.c
diffstat 1 files changed, 15 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/fm/fmd/common/fmd_module.c	Wed Jul 28 20:01:03 2010 -0700
+++ b/usr/src/cmd/fm/fmd/common/fmd_module.c	Wed Jul 28 23:06:01 2010 -0700
@@ -526,6 +526,7 @@
 	fmd_event_impl_t *ep = (fmd_event_impl_t *)e;
 	fmd_hdl_t *hdl = (fmd_hdl_t *)mp;
 	fmd_modtimer_t *t;
+	fmd_topo_t *old_topo;
 	volatile int err;
 
 	/*
@@ -575,9 +576,22 @@
 			fmd_case_publish(ep->ev_data, FMD_CASE_CURRENT);
 			break;
 		case FMD_EVT_TOPO:
-			fmd_topo_rele(mp->mod_topo_current);
+			/*
+			 * Save the pointer to the old topology and update
+			 * the pointer with the updated topology.
+			 * With this approach, other threads that reference the
+			 * topology either
+			 *  - finishes with old topology since
+			 *	it is released after updating
+			 *	mod_topo_current.
+			 *  - or is blocked while mod_topo_current is updated.
+			 */
+			old_topo = mp->mod_topo_current;
+			fmd_module_lock(mp);
 			mp->mod_topo_current = (fmd_topo_t *)ep->ev_data;
 			fmd_topo_addref(mp->mod_topo_current);
+			fmd_module_unlock(mp);
+			fmd_topo_rele(old_topo);
 			ops->fmdo_topo(hdl, mp->mod_topo_current->ft_hdl);
 			break;
 		}