6526408 udp application hangs forever when using SO_SNDBUF with value 0 due to QFULL flag never cleared
--- 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: