sctp: Cleanup stream schedulers.
No functional change intended. MFC after: 1 week
This commit is contained in:
parent
0b92a7fe47
commit
414499b3f9
@ -12176,7 +12176,7 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
|
||||
* initializing the new stuff.
|
||||
*/
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 0);
|
||||
stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, false);
|
||||
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
|
||||
TAILQ_INIT(&stcb->asoc.strmout[i].outqueue);
|
||||
/* FIX ME FIX ME */
|
||||
|
@ -54,6 +54,7 @@ sctp_ss_default_init(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
uint16_t i;
|
||||
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
|
||||
asoc->ss_data.locked_on_sending = NULL;
|
||||
asoc->ss_data.last_out_stream = NULL;
|
||||
TAILQ_INIT(&asoc->ss_data.out.wheel);
|
||||
@ -72,7 +73,7 @@ sctp_ss_default_init(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
|
||||
static void
|
||||
sctp_ss_default_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
int clear_values SCTP_UNUSED)
|
||||
bool clear_values SCTP_UNUSED)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
|
||||
@ -80,9 +81,8 @@ sctp_ss_default_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq;
|
||||
|
||||
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.rr.next_spoke);
|
||||
strq->ss_params.rr.next_spoke.tqe_next = NULL;
|
||||
strq->ss_params.rr.next_spoke.tqe_prev = NULL;
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.ss.rr.next_spoke);
|
||||
strq->ss_params.scheduled = false;
|
||||
}
|
||||
asoc->ss_data.last_out_stream = NULL;
|
||||
return;
|
||||
@ -99,8 +99,7 @@ sctp_ss_default_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq,
|
||||
stcb->asoc.ss_data.last_out_stream = strq;
|
||||
}
|
||||
}
|
||||
strq->ss_params.rr.next_spoke.tqe_next = NULL;
|
||||
strq->ss_params.rr.next_spoke.tqe_prev = NULL;
|
||||
strq->ss_params.scheduled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -112,23 +111,18 @@ sctp_ss_default_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
|
||||
/* Add to wheel if not already on it and stream queue not empty */
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) &&
|
||||
(strq->ss_params.rr.next_spoke.tqe_next == NULL) &&
|
||||
(strq->ss_params.rr.next_spoke.tqe_prev == NULL)) {
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) && !strq->ss_params.scheduled) {
|
||||
TAILQ_INSERT_TAIL(&asoc->ss_data.out.wheel,
|
||||
strq, ss_params.rr.next_spoke);
|
||||
strq, ss_params.ss.rr.next_spoke);
|
||||
strq->ss_params.scheduled = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
sctp_ss_default_is_empty(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc)
|
||||
{
|
||||
if (TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
|
||||
return (1);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
return (TAILQ_EMPTY(&asoc->ss_data.out.wheel));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -142,13 +136,11 @@ sctp_ss_default_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
* Remove from wheel if stream queue is empty and actually is on the
|
||||
* wheel
|
||||
*/
|
||||
if (TAILQ_EMPTY(&strq->outqueue) &&
|
||||
(strq->ss_params.rr.next_spoke.tqe_next != NULL ||
|
||||
strq->ss_params.rr.next_spoke.tqe_prev != NULL)) {
|
||||
if (TAILQ_EMPTY(&strq->outqueue) && strq->ss_params.scheduled) {
|
||||
if (asoc->ss_data.last_out_stream == strq) {
|
||||
asoc->ss_data.last_out_stream = TAILQ_PREV(asoc->ss_data.last_out_stream,
|
||||
sctpwheel_listhead,
|
||||
ss_params.rr.next_spoke);
|
||||
ss_params.ss.rr.next_spoke);
|
||||
if (asoc->ss_data.last_out_stream == NULL) {
|
||||
asoc->ss_data.last_out_stream = TAILQ_LAST(&asoc->ss_data.out.wheel,
|
||||
sctpwheel_listhead);
|
||||
@ -157,9 +149,8 @@ sctp_ss_default_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
asoc->ss_data.last_out_stream = NULL;
|
||||
}
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.rr.next_spoke);
|
||||
strq->ss_params.rr.next_spoke.tqe_next = NULL;
|
||||
strq->ss_params.rr.next_spoke.tqe_prev = NULL;
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.ss.rr.next_spoke);
|
||||
strq->ss_params.scheduled = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -179,7 +170,7 @@ default_again:
|
||||
if (strqt == NULL) {
|
||||
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
} else {
|
||||
strq = TAILQ_NEXT(strqt, ss_params.rr.next_spoke);
|
||||
strq = TAILQ_NEXT(strqt, ss_params.ss.rr.next_spoke);
|
||||
if (strq == NULL) {
|
||||
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
}
|
||||
@ -257,24 +248,24 @@ sctp_ss_default_set_value(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_associa
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
sctp_ss_default_is_user_msgs_incomplete(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc)
|
||||
{
|
||||
struct sctp_stream_out *strq;
|
||||
struct sctp_stream_queue_pending *sp;
|
||||
|
||||
if (asoc->stream_queue_cnt != 1) {
|
||||
return (0);
|
||||
return (false);
|
||||
}
|
||||
strq = asoc->ss_data.locked_on_sending;
|
||||
if (strq == NULL) {
|
||||
return (0);
|
||||
return (false);
|
||||
}
|
||||
sp = TAILQ_FIRST(&strq->outqueue);
|
||||
if (sp == NULL) {
|
||||
return (0);
|
||||
return (false);
|
||||
}
|
||||
return (!sp->msg_is_complete);
|
||||
return (sp->msg_is_complete == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -290,22 +281,21 @@ sctp_ss_rr_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) &&
|
||||
(strq->ss_params.rr.next_spoke.tqe_next == NULL) &&
|
||||
(strq->ss_params.rr.next_spoke.tqe_prev == NULL)) {
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) && !strq->ss_params.scheduled) {
|
||||
if (TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
|
||||
TAILQ_INSERT_HEAD(&asoc->ss_data.out.wheel, strq, ss_params.rr.next_spoke);
|
||||
TAILQ_INSERT_HEAD(&asoc->ss_data.out.wheel, strq, ss_params.ss.rr.next_spoke);
|
||||
} else {
|
||||
strqt = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
while (strqt != NULL && (strqt->sid < strq->sid)) {
|
||||
strqt = TAILQ_NEXT(strqt, ss_params.rr.next_spoke);
|
||||
strqt = TAILQ_NEXT(strqt, ss_params.ss.rr.next_spoke);
|
||||
}
|
||||
if (strqt != NULL) {
|
||||
TAILQ_INSERT_BEFORE(strqt, strq, ss_params.rr.next_spoke);
|
||||
TAILQ_INSERT_BEFORE(strqt, strq, ss_params.ss.rr.next_spoke);
|
||||
} else {
|
||||
TAILQ_INSERT_TAIL(&asoc->ss_data.out.wheel, strq, ss_params.rr.next_spoke);
|
||||
TAILQ_INSERT_TAIL(&asoc->ss_data.out.wheel, strq, ss_params.ss.rr.next_spoke);
|
||||
}
|
||||
}
|
||||
strq->ss_params.scheduled = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -334,7 +324,7 @@ rrp_again:
|
||||
if (strqt == NULL) {
|
||||
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
} else {
|
||||
strq = TAILQ_NEXT(strqt, ss_params.rr.next_spoke);
|
||||
strq = TAILQ_NEXT(strqt, ss_params.ss.rr.next_spoke);
|
||||
if (strq == NULL) {
|
||||
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
}
|
||||
@ -372,7 +362,7 @@ rrp_again:
|
||||
*/
|
||||
static void
|
||||
sctp_ss_prio_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
int clear_values)
|
||||
bool clear_values)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
|
||||
@ -381,11 +371,10 @@ sctp_ss_prio_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
|
||||
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
if (clear_values) {
|
||||
strq->ss_params.prio.priority = 0;
|
||||
strq->ss_params.ss.prio.priority = 0;
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.prio.next_spoke);
|
||||
strq->ss_params.prio.next_spoke.tqe_next = NULL;
|
||||
strq->ss_params.prio.next_spoke.tqe_prev = NULL;
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.ss.prio.next_spoke);
|
||||
strq->ss_params.scheduled = false;
|
||||
}
|
||||
asoc->ss_data.last_out_stream = NULL;
|
||||
return;
|
||||
@ -402,12 +391,11 @@ sctp_ss_prio_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq, st
|
||||
stcb->asoc.ss_data.last_out_stream = strq;
|
||||
}
|
||||
}
|
||||
strq->ss_params.prio.next_spoke.tqe_next = NULL;
|
||||
strq->ss_params.prio.next_spoke.tqe_prev = NULL;
|
||||
strq->ss_params.scheduled = false;
|
||||
if (with_strq != NULL) {
|
||||
strq->ss_params.prio.priority = with_strq->ss_params.prio.priority;
|
||||
strq->ss_params.ss.prio.priority = with_strq->ss_params.ss.prio.priority;
|
||||
} else {
|
||||
strq->ss_params.prio.priority = 0;
|
||||
strq->ss_params.ss.prio.priority = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -421,22 +409,21 @@ sctp_ss_prio_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
|
||||
/* Add to wheel if not already on it and stream queue not empty */
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) &&
|
||||
(strq->ss_params.prio.next_spoke.tqe_next == NULL) &&
|
||||
(strq->ss_params.prio.next_spoke.tqe_prev == NULL)) {
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) && !strq->ss_params.scheduled) {
|
||||
if (TAILQ_EMPTY(&asoc->ss_data.out.wheel)) {
|
||||
TAILQ_INSERT_HEAD(&asoc->ss_data.out.wheel, strq, ss_params.prio.next_spoke);
|
||||
TAILQ_INSERT_HEAD(&asoc->ss_data.out.wheel, strq, ss_params.ss.prio.next_spoke);
|
||||
} else {
|
||||
strqt = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
while (strqt != NULL && strqt->ss_params.prio.priority < strq->ss_params.prio.priority) {
|
||||
strqt = TAILQ_NEXT(strqt, ss_params.prio.next_spoke);
|
||||
while (strqt != NULL && strqt->ss_params.ss.prio.priority < strq->ss_params.ss.prio.priority) {
|
||||
strqt = TAILQ_NEXT(strqt, ss_params.ss.prio.next_spoke);
|
||||
}
|
||||
if (strqt != NULL) {
|
||||
TAILQ_INSERT_BEFORE(strqt, strq, ss_params.prio.next_spoke);
|
||||
TAILQ_INSERT_BEFORE(strqt, strq, ss_params.ss.prio.next_spoke);
|
||||
} else {
|
||||
TAILQ_INSERT_TAIL(&asoc->ss_data.out.wheel, strq, ss_params.prio.next_spoke);
|
||||
TAILQ_INSERT_TAIL(&asoc->ss_data.out.wheel, strq, ss_params.ss.prio.next_spoke);
|
||||
}
|
||||
}
|
||||
strq->ss_params.scheduled = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -451,12 +438,11 @@ sctp_ss_prio_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
* Remove from wheel if stream queue is empty and actually is on the
|
||||
* wheel
|
||||
*/
|
||||
if (TAILQ_EMPTY(&strq->outqueue) &&
|
||||
(strq->ss_params.prio.next_spoke.tqe_next != NULL ||
|
||||
strq->ss_params.prio.next_spoke.tqe_prev != NULL)) {
|
||||
if (TAILQ_EMPTY(&strq->outqueue) && strq->ss_params.scheduled) {
|
||||
if (asoc->ss_data.last_out_stream == strq) {
|
||||
asoc->ss_data.last_out_stream = TAILQ_PREV(asoc->ss_data.last_out_stream, sctpwheel_listhead,
|
||||
ss_params.prio.next_spoke);
|
||||
asoc->ss_data.last_out_stream = TAILQ_PREV(asoc->ss_data.last_out_stream,
|
||||
sctpwheel_listhead,
|
||||
ss_params.ss.prio.next_spoke);
|
||||
if (asoc->ss_data.last_out_stream == NULL) {
|
||||
asoc->ss_data.last_out_stream = TAILQ_LAST(&asoc->ss_data.out.wheel,
|
||||
sctpwheel_listhead);
|
||||
@ -465,9 +451,8 @@ sctp_ss_prio_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
asoc->ss_data.last_out_stream = NULL;
|
||||
}
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.prio.next_spoke);
|
||||
strq->ss_params.prio.next_spoke.tqe_next = NULL;
|
||||
strq->ss_params.prio.next_spoke.tqe_prev = NULL;
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.ss.prio.next_spoke);
|
||||
strq->ss_params.scheduled = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -487,9 +472,9 @@ prio_again:
|
||||
if (strqt == NULL) {
|
||||
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
} else {
|
||||
strqn = TAILQ_NEXT(strqt, ss_params.prio.next_spoke);
|
||||
strqn = TAILQ_NEXT(strqt, ss_params.ss.prio.next_spoke);
|
||||
if (strqn != NULL &&
|
||||
strqn->ss_params.prio.priority == strqt->ss_params.prio.priority) {
|
||||
strqn->ss_params.ss.prio.priority == strqt->ss_params.ss.prio.priority) {
|
||||
strq = strqn;
|
||||
} else {
|
||||
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
@ -528,7 +513,7 @@ sctp_ss_prio_get_value(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_associatio
|
||||
if (strq == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
*value = strq->ss_params.prio.priority;
|
||||
*value = strq->ss_params.ss.prio.priority;
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -539,7 +524,7 @@ sctp_ss_prio_set_value(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
if (strq == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
strq->ss_params.prio.priority = value;
|
||||
strq->ss_params.ss.prio.priority = value;
|
||||
sctp_ss_prio_remove(stcb, asoc, strq, NULL);
|
||||
sctp_ss_prio_add(stcb, asoc, strq, NULL);
|
||||
return (1);
|
||||
@ -551,7 +536,7 @@ sctp_ss_prio_set_value(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
*/
|
||||
static void
|
||||
sctp_ss_fb_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
int clear_values)
|
||||
bool clear_values)
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
|
||||
@ -560,11 +545,10 @@ sctp_ss_fb_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
|
||||
strq = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
if (clear_values) {
|
||||
strq->ss_params.fb.rounds = -1;
|
||||
strq->ss_params.ss.fb.rounds = -1;
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.fb.next_spoke);
|
||||
strq->ss_params.fb.next_spoke.tqe_next = NULL;
|
||||
strq->ss_params.fb.next_spoke.tqe_prev = NULL;
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.ss.fb.next_spoke);
|
||||
strq->ss_params.scheduled = false;
|
||||
}
|
||||
asoc->ss_data.last_out_stream = NULL;
|
||||
return;
|
||||
@ -581,12 +565,11 @@ sctp_ss_fb_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq, stru
|
||||
stcb->asoc.ss_data.last_out_stream = strq;
|
||||
}
|
||||
}
|
||||
strq->ss_params.fb.next_spoke.tqe_next = NULL;
|
||||
strq->ss_params.fb.next_spoke.tqe_prev = NULL;
|
||||
strq->ss_params.scheduled = false;
|
||||
if (with_strq != NULL) {
|
||||
strq->ss_params.fb.rounds = with_strq->ss_params.fb.rounds;
|
||||
strq->ss_params.ss.fb.rounds = with_strq->ss_params.ss.fb.rounds;
|
||||
} else {
|
||||
strq->ss_params.fb.rounds = -1;
|
||||
strq->ss_params.ss.fb.rounds = -1;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -597,12 +580,11 @@ sctp_ss_fb_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) &&
|
||||
(strq->ss_params.fb.next_spoke.tqe_next == NULL) &&
|
||||
(strq->ss_params.fb.next_spoke.tqe_prev == NULL)) {
|
||||
if (strq->ss_params.fb.rounds < 0)
|
||||
strq->ss_params.fb.rounds = TAILQ_FIRST(&strq->outqueue)->length;
|
||||
TAILQ_INSERT_TAIL(&asoc->ss_data.out.wheel, strq, ss_params.fb.next_spoke);
|
||||
if (!TAILQ_EMPTY(&strq->outqueue) && !strq->ss_params.scheduled) {
|
||||
if (strq->ss_params.ss.fb.rounds < 0)
|
||||
strq->ss_params.ss.fb.rounds = TAILQ_FIRST(&strq->outqueue)->length;
|
||||
TAILQ_INSERT_TAIL(&asoc->ss_data.out.wheel, strq, ss_params.ss.fb.next_spoke);
|
||||
strq->ss_params.scheduled = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -617,12 +599,11 @@ sctp_ss_fb_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
* Remove from wheel if stream queue is empty and actually is on the
|
||||
* wheel
|
||||
*/
|
||||
if (TAILQ_EMPTY(&strq->outqueue) &&
|
||||
(strq->ss_params.fb.next_spoke.tqe_next != NULL ||
|
||||
strq->ss_params.fb.next_spoke.tqe_prev != NULL)) {
|
||||
if (TAILQ_EMPTY(&strq->outqueue) && strq->ss_params.scheduled) {
|
||||
if (asoc->ss_data.last_out_stream == strq) {
|
||||
asoc->ss_data.last_out_stream = TAILQ_PREV(asoc->ss_data.last_out_stream, sctpwheel_listhead,
|
||||
ss_params.fb.next_spoke);
|
||||
asoc->ss_data.last_out_stream = TAILQ_PREV(asoc->ss_data.last_out_stream,
|
||||
sctpwheel_listhead,
|
||||
ss_params.ss.fb.next_spoke);
|
||||
if (asoc->ss_data.last_out_stream == NULL) {
|
||||
asoc->ss_data.last_out_stream = TAILQ_LAST(&asoc->ss_data.out.wheel,
|
||||
sctpwheel_listhead);
|
||||
@ -631,9 +612,8 @@ sctp_ss_fb_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
asoc->ss_data.last_out_stream = NULL;
|
||||
}
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.fb.next_spoke);
|
||||
strq->ss_params.fb.next_spoke.tqe_next = NULL;
|
||||
strq->ss_params.fb.next_spoke.tqe_prev = NULL;
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.wheel, strq, ss_params.ss.fb.next_spoke);
|
||||
strq->ss_params.scheduled = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -651,7 +631,7 @@ sctp_ss_fb_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
|
||||
TAILQ_FIRST(&asoc->ss_data.out.wheel) == TAILQ_LAST(&asoc->ss_data.out.wheel, sctpwheel_listhead)) {
|
||||
strqt = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
} else {
|
||||
strqt = TAILQ_NEXT(asoc->ss_data.last_out_stream, ss_params.fb.next_spoke);
|
||||
strqt = TAILQ_NEXT(asoc->ss_data.last_out_stream, ss_params.ss.fb.next_spoke);
|
||||
}
|
||||
do {
|
||||
if ((strqt != NULL) &&
|
||||
@ -660,13 +640,14 @@ sctp_ss_fb_select(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_nets *net,
|
||||
(net == NULL || (TAILQ_FIRST(&strqt->outqueue) && TAILQ_FIRST(&strqt->outqueue)->net == NULL) ||
|
||||
(net != NULL && TAILQ_FIRST(&strqt->outqueue) && TAILQ_FIRST(&strqt->outqueue)->net != NULL &&
|
||||
TAILQ_FIRST(&strqt->outqueue)->net == net))))) {
|
||||
if ((strqt->ss_params.fb.rounds >= 0) && (strq == NULL ||
|
||||
strqt->ss_params.fb.rounds < strq->ss_params.fb.rounds)) {
|
||||
if ((strqt->ss_params.ss.fb.rounds >= 0) &&
|
||||
((strq == NULL) ||
|
||||
(strqt->ss_params.ss.fb.rounds < strq->ss_params.ss.fb.rounds))) {
|
||||
strq = strqt;
|
||||
}
|
||||
}
|
||||
if (strqt != NULL) {
|
||||
strqt = TAILQ_NEXT(strqt, ss_params.fb.next_spoke);
|
||||
strqt = TAILQ_NEXT(strqt, ss_params.ss.fb.next_spoke);
|
||||
} else {
|
||||
strqt = TAILQ_FIRST(&asoc->ss_data.out.wheel);
|
||||
}
|
||||
@ -693,16 +674,16 @@ sctp_ss_fb_scheduled(struct sctp_tcb *stcb, struct sctp_nets *net SCTP_UNUSED,
|
||||
} else {
|
||||
stcb->asoc.ss_data.locked_on_sending = NULL;
|
||||
}
|
||||
subtract = strq->ss_params.fb.rounds;
|
||||
TAILQ_FOREACH(strqt, &asoc->ss_data.out.wheel, ss_params.fb.next_spoke) {
|
||||
strqt->ss_params.fb.rounds -= subtract;
|
||||
if (strqt->ss_params.fb.rounds < 0)
|
||||
strqt->ss_params.fb.rounds = 0;
|
||||
subtract = strq->ss_params.ss.fb.rounds;
|
||||
TAILQ_FOREACH(strqt, &asoc->ss_data.out.wheel, ss_params.ss.fb.next_spoke) {
|
||||
strqt->ss_params.ss.fb.rounds -= subtract;
|
||||
if (strqt->ss_params.ss.fb.rounds < 0)
|
||||
strqt->ss_params.ss.fb.rounds = 0;
|
||||
}
|
||||
if (TAILQ_FIRST(&strq->outqueue)) {
|
||||
strq->ss_params.fb.rounds = TAILQ_FIRST(&strq->outqueue)->length;
|
||||
strq->ss_params.ss.fb.rounds = TAILQ_FIRST(&strq->outqueue)->length;
|
||||
} else {
|
||||
strq->ss_params.fb.rounds = -1;
|
||||
strq->ss_params.ss.fb.rounds = -1;
|
||||
}
|
||||
asoc->ss_data.last_out_stream = strq;
|
||||
return;
|
||||
@ -754,7 +735,7 @@ sctp_ss_fcfs_init(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
|
||||
static void
|
||||
sctp_ss_fcfs_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
int clear_values SCTP_UNUSED)
|
||||
bool clear_values SCTP_UNUSED)
|
||||
{
|
||||
struct sctp_stream_queue_pending *sp;
|
||||
|
||||
@ -763,8 +744,7 @@ sctp_ss_fcfs_clear(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
while (!TAILQ_EMPTY(&asoc->ss_data.out.list)) {
|
||||
sp = TAILQ_FIRST(&asoc->ss_data.out.list);
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.list, sp, ss_next);
|
||||
sp->ss_next.tqe_next = NULL;
|
||||
sp->ss_next.tqe_prev = NULL;
|
||||
sp->scheduled = false;
|
||||
}
|
||||
asoc->ss_data.last_out_stream = NULL;
|
||||
return;
|
||||
@ -781,8 +761,7 @@ sctp_ss_fcfs_init_stream(struct sctp_tcb *stcb, struct sctp_stream_out *strq, st
|
||||
stcb->asoc.ss_data.last_out_stream = strq;
|
||||
}
|
||||
}
|
||||
strq->ss_params.fb.next_spoke.tqe_next = NULL;
|
||||
strq->ss_params.fb.next_spoke.tqe_prev = NULL;
|
||||
strq->ss_params.scheduled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -792,21 +771,17 @@ sctp_ss_fcfs_add(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
|
||||
if (sp && (sp->ss_next.tqe_next == NULL) &&
|
||||
(sp->ss_next.tqe_prev == NULL)) {
|
||||
if (!sp->scheduled) {
|
||||
TAILQ_INSERT_TAIL(&asoc->ss_data.out.list, sp, ss_next);
|
||||
sp->scheduled = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
sctp_ss_fcfs_is_empty(struct sctp_tcb *stcb SCTP_UNUSED, struct sctp_association *asoc)
|
||||
{
|
||||
if (TAILQ_EMPTY(&asoc->ss_data.out.list)) {
|
||||
return (1);
|
||||
} else {
|
||||
return (0);
|
||||
}
|
||||
return (TAILQ_EMPTY(&asoc->ss_data.out.list));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -815,12 +790,9 @@ sctp_ss_fcfs_remove(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
{
|
||||
SCTP_TCB_SEND_LOCK_ASSERT(stcb);
|
||||
|
||||
if (sp &&
|
||||
((sp->ss_next.tqe_next != NULL) ||
|
||||
(sp->ss_next.tqe_prev != NULL))) {
|
||||
if (sp->scheduled) {
|
||||
TAILQ_REMOVE(&asoc->ss_data.out.list, sp, ss_next);
|
||||
sp->ss_next.tqe_next = NULL;
|
||||
sp->ss_next.tqe_prev = NULL;
|
||||
sp->scheduled = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -505,6 +505,7 @@ struct sctp_queued_to_read { /* sinfo structure Pluse more */
|
||||
* the user is in the explict MSG_EOR mode
|
||||
* and wrote some data, but has not completed
|
||||
* sending.
|
||||
* ss_next and scheduled are only used by the FCFS stream scheduler.
|
||||
*/
|
||||
struct sctp_stream_queue_pending {
|
||||
struct mbuf *data;
|
||||
@ -529,6 +530,7 @@ struct sctp_stream_queue_pending {
|
||||
uint8_t put_last_out;
|
||||
uint8_t discard_rest;
|
||||
uint8_t processing;
|
||||
bool scheduled;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -588,10 +590,13 @@ struct ss_fb {
|
||||
* This union holds all parameters per stream
|
||||
* necessary for different stream schedulers.
|
||||
*/
|
||||
union scheduling_parameters {
|
||||
struct ss_rr rr;
|
||||
struct ss_prio prio;
|
||||
struct ss_fb fb;
|
||||
struct scheduling_parameters {
|
||||
union {
|
||||
struct ss_rr rr;
|
||||
struct ss_prio prio;
|
||||
struct ss_fb fb;
|
||||
} ss;
|
||||
bool scheduled;
|
||||
};
|
||||
|
||||
/* States for outgoing streams */
|
||||
@ -604,7 +609,7 @@ union scheduling_parameters {
|
||||
/* This struct is used to track the traffic on outbound streams */
|
||||
struct sctp_stream_out {
|
||||
struct sctp_streamhead outqueue;
|
||||
union scheduling_parameters ss_params;
|
||||
struct scheduling_parameters ss_params;
|
||||
uint32_t chunks_on_queues; /* send queue and sent queue */
|
||||
#if defined(SCTP_DETAILED_STR_STATS)
|
||||
uint32_t abandoned_unsent[SCTP_PR_SCTP_MAX + 1];
|
||||
@ -731,11 +736,11 @@ struct sctp_cc_functions {
|
||||
struct sctp_ss_functions {
|
||||
void (*sctp_ss_init) (struct sctp_tcb *stcb, struct sctp_association *asoc);
|
||||
void (*sctp_ss_clear) (struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
int clear_values);
|
||||
bool clear_values);
|
||||
void (*sctp_ss_init_stream) (struct sctp_tcb *stcb, struct sctp_stream_out *strq, struct sctp_stream_out *with_strq);
|
||||
void (*sctp_ss_add_to_stream) (struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp);
|
||||
int (*sctp_ss_is_empty) (struct sctp_tcb *stcb, struct sctp_association *asoc);
|
||||
bool (*sctp_ss_is_empty) (struct sctp_tcb *stcb, struct sctp_association *asoc);
|
||||
void (*sctp_ss_remove_from_stream) (struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp);
|
||||
struct sctp_stream_out *(*sctp_ss_select_stream) (struct sctp_tcb *stcb,
|
||||
@ -748,7 +753,7 @@ struct sctp_stream_out *(*sctp_ss_select_stream) (struct sctp_tcb *stcb,
|
||||
struct sctp_stream_out *strq, uint16_t *value);
|
||||
int (*sctp_ss_set_value) (struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_stream_out *strq, uint16_t value);
|
||||
int (*sctp_ss_is_user_msgs_incomplete) (struct sctp_tcb *stcb, struct sctp_association *asoc);
|
||||
bool (*sctp_ss_is_user_msgs_incomplete) (struct sctp_tcb *stcb, struct sctp_association *asoc);
|
||||
};
|
||||
|
||||
/* used to save ASCONF chunks for retransmission */
|
||||
|
@ -4043,7 +4043,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
SCTP_FIND_STCB(inp, stcb, av->assoc_id);
|
||||
if (stcb) {
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 1);
|
||||
stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, true);
|
||||
stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value];
|
||||
stcb->asoc.stream_scheduling_module = av->assoc_value;
|
||||
stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc);
|
||||
@ -4066,7 +4066,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
|
||||
LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
|
||||
SCTP_TCB_LOCK(stcb);
|
||||
SCTP_TCB_SEND_LOCK(stcb);
|
||||
stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 1);
|
||||
stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, true);
|
||||
stcb->asoc.ss_functions = sctp_ss_functions[av->assoc_value];
|
||||
stcb->asoc.stream_scheduling_module = av->assoc_value;
|
||||
stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user