From 4d58b0c3a9bcead24d81492638f38564f48e9316 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sun, 7 Aug 2016 12:51:13 +0000 Subject: [PATCH] Remove stream queue entry consistently from wheel. While there, improve the handling of drain. MFC after: 3 days --- sys/netinet/sctp_input.c | 4 +++- sys/netinet/sctp_output.c | 6 +++--- sys/netinet/sctp_pcb.c | 5 ++--- sys/netinet/sctputil.c | 3 ++- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index c07019c965c6..8dacea7067eb 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -260,6 +260,7 @@ sctp_is_there_unsent_data(struct sctp_tcb *stcb, int so_locked } atomic_subtract_int(&stcb->asoc.stream_queue_cnt, 1); TAILQ_REMOVE(&stcb->asoc.strmout[i].outqueue, sp, next); + stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, &asoc->strmout[i], sp, 1); if (sp->net) { sctp_free_remote_addr(sp->net); sp->net = NULL; @@ -341,8 +342,9 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb) for (i = newcnt; i < asoc->pre_open_streams; i++) { outs = &asoc->strmout[i]; TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) { + atomic_subtract_int(&stcb->asoc.stream_queue_cnt, 1); TAILQ_REMOVE(&outs->outqueue, sp, next); - asoc->stream_queue_cnt--; + stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp, 1); sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb, 0, sp, SCTP_SO_NOT_LOCKED); if (sp->data) { diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index dd14e8ac42fa..a36d037f8eb1 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -7232,12 +7232,12 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, } 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); if ((strq->state == SCTP_STREAM_RESET_PENDING) && (strq->chunks_on_queues == 0) && TAILQ_EMPTY(&strq->outqueue)) { stcb->asoc.trigger_reset = 1; } - stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, strq, sp, send_lock_up); if (sp->net) { sctp_free_remote_addr(sp->net); sp->net = NULL; @@ -7661,7 +7661,6 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, } if (sp->msg_is_complete && (sp->length == 0) && (sp->sender_all_done)) { /* All done pull and kill the message */ - atomic_subtract_int(&asoc->stream_queue_cnt, 1); if (sp->put_last_out == 0) { SCTP_PRINTF("Gak, put out entire msg with NO end!-2\n"); SCTP_PRINTF("sender_done:%d len:%d msg_comp:%d put_last_out:%d send_lock:%d\n", @@ -7675,13 +7674,14 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, 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); if ((strq->state == SCTP_STREAM_RESET_PENDING) && (strq->chunks_on_queues == 0) && TAILQ_EMPTY(&strq->outqueue)) { stcb->asoc.trigger_reset = 1; } - stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, strq, sp, send_lock_up); if (sp->net) { sctp_free_remote_addr(sp->net); sp->net = NULL; diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 7351c0feaf09..90e564f07dcb 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -4978,7 +4978,9 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre outs = &asoc->strmout[i]; /* now clean up any chunks here */ TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) { + atomic_subtract_int(&asoc->stream_queue_cnt, 1); TAILQ_REMOVE(&outs->outqueue, sp, next); + stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp, 0); sctp_free_spbufspace(stcb, asoc, sp); if (sp->data) { if (so) { @@ -6869,9 +6871,6 @@ sctp_drain_mbufs(struct sctp_tcb *stcb) ctl, ctl->on_strm_q); } #endif - if (ctl->on_read_q) { - continue; - } if (SCTP_TSN_GT(ctl->sinfo_tsn, cumulative_tsn_p1)) { /* Yep it is above cum-ack */ cnt++; diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 8da4e8389773..bebf5f0cde4f 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -3907,8 +3907,9 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock, outs = &asoc->strmout[i]; /* clean up any sends there */ TAILQ_FOREACH_SAFE(sp, &outs->outqueue, next, nsp) { - asoc->stream_queue_cnt--; + atomic_subtract_int(&asoc->stream_queue_cnt, 1); TAILQ_REMOVE(&outs->outqueue, sp, next); + stcb->asoc.ss_functions.sctp_ss_remove_from_stream(stcb, asoc, outs, sp, holds_lock); sctp_free_spbufspace(stcb, asoc, sp); if (sp->data) { sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,