aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2021-09-20 22:54:13 +0000
committerMichael Tuexen <tuexen@FreeBSD.org>2021-09-20 22:54:13 +0000
commit0b79a76f848768068d409edcb36f2a58cdd17e61 (patch)
tree503c7d6fdbe6a45e72d8da280323993d04819dac /sys/netinet
parent5572fda3a2f305fc4fb4c853d8d578c13d59c1a5 (diff)
downloadsrc-0b79a76f848768068d409edcb36f2a58cdd17e61.tar.gz
src-0b79a76f848768068d409edcb36f2a58cdd17e61.zip
sctp: improve consistency when calling stream scheduler
Hold always the stcb send lock when calling sctp_ss_init() and sctp_ss_remove_from_stream(). MFC after: 1 week
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/sctp_output.c8
-rw-r--r--sys/netinet/sctp_timer.c17
-rw-r--r--sys/netinet/sctputil.c4
3 files changed, 16 insertions, 13 deletions
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 434ab7e1f8dc..27ad92527454 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -7207,13 +7207,13 @@ one_more_time:
sp->put_last_out,
send_lock_up);
}
- if ((TAILQ_NEXT(sp, next) == NULL) && (send_lock_up == 0)) {
+ if (send_lock_up == 0) {
SCTP_TCB_SEND_LOCK(stcb);
send_lock_up = 1;
}
atomic_subtract_int(&asoc->stream_queue_cnt, 1);
TAILQ_REMOVE(&strq->outqueue, sp, next);
- stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, strq, sp, send_lock_up);
+ stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, strq, sp, 1);
if ((strq->state == SCTP_STREAM_RESET_PENDING) &&
(strq->chunks_on_queues == 0) &&
TAILQ_EMPTY(&strq->outqueue)) {
@@ -7638,13 +7638,13 @@ dont_do_it:
sp->put_last_out,
send_lock_up);
}
- if ((send_lock_up == 0) && (TAILQ_NEXT(sp, next) == NULL)) {
+ if (send_lock_up == 0) {
SCTP_TCB_SEND_LOCK(stcb);
send_lock_up = 1;
}
atomic_subtract_int(&asoc->stream_queue_cnt, 1);
TAILQ_REMOVE(&strq->outqueue, sp, next);
- stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, strq, sp, send_lock_up);
+ stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, strq, sp, 1);
if ((strq->state == SCTP_STREAM_RESET_PENDING) &&
(strq->chunks_on_queues == 0) &&
TAILQ_EMPTY(&strq->outqueue)) {
diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c
index e657bc280ccc..72a0a2c32c88 100644
--- a/sys/netinet/sctp_timer.c
+++ b/sys/netinet/sctp_timer.c
@@ -1344,18 +1344,18 @@ sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
static void
-sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp,
- struct sctp_tcb *stcb)
+sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
{
struct sctp_stream_queue_pending *sp;
unsigned int i, chks_in_queue = 0;
int being_filled = 0;
- /*
- * This function is ONLY called when the send/sent queues are empty.
- */
- if ((stcb == NULL) || (inp == NULL))
- return;
+ KASSERT(inp != NULL, ("inp is NULL"));
+ KASSERT(stcb != NULL, ("stcb is NULL"));
+
+ SCTP_TCB_SEND_LOCK(stcb);
+ KASSERT(TAILQ_EMPTY(&stcb->asoc.send_queue), ("send_queue not empty"));
+ KASSERT(TAILQ_EMPTY(&stcb->asoc.sent_queue), ("sent_queue not empty"));
if (stcb->asoc.sent_queue_retran_cnt) {
SCTP_PRINTF("Hmm, sent_queue_retran_cnt is non-zero %d\n",
@@ -1364,7 +1364,7 @@ sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp,
}
if (stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, &stcb->asoc)) {
/* No stream scheduler information, initialize scheduler */
- stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 0);
+ stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 1);
if (!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, &stcb->asoc)) {
/* yep, we lost a stream or two */
SCTP_PRINTF("Found additional streams NOT managed by scheduler, corrected\n");
@@ -1406,6 +1406,7 @@ sctp_audit_stream_queues_for_size(struct sctp_inpcb *inp,
(u_long)stcb->asoc.total_output_queue_size);
stcb->asoc.total_output_queue_size = 0;
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
}
int
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index c6cdd3315704..a7eb50716cc9 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -1288,6 +1288,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
return (ENOMEM);
}
+ SCTP_TCB_SEND_LOCK(stcb);
for (i = 0; i < asoc->streamoutcnt; i++) {
/*
* inbound side must be set to 0xffff, also NOTE when we get
@@ -1315,7 +1316,8 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
asoc->strmout[i].last_msg_incomplete = 0;
asoc->strmout[i].state = SCTP_STREAM_OPENING;
}
- asoc->ss_functions.sctp_ss_init(stcb, asoc, 0);
+ asoc->ss_functions.sctp_ss_init(stcb, asoc, 1);
+ SCTP_TCB_SEND_UNLOCK(stcb);
/* Now the mapping array */
asoc->mapping_array_size = SCTP_INITIAL_MAPPING_ARRAY;