The branch main has been updated by tuexen:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=0b79a76f848768068d409edcb36f2a58cdd17e61

commit 0b79a76f848768068d409edcb36f2a58cdd17e61
Author:     Michael Tuexen <tue...@freebsd.org>
AuthorDate: 2021-09-20 22:54:13 +0000
Commit:     Michael Tuexen <tue...@freebsd.org>
CommitDate: 2021-09-20 22:54:13 +0000

    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
---
 sys/netinet/sctp_output.c |  8 ++++----
 sys/netinet/sctp_timer.c  | 17 +++++++++--------
 sys/netinet/sctputil.c    |  4 +++-
 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;
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to