changeset 981:e6bfffd6f3be

6230252 squeue hang
author bw
date Wed, 23 Nov 2005 03:08:29 -0800
parents 253cff0301e4
children 9bc5c1db9740
files usr/src/uts/common/inet/squeue.c
diffstat 1 files changed, 34 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/inet/squeue.c	Tue Nov 22 22:54:27 2005 -0800
+++ b/usr/src/uts/common/inet/squeue.c	Wed Nov 23 03:08:29 2005 -0800
@@ -210,7 +210,7 @@
 #include <sys/squeue_impl.h>
 
 static void squeue_fire(void *);
-static void squeue_drain(squeue_t *, uint_t, clock_t);
+static void squeue_drain(squeue_t *, uint_t, hrtime_t);
 static void squeue_worker(squeue_t *sqp);
 
 #if SQUEUE_PROFILE
@@ -220,15 +220,17 @@
 
 kmem_cache_t *squeue_cache;
 
+#define	SQUEUE_MSEC_TO_NSEC 1000000
+
 int squeue_intrdrain_ms = 20;
 int squeue_writerdrain_ms = 10;
 int squeue_workerdrain_ms = 10;
 int squeue_workerwait_ms = 10;
 
-/* The values above converted to ticks */
-static int squeue_intrdrain_tick = 0;
-static int squeue_writerdrain_tick = 0;
-static int squeue_workerdrain_tick = 0;
+/* The values above converted to ticks or nano seconds */
+static int squeue_intrdrain_ns = 0;
+static int squeue_writerdrain_ns = 0;
+static int squeue_workerdrain_ns = 0;
 static int squeue_workerwait_tick = 0;
 
 /*
@@ -434,9 +436,9 @@
 	squeue_cache = kmem_cache_create("squeue_cache",
 	    sizeof (squeue_t), 64, NULL, NULL, NULL, NULL, NULL, 0);
 
-	squeue_intrdrain_tick = MSEC_TO_TICK_ROUNDUP(squeue_intrdrain_ms);
-	squeue_writerdrain_tick = MSEC_TO_TICK_ROUNDUP(squeue_writerdrain_ms);
-	squeue_workerdrain_tick = MSEC_TO_TICK_ROUNDUP(squeue_workerdrain_ms);
+	squeue_intrdrain_ns = squeue_intrdrain_ms * SQUEUE_MSEC_TO_NSEC;
+	squeue_writerdrain_ns = squeue_writerdrain_ms * SQUEUE_MSEC_TO_NSEC;
+	squeue_workerdrain_ns = squeue_workerdrain_ms * SQUEUE_MSEC_TO_NSEC;
 	squeue_workerwait_tick = MSEC_TO_TICK_ROUNDUP(squeue_workerwait_ms);
 }
 
@@ -453,7 +455,8 @@
 	sqp->sq_bind = bind;
 	sqp->sq_wait = MSEC_TO_TICK(wait);
 	sqp->sq_avg_drain_time =
-	    drv_hztousec(squeue_intrdrain_tick)/squeue_intrdrain_tick;
+	    drv_hztousec(NSEC_TO_TICK_ROUNDUP(squeue_intrdrain_ns)) /
+	    NSEC_TO_TICK_ROUNDUP(squeue_intrdrain_ns);
 
 #if SQUEUE_PROFILE
 	if ((sqp->sq_kstat = kstat_create("ip", bind, name,
@@ -525,6 +528,7 @@
 	int		interrupt = servicing_interrupt();
 	void 		*arg;
 	sqproc_t	proc;
+	hrtime_t	now;
 #if SQUEUE_PROFILE
 	hrtime_t 	start, delta;
 #endif
@@ -662,12 +666,13 @@
 		sqp->sq_isintr = interrupt;
 #endif
 
+		now = gethrtime();
 		if (interrupt) {
-			squeue_drain(sqp, SQS_ENTER, lbolt +
-			    squeue_intrdrain_tick);
+			squeue_drain(sqp, SQS_ENTER, now +
+			    squeue_intrdrain_ns);
 		} else {
-			squeue_drain(sqp, SQS_USER, lbolt +
-			    squeue_writerdrain_tick);
+			squeue_drain(sqp, SQS_USER, now +
+			    squeue_writerdrain_ns);
 		}
 
 #if SQUEUE_PROFILE
@@ -724,6 +729,7 @@
     uint8_t tag)
 {
 	int	interrupt = servicing_interrupt();
+	hrtime_t now;
 #if SQUEUE_PROFILE
 	hrtime_t start, delta;
 #endif
@@ -852,12 +858,13 @@
 		sqp->sq_isintr = interrupt;
 #endif
 
+		now = gethrtime();
 		if (interrupt) {
-			squeue_drain(sqp, SQS_ENTER, lbolt +
-			    squeue_intrdrain_tick);
+			squeue_drain(sqp, SQS_ENTER, now +
+			    squeue_intrdrain_ns);
 		} else {
-			squeue_drain(sqp, SQS_USER, lbolt +
-			    squeue_writerdrain_tick);
+			squeue_drain(sqp, SQS_USER, now +
+			    squeue_writerdrain_ns);
 		}
 
 #if SQUEUE_PROFILE
@@ -1170,7 +1177,7 @@
 }
 
 static void
-squeue_drain(squeue_t *sqp, uint_t proc_type, clock_t expire)
+squeue_drain(squeue_t *sqp, uint_t proc_type, hrtime_t expire)
 {
 	mblk_t	*mp;
 	mblk_t 	*head;
@@ -1184,6 +1191,7 @@
 	ill_rx_ring_t	*sq_rx_ring = sqp->sq_rx_ring;
 	int	interrupt = servicing_interrupt();
 	boolean_t poll_on = B_FALSE;
+	hrtime_t now;
 
 	ASSERT(mutex_owned(&sqp->sq_lock));
 	ASSERT(!(sqp->sq_state & SQS_PROC));
@@ -1276,7 +1284,9 @@
 	total_cnt += cnt;
 
 	if (sqp->sq_first != NULL) {
-		if (!expire || (lbolt < expire)) {
+
+		now = gethrtime();
+		if (!expire || (now < expire)) {
 			/* More arrived and time not expired */
 			head = sqp->sq_first;
 			sqp->sq_first = NULL;
@@ -1329,6 +1339,7 @@
 	kmutex_t *lock = &sqp->sq_lock;
 	kcondvar_t *async = &sqp->sq_async;
 	callb_cpr_t cprinfo;
+	hrtime_t now;
 #if SQUEUE_PROFILE
 	hrtime_t start;
 #endif
@@ -1353,9 +1364,10 @@
 		}
 #endif
 
-		ASSERT(squeue_workerdrain_tick != 0);
+		ASSERT(squeue_workerdrain_ns != 0);
+		now = gethrtime();
 		sqp->sq_run = curthread;
-		squeue_drain(sqp, SQS_WORKER, lbolt +  squeue_workerdrain_tick);
+		squeue_drain(sqp, SQS_WORKER, now +  squeue_workerdrain_ns);
 		sqp->sq_run = NULL;
 
 		if (sqp->sq_first != NULL) {
@@ -1363,7 +1375,7 @@
 			 * Doing too much processing by worker thread
 			 * in presense of interrupts can be sub optimal.
 			 * Instead, once a drain is done by worker thread
-			 * for squeue_writerdrain_ms (the reason we are
+			 * for squeue_writerdrain_ns (the reason we are
 			 * here), we force wait for squeue_workerwait_tick
 			 * before doing more processing even if sq_wait is
 			 * set to 0.