diff options
Diffstat (limited to 'net/sctp/outqueue.c')
-rw-r--r-- | net/sctp/outqueue.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 4db012aa25f7..7d67feeeffc1 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -364,10 +364,12 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc, | |||
364 | list_for_each_entry_safe(chk, temp, queue, transmitted_list) { | 364 | list_for_each_entry_safe(chk, temp, queue, transmitted_list) { |
365 | struct sctp_stream_out *streamout; | 365 | struct sctp_stream_out *streamout; |
366 | 366 | ||
367 | if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || | 367 | if (!chk->msg->abandoned && |
368 | chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive) | 368 | (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || |
369 | chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)) | ||
369 | continue; | 370 | continue; |
370 | 371 | ||
372 | chk->msg->abandoned = 1; | ||
371 | list_del_init(&chk->transmitted_list); | 373 | list_del_init(&chk->transmitted_list); |
372 | sctp_insert_list(&asoc->outqueue.abandoned, | 374 | sctp_insert_list(&asoc->outqueue.abandoned, |
373 | &chk->transmitted_list); | 375 | &chk->transmitted_list); |
@@ -377,7 +379,8 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc, | |||
377 | asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; | 379 | asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; |
378 | streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; | 380 | streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++; |
379 | 381 | ||
380 | if (!chk->tsn_gap_acked) { | 382 | if (queue != &asoc->outqueue.retransmit && |
383 | !chk->tsn_gap_acked) { | ||
381 | if (chk->transport) | 384 | if (chk->transport) |
382 | chk->transport->flight_size -= | 385 | chk->transport->flight_size -= |
383 | sctp_data_size(chk); | 386 | sctp_data_size(chk); |
@@ -403,10 +406,13 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc, | |||
403 | q->sched->unsched_all(&asoc->stream); | 406 | q->sched->unsched_all(&asoc->stream); |
404 | 407 | ||
405 | list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) { | 408 | list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) { |
406 | if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || | 409 | if (!chk->msg->abandoned && |
407 | chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive) | 410 | (!(chk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG) || |
411 | !SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) || | ||
412 | chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)) | ||
408 | continue; | 413 | continue; |
409 | 414 | ||
415 | chk->msg->abandoned = 1; | ||
410 | sctp_sched_dequeue_common(q, chk); | 416 | sctp_sched_dequeue_common(q, chk); |
411 | asoc->sent_cnt_removable--; | 417 | asoc->sent_cnt_removable--; |
412 | asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; | 418 | asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++; |
@@ -1434,7 +1440,8 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1434 | /* If this chunk has not been acked, stop | 1440 | /* If this chunk has not been acked, stop |
1435 | * considering it as 'outstanding'. | 1441 | * considering it as 'outstanding'. |
1436 | */ | 1442 | */ |
1437 | if (!tchunk->tsn_gap_acked) { | 1443 | if (transmitted_queue != &q->retransmit && |
1444 | !tchunk->tsn_gap_acked) { | ||
1438 | if (tchunk->transport) | 1445 | if (tchunk->transport) |
1439 | tchunk->transport->flight_size -= | 1446 | tchunk->transport->flight_size -= |
1440 | sctp_data_size(tchunk); | 1447 | sctp_data_size(tchunk); |