changeset 12589:08d831116e35

6930949 busy wait loops in px_intr.c and px_ib.c should be consolidated into a single function
author David Major <David.Major@Oracle.COM>
date Tue, 08 Jun 2010 15:59:50 -0600
parents 1cb8fb936e1f
children bfdd79a6d888
files usr/src/uts/sun4/io/px/px_ib.c usr/src/uts/sun4/io/px/px_ib.h usr/src/uts/sun4/io/px/px_intr.c
diffstat 3 files changed, 71 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/sun4/io/px/px_ib.c	Tue Jun 08 13:46:34 2010 -0700
+++ b/usr/src/uts/sun4/io/px/px_ib.c	Tue Jun 08 15:59:50 2010 -0600
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -165,6 +164,45 @@
 	mutex_exit(&ib_p->ib_intr_lock);
 }
 
+int
+px_ib_intr_pend(dev_info_t *dip, sysino_t sysino)
+{
+	int		ret = DDI_SUCCESS;
+	hrtime_t	start_time, prev, curr, interval, jump;
+	hrtime_t	intr_timeout;
+	intr_state_t	intr_state;
+
+	/* Disable the interrupt */
+	PX_INTR_DISABLE(dip, sysino);
+
+	intr_timeout = px_intrpend_timeout;
+	jump = TICK_TO_NSEC(xc_tick_jump_limit);
+
+	/* Busy wait on pending interrupt */
+	for (curr = start_time = gethrtime(); !panicstr &&
+	    ((ret = px_lib_intr_getstate(dip, sysino,
+	    &intr_state)) == DDI_SUCCESS) &&
+	    (intr_state == INTR_DELIVERED_STATE); /* */) {
+		/*
+		 * If we have a really large jump in hrtime, it is most
+		 * probably because we entered the debugger (or OBP,
+		 * in general). So, we adjust the timeout accordingly
+		 * to prevent declaring an interrupt timeout. The
+		 * master-interrupt mechanism in OBP should deliver
+		 * the interrupts properly.
+		 */
+		prev = curr;
+		curr = gethrtime();
+		interval = curr - prev;
+		if (interval > jump)
+			intr_timeout += interval;
+		if (curr - start_time > intr_timeout) {
+			ret = DDI_FAILURE;
+			break;
+		}
+	}
+	return (ret);
+}
 
 void
 px_ib_intr_dist_en(dev_info_t *dip, cpuid_t cpu_id, devino_t ino,
@@ -173,10 +211,6 @@
 	uint32_t	old_cpu_id;
 	sysino_t	sysino;
 	intr_valid_state_t	enabled = 0;
-	hrtime_t	start_time, prev, curr, interval, jump;
-	hrtime_t	intr_timeout;
-	intr_state_t	intr_state;
-	int		e = DDI_SUCCESS;
 
 	DBG(DBG_IB, dip, "px_ib_intr_dist_en: ino=0x%x\n", ino);
 
@@ -204,49 +238,18 @@
 	if (cpu_id == old_cpu_id)
 		return;
 
-	if (!wait_flag)
-		goto done;
-
-	/* Busy wait on pending interrupts */
-	PX_INTR_DISABLE(dip, sysino);
-
-	intr_timeout = px_intrpend_timeout;
-	jump = TICK_TO_NSEC(xc_tick_jump_limit);
+	/* Wait on pending interrupts */
+	if (wait_flag != 0 && px_ib_intr_pend(dip, sysino) != DDI_SUCCESS) {
+		cmn_err(CE_WARN,
+		    "%s%d: px_ib_intr_dist_en: sysino 0x%lx(ino 0x%x) "
+		    "from cpu id 0x%x to 0x%x timeout",
+		    ddi_driver_name(dip), ddi_get_instance(dip),
+		    sysino, ino, old_cpu_id, cpu_id);
 
-	for (curr = start_time = gethrtime(); !panicstr &&
-	    ((e = px_lib_intr_getstate(dip, sysino, &intr_state)) ==
-	    DDI_SUCCESS) &&
-	    (intr_state == INTR_DELIVERED_STATE); /* */) {
-		/*
-		 * If we have a really large jump in hrtime, it is most
-		 * probably because we entered the debugger (or OBP,
-		 * in general). So, we adjust the timeout accordingly
-		 * to prevent declaring an interrupt timeout. The
-		 * master-interrupt mechanism in OBP should deliver
-		 * the interrupts properly.
-		 */
-		prev = curr;
-		curr = gethrtime();
-		interval = curr - prev;
-		if (interval > jump)
-			intr_timeout += interval;
-		if (curr - start_time > intr_timeout) {
-			cmn_err(CE_WARN,
-			    "%s%d: px_ib_intr_dist_en: sysino 0x%lx(ino 0x%x) "
-			    "from cpu id 0x%x to 0x%x timeout",
-			    ddi_driver_name(dip), ddi_get_instance(dip),
-			    sysino, ino, old_cpu_id, cpu_id);
-
-			e = DDI_FAILURE;
-			break;
-		}
+		DBG(DBG_IB, dip, "px_ib_intr_dist_en: failed, "
+		    "ino 0x%x sysino 0x%x\n", ino, sysino);
 	}
 
-	if (e != DDI_SUCCESS)
-		DBG(DBG_IB, dip, "px_ib_intr_dist_en: failed, "
-		    "ino 0x%x sysino 0x%x\n", ino, sysino);
-
-done:
 	PX_INTR_ENABLE(dip, sysino, cpu_id);
 }
 
@@ -602,8 +605,6 @@
 	sysino_t	sysino = ino_p->ino_sysino;
 	dev_info_t	*dip = px_p->px_dip;
 	cpuid_t		curr_cpu;
-	hrtime_t	start_time;
-	intr_state_t	intr_state;
 	int		ret = DDI_SUCCESS;
 
 	ASSERT(MUTEX_HELD(&ib_p->ib_ino_lst_mutex));
@@ -620,21 +621,12 @@
 		return (ret);
 	}
 
-	PX_INTR_DISABLE(dip, sysino);
-
-	/* Busy wait on pending interrupt */
-	for (start_time = gethrtime(); !panicstr &&
-	    ((ret = px_lib_intr_getstate(dip, sysino, &intr_state))
-	    == DDI_SUCCESS) && (intr_state == INTR_DELIVERED_STATE); /* */) {
-		if (gethrtime() - start_time > px_intrpend_timeout) {
-			cmn_err(CE_WARN, "%s%d: px_ib_ino_add_intr: pending "
-			    "sysino 0x%lx(ino 0x%x) timeout",
-			    ddi_driver_name(dip), ddi_get_instance(dip),
-			    sysino, ino);
-
-			ret = DDI_FAILURE;
-			break;
-		}
+	/* Wait on pending interrupt */
+	if ((ret = px_ib_intr_pend(dip, sysino)) != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: px_ib_ino_add_intr: pending "
+		    "sysino 0x%lx(ino 0x%x) timeout",
+		    ddi_driver_name(dip), ddi_get_instance(dip),
+		    sysino, ino);
 	}
 
 	/*
@@ -687,8 +679,6 @@
 	sysino_t	sysino = ino_p->ino_sysino;
 	dev_info_t	*dip = px_p->px_dip;
 	px_ih_t		*ih_lst = ipil_p->ipil_ih_head;
-	hrtime_t	start_time;
-	intr_state_t	intr_state;
 	int		i, ret = DDI_SUCCESS;
 
 	ASSERT(MUTEX_HELD(&ino_p->ino_ib_p->ib_ino_lst_mutex));
@@ -696,22 +686,12 @@
 	DBG(DBG_IB, px_p->px_dip, "px_ib_ino_rem_intr ino=%x\n",
 	    ino_p->ino_ino);
 
-	/* Disable the interrupt */
-	PX_INTR_DISABLE(px_p->px_dip, sysino);
-
-	/* Busy wait on pending interrupt */
-	for (start_time = gethrtime(); !panicstr &&
-	    ((ret = px_lib_intr_getstate(dip, sysino, &intr_state))
-	    == DDI_SUCCESS) && (intr_state == INTR_DELIVERED_STATE); /* */) {
-		if (gethrtime() - start_time > px_intrpend_timeout) {
-			cmn_err(CE_WARN, "%s%d: px_ib_ino_rem_intr: pending "
-			    "sysino 0x%lx(ino 0x%x) timeout",
-			    ddi_driver_name(dip), ddi_get_instance(dip),
-			    sysino, ino);
-
-			ret = DDI_FAILURE;
-			break;
-		}
+	/* Wait on pending interrupt */
+	if ((ret = px_ib_intr_pend(dip, sysino)) != DDI_SUCCESS) {
+		cmn_err(CE_WARN, "%s%d: px_ib_ino_rem_intr: pending "
+		    "sysino 0x%lx(ino 0x%x) timeout",
+		    ddi_driver_name(dip), ddi_get_instance(dip),
+		    sysino, ino);
 	}
 
 	/*
--- a/usr/src/uts/sun4/io/px/px_ib.h	Tue Jun 08 13:46:34 2010 -0700
+++ b/usr/src/uts/sun4/io/px/px_ib.h	Tue Jun 08 15:59:50 2010 -0600
@@ -19,8 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #ifndef	_SYS_PX_IB_H
@@ -133,6 +132,7 @@
 extern void px_ib_detach(px_t *px_p);
 extern void px_ib_intr_enable(px_t *px_p, cpuid_t cpuid, devino_t ino);
 extern void px_ib_intr_disable(px_ib_t *ib_p, devino_t ino, int wait);
+extern int px_ib_intr_pend(dev_info_t *dip, sysino_t sysino);
 extern void px_ib_intr_dist_en(dev_info_t *dip, cpuid_t cpu_id, devino_t ino,
     boolean_t wait_flag);
 
--- a/usr/src/uts/sun4/io/px/px_intr.c	Tue Jun 08 13:46:34 2010 -0700
+++ b/usr/src/uts/sun4/io/px/px_intr.c	Tue Jun 08 15:59:50 2010 -0600
@@ -988,9 +988,6 @@
 
 	/* Sharing the INO using a new PIL */
 	if (ipil_list != NULL) {
-		intr_state_t	intr_state;
-		hrtime_t	start_time;
-
 		/*
 		 * disable INO to avoid lopil race condition with
 		 * px_intx_intr
@@ -1004,23 +1001,14 @@
 			goto fail1;
 		}
 
-		/* Disable the interrupt */
-		PX_INTR_DISABLE(dip, ino_p->ino_sysino);
-
-		/* Busy wait on pending interrupt */
-		for (start_time = gethrtime(); !panicstr &&
-		    ((ret = px_lib_intr_getstate(dip, ino_p->ino_sysino,
-		    &intr_state)) == DDI_SUCCESS) &&
-		    (intr_state == INTR_DELIVERED_STATE); /* */) {
-			if (gethrtime() - start_time > px_intrpend_timeout) {
-				cmn_err(CE_WARN, "%s%d: px_add_intx_intr: "
-				    "pending sysino 0x%lx(ino 0x%x) timeout",
-				    ddi_driver_name(dip), ddi_get_instance(dip),
-				    ino_p->ino_sysino, ino_p->ino_ino);
-
-				ret = DDI_FAILURE;
-				goto fail1;
-			}
+		/* Wait on pending interrupt */
+		if ((ret = px_ib_intr_pend(dip, ino_p->ino_sysino)) !=
+		    DDI_SUCCESS) {
+			cmn_err(CE_WARN, "%s%d: px_add_intx_intr: "
+			    "pending sysino 0x%lx(ino 0x%x) timeout",
+			    ddi_driver_name(dip), ddi_get_instance(dip),
+			    ino_p->ino_sysino, ino_p->ino_ino);
+			goto fail1;
 		}
 	}