More issues with pre-blocking:

a) Need for EEOR mode to take the min of the socket buffer size and the
    add more threshold, otherwise if you are so silly as to set a send
    buf size less than the add-more you could block forever in eeor mode.

 b) We were incorrectly using the sysctl vs the calculated value. This
    causes us to block forever if the addmore theshold is larger than
    then the socket buffer size.
This commit is contained in:
Randall Stewart 2008-10-27 14:49:12 +00:00
parent 35e4161b1f
commit 73adc48f49
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=184340

View File

@ -12435,7 +12435,7 @@ sctp_lower_sosend(struct socket *so,
goto out_unlocked;
}
if (user_marks_eor) {
local_add_more = SCTP_BASE_SYSCTL(sctp_add_more_threshold);
local_add_more = min(SCTP_SB_LIMIT_SND(so), SCTP_BASE_SYSCTL(sctp_add_more_threshold));
} else {
/*-
* For non-eeor the whole message must fit in
@ -12454,9 +12454,15 @@ sctp_lower_sosend(struct socket *so,
/* No room right now ! */
SOCKBUF_LOCK(&so->so_snd);
inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk));
while ((SCTP_SB_LIMIT_SND(so) < (inqueue_bytes + SCTP_BASE_SYSCTL(sctp_add_more_threshold))) ||
((stcb->asoc.stream_queue_cnt + stcb->asoc.chunks_on_out_queue) >= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue) /* while */ )) {
while ((SCTP_SB_LIMIT_SND(so) < (inqueue_bytes + local_add_more)) ||
((stcb->asoc.stream_queue_cnt + stcb->asoc.chunks_on_out_queue) >= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue)) /* while */ ) {
SCTPDBG(SCTP_DEBUG_OUTPUT1, "pre_block limit:%d <(inq:%d + %d) || (%d+%d > %d)\n",
SCTP_SB_LIMIT_SND(so),
inqueue_bytes,
local_add_more,
stcb->asoc.stream_queue_cnt,
stcb->asoc.chunks_on_out_queue,
SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue));
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_BLK_LOGGING_ENABLE) {
sctp_log_block(SCTP_BLOCK_LOG_INTO_BLKA,
so, asoc, sndlen);