6526408 udp application hangs forever when using SO_SNDBUF with value 0 due to QFULL flag never cleared
authorrk129064
Mon, 29 Oct 2007 14:07:16 -0700
changeset 5360 96c808cd96bc
parent 5359 4e4591c79144
child 5361 7208b3d87040
6526408 udp application hangs forever when using SO_SNDBUF with value 0 due to QFULL flag never cleared
usr/src/uts/common/io/stream.c
usr/src/uts/common/os/strsubr.c
--- a/usr/src/uts/common/io/stream.c	Mon Oct 29 13:55:58 2007 -0700
+++ b/usr/src/uts/common/io/stream.c	Mon Oct 29 14:07:16 2007 -0700
@@ -1739,8 +1739,8 @@
 		if (bp->b_band == 0) {
 			q->q_count -= bytecnt;
 			q->q_mblkcnt -= mblkcnt;
-			if ((q->q_count < q->q_hiwat) &&
-			    (q->q_mblkcnt < q->q_hiwat)) {
+			if (q->q_mblkcnt == 0 || ((q->q_count < q->q_hiwat) &&
+			    (q->q_mblkcnt < q->q_hiwat))) {
 				q->q_flag &= ~QFULL;
 			}
 		} else {
@@ -1761,8 +1761,9 @@
 			}
 			qbp->qb_count -= bytecnt;
 			qbp->qb_mblkcnt -= mblkcnt;
-			if ((qbp->qb_count < qbp->qb_hiwat) &&
-			    (qbp->qb_mblkcnt < qbp->qb_hiwat)) {
+			if (qbp->qb_mblkcnt == 0 ||
+			    ((qbp->qb_count < qbp->qb_hiwat) &&
+			    (qbp->qb_mblkcnt < qbp->qb_hiwat))) {
 				qbp->qb_flag &= ~QB_FULL;
 			}
 		}
@@ -1959,15 +1960,15 @@
 	if (mp->b_band == 0) {		/* Perform q_count accounting */
 		q->q_count -= bytecnt;
 		q->q_mblkcnt -= mblkcnt;
-		if ((q->q_count < q->q_hiwat) &&
-		    (q->q_mblkcnt < q->q_hiwat)) {
+		if (q->q_mblkcnt == 0 || ((q->q_count < q->q_hiwat) &&
+		    (q->q_mblkcnt < q->q_hiwat))) {
 			q->q_flag &= ~QFULL;
 		}
 	} else {			/* Perform qb_count accounting */
 		qbp->qb_count -= bytecnt;
 		qbp->qb_mblkcnt -= mblkcnt;
-		if ((qbp->qb_count < qbp->qb_hiwat) &&
-		    (qbp->qb_mblkcnt < qbp->qb_hiwat)) {
+		if (qbp->qb_mblkcnt == 0 || ((qbp->qb_count < qbp->qb_hiwat) &&
+		    (qbp->qb_mblkcnt < qbp->qb_hiwat))) {
 			qbp->qb_flag &= ~QB_FULL;
 		}
 	}
--- a/usr/src/uts/common/os/strsubr.c	Mon Oct 29 13:55:58 2007 -0700
+++ b/usr/src/uts/common/os/strsubr.c	Mon Oct 29 14:07:16 2007 -0700
@@ -7566,9 +7566,13 @@
 	 */
 	mutex_enter(QLOCK(q));
 	/*
-	 * If both q_count and q_mblkcnt are less than the hiwat mark
-	 */
-	if ((q->q_count < q->q_hiwat) && (q->q_mblkcnt < q->q_hiwat)) {
+	 * If queue is empty i.e q_mblkcnt is zero, queue can not be full.
+	 * Hence clear the QFULL.
+	 * If both q_count and q_mblkcnt are less than the hiwat mark,
+	 * clear the QFULL.
+	 */
+	if (q->q_mblkcnt == 0 || ((q->q_count < q->q_hiwat) &&
+	    (q->q_mblkcnt < q->q_hiwat))) {
 		q->q_flag &= ~QFULL;
 		/*
 		 * A little more confusing, how about this way: