summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/io/stream.c10
-rw-r--r--usr/src/uts/common/os/streamio.c30
-rw-r--r--usr/src/uts/common/os/strsubr.c34
-rw-r--r--usr/src/uts/common/sys/strsubr.h4
4 files changed, 38 insertions, 40 deletions
diff --git a/usr/src/uts/common/io/stream.c b/usr/src/uts/common/io/stream.c
index 84f32f1cde..943cbe15a7 100644
--- a/usr/src/uts/common/io/stream.c
+++ b/usr/src/uts/common/io/stream.c
@@ -1672,7 +1672,7 @@ mblk_t *
getq(queue_t *q)
{
mblk_t *bp;
- int band = 0;
+ uchar_t band = 0;
bp = getq_noenab(q);
if (bp != NULL)
@@ -1778,7 +1778,7 @@ getq_noenab(queue_t *q)
* But for the write side strwakeq might be invoked and it acquires sd_lock.
*/
void
-qbackenable(queue_t *q, int band)
+qbackenable(queue_t *q, uchar_t band)
{
int backenab = 0;
qband_t *qbp;
@@ -2053,7 +2053,7 @@ flushq_common(queue_t *q, int flag, int pcproto_flag)
mutex_exit(QLOCK(q));
for (bpri = q->q_nband; bpri != 0; bpri--)
if (qbf[bpri])
- backenable(q, (int)bpri);
+ backenable(q, bpri);
if (qbf[0])
backenable(q, 0);
} else
@@ -2131,7 +2131,7 @@ flushband(queue_t *q, unsigned char pri, int flag)
q->q_flag &= ~QWANTW;
mutex_exit(QLOCK(q));
- backenable(q, (int)pri);
+ backenable(q, pri);
} else
mutex_exit(QLOCK(q));
} else { /* pri != 0 */
@@ -2170,7 +2170,7 @@ flushband(queue_t *q, unsigned char pri, int flag)
* will need to be called.
*/
if (flushed)
- qbackenable(q, (int)pri);
+ qbackenable(q, pri);
}
}
diff --git a/usr/src/uts/common/os/streamio.c b/usr/src/uts/common/os/streamio.c
index ec56bc9616..7c3de87018 100644
--- a/usr/src/uts/common/os/streamio.c
+++ b/usr/src/uts/common/os/streamio.c
@@ -204,15 +204,6 @@ push_mod(queue_t *qp, dev_t *devp, struct stdata *stp, const char *name,
return (error);
/*
- * If flow control is on, don't break it - enable
- * first back queue with svc procedure
- */
- if (_RD(stp->sd_wrq)->q_flag & QWANTW) {
- /* Note: no setqback here - use pri -1. */
- backenable(_RD(stp->sd_wrq->q_next), -1);
- }
-
- /*
* Check to see if caller wants a STREAMS anchor
* put at this place in the stream, and add if so.
*/
@@ -3774,15 +3765,6 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag,
}
}
- /*
- * If flow control is on, don't break it - enable
- * first back queue with svc procedure.
- */
- if (rdq->q_flag & QWANTW) {
- /* Note: no setqback here - use pri -1. */
- backenable(_RD(wrq->q_next), -1);
- }
-
mutex_enter(&stp->sd_lock);
/*
@@ -4054,18 +4036,6 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag,
mutex_exit(&stp->sd_lock);
return (error);
}
- /*
- * If flow control is on, don't break it - enable
- * first back queue with svc procedure.
- */
- if (_RD(tmp_wrq)->q_nfsrv->q_flag & QWANTW) {
- /*
- * Note: no setqback here - use pri -1.
- * tmp_wrq->q_next is the new module. We need
- * to backenable() the module below the new module.
- */
- backenable(_RD(tmp_wrq->q_next->q_next), -1);
- }
mutex_enter(&stp->sd_lock);
diff --git a/usr/src/uts/common/os/strsubr.c b/usr/src/uts/common/os/strsubr.c
index c37fab366c..b3826021d3 100644
--- a/usr/src/uts/common/os/strsubr.c
+++ b/usr/src/uts/common/os/strsubr.c
@@ -287,6 +287,7 @@ static void runbufcalls(void);
static void sqenable(syncq_t *);
static void sqfill_events(syncq_t *, queue_t *, mblk_t *, void (*)());
static void wait_q_syncq(queue_t *);
+static void backenable_insertedq(queue_t *);
static void queue_service(queue_t *);
static void stream_service(stdata_t *);
@@ -4037,7 +4038,7 @@ strctty(stdata_t *stp)
* Use pri == -1 to avoid the setqback
*/
void
-backenable(queue_t *q, int pri)
+backenable(queue_t *q, uchar_t pri)
{
queue_t *nq;
@@ -4074,8 +4075,7 @@ backenable(queue_t *q, int pri)
ASSERT(MUTEX_HELD(QLOCK(nq)));
}
#endif
- if (pri != -1)
- setqback(nq, pri);
+ setqback(nq, pri);
qenable_locked(nq);
if (freezer != curthread)
mutex_exit(QLOCK(nq));
@@ -4534,6 +4534,28 @@ strunlock(struct stdata *stp, sqlist_t *sqlist)
}
}
+/*
+ * When the module has service procedure, we need check if the next
+ * module which has service procedure is in flow control to trigger
+ * the backenable.
+ */
+static void
+backenable_insertedq(queue_t *q)
+{
+ qband_t *qbp;
+
+ claimstr(q);
+ if (q->q_qinfo->qi_srvp != NULL && q->q_next != NULL) {
+ if (q->q_next->q_nfsrv->q_flag & QWANTW)
+ backenable(q, 0);
+
+ qbp = q->q_next->q_nfsrv->q_bandp;
+ for (; qbp != NULL; qbp = qbp->qb_next)
+ if ((qbp->qb_flag & QB_WANTW) && qbp->qb_first != NULL)
+ backenable(q, qbp->qb_first->b_band);
+ }
+ releasestr(q);
+}
/*
* Given two read queues, insert a new single one after another.
@@ -4615,6 +4637,12 @@ insertq(struct stdata *stp, queue_t *new)
stp->sd_pushcnt++;
strunlock(stp, NULL);
+
+ /* check if the write Q needs backenable */
+ backenable_insertedq(wnew);
+
+ /* check if the read Q needs backenable */
+ backenable_insertedq(new);
}
/*
diff --git a/usr/src/uts/common/sys/strsubr.h b/usr/src/uts/common/sys/strsubr.h
index a713331ce0..38b6e8669d 100644
--- a/usr/src/uts/common/sys/strsubr.h
+++ b/usr/src/uts/common/sys/strsubr.h
@@ -1120,14 +1120,14 @@ extern void runbuffcalls(void);
extern void disable_svc(queue_t *);
extern void remove_runlist(queue_t *);
extern void wait_svc(queue_t *);
-extern void backenable(queue_t *, int);
+extern void backenable(queue_t *, uchar_t);
extern void set_qend(queue_t *);
extern void set_qnexthot(queue_t *);
extern int strgeterr(stdata_t *, int32_t, int);
extern void qenable_locked(queue_t *);
extern mblk_t *getq_noenab(queue_t *);
extern void rmvq_noenab(queue_t *, mblk_t *);
-extern void qbackenable(queue_t *, int);
+extern void qbackenable(queue_t *, uchar_t);
extern void strblock(queue_t *);
extern void strunblock(queue_t *);