All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net 0/3] a couple of fixes for chunks abandoned in prsctp
@ 2017-11-25 13:18 ` Xin Long
  0 siblings, 0 replies; 18+ messages in thread
From: Xin Long @ 2017-11-25 13:18 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: davem, Marcelo Ricardo Leitner, Neil Horman

Now when abandoning chunks in prsctp, it doesn't consider for frags in
one msg, which would cause peer can never receive the whole frags for
one msg to get them reassembled, these pieces of this msg will stay in
the reasm queue forever and block the following chunks' receiving.

This patchset is to fix them in patch 2 and 3, and also fix another
issue for prsctp in patch 1.

Xin Long (3):
  sctp: only update outstanding_bytes for transmitted queue when doing
    prsctp_prune
  sctp: abandon the whole msg if one part of a fragmented message is
    abandoned
  sctp: do not abandon the other frags in unsent outq if one msg has
    outstanding frags

 include/net/sctp/structs.h |  3 ++-
 net/sctp/chunk.c           | 11 +++++++++++
 net/sctp/outqueue.c        | 19 +++++++++++++------
 3 files changed, 26 insertions(+), 7 deletions(-)

-- 
2.1.0

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH net 0/3] a couple of fixes for chunks abandoned in prsctp
@ 2017-11-25 13:18 ` Xin Long
  0 siblings, 0 replies; 18+ messages in thread
From: Xin Long @ 2017-11-25 13:18 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: davem, Marcelo Ricardo Leitner, Neil Horman

Now when abandoning chunks in prsctp, it doesn't consider for frags in
one msg, which would cause peer can never receive the whole frags for
one msg to get them reassembled, these pieces of this msg will stay in
the reasm queue forever and block the following chunks' receiving.

This patchset is to fix them in patch 2 and 3, and also fix another
issue for prsctp in patch 1.

Xin Long (3):
  sctp: only update outstanding_bytes for transmitted queue when doing
    prsctp_prune
  sctp: abandon the whole msg if one part of a fragmented message is
    abandoned
  sctp: do not abandon the other frags in unsent outq if one msg has
    outstanding frags

 include/net/sctp/structs.h |  3 ++-
 net/sctp/chunk.c           | 11 +++++++++++
 net/sctp/outqueue.c        | 19 +++++++++++++------
 3 files changed, 26 insertions(+), 7 deletions(-)

-- 
2.1.0


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH net 1/3] sctp: only update outstanding_bytes for transmitted queue when doing prsctp_prune
  2017-11-25 13:18 ` Xin Long
@ 2017-11-25 13:18   ` Xin Long
  -1 siblings, 0 replies; 18+ messages in thread
From: Xin Long @ 2017-11-25 13:18 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: davem, Marcelo Ricardo Leitner, Neil Horman

Now outstanding_bytes is only increased when appending chunks into one
packet and sending it at 1st time, while decreased when it is about to
move into retransmit queue. It means outstanding_bytes value is already
decreased for all chunks in retransmit queue.

However sctp_prsctp_prune_sent is a common function to check the chunks
in both transmitted and retransmit queue, it decrease outstanding_bytes
when moving a chunk into abandoned queue from either of them.

It could cause outstanding_bytes underflow, as it also decreases it's
value for the chunks in retransmit queue.

This patch fixes it by only updating outstanding_bytes for transmitted
queue when pruning queues for prsctp prio policy, the same fix is also
needed in sctp_check_transmitted.

Fixes: 8dbdf1f5b09c ("sctp: implement prsctp PRIO policy")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/sctp/outqueue.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 4db012a..7029f8b 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -377,7 +377,8 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,
 		asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
 		streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
 
-		if (!chk->tsn_gap_acked) {
+		if (queue != &asoc->outqueue.retransmit &&
+		    !chk->tsn_gap_acked) {
 			if (chk->transport)
 				chk->transport->flight_size -=
 						sctp_data_size(chk);
@@ -1434,7 +1435,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
 			/* If this chunk has not been acked, stop
 			 * considering it as 'outstanding'.
 			 */
-			if (!tchunk->tsn_gap_acked) {
+			if (transmitted_queue != &q->retransmit &&
+			    !tchunk->tsn_gap_acked) {
 				if (tchunk->transport)
 					tchunk->transport->flight_size -=
 							sctp_data_size(tchunk);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net 1/3] sctp: only update outstanding_bytes for transmitted queue when doing prsctp_prune
@ 2017-11-25 13:18   ` Xin Long
  0 siblings, 0 replies; 18+ messages in thread
From: Xin Long @ 2017-11-25 13:18 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: davem, Marcelo Ricardo Leitner, Neil Horman

Now outstanding_bytes is only increased when appending chunks into one
packet and sending it at 1st time, while decreased when it is about to
move into retransmit queue. It means outstanding_bytes value is already
decreased for all chunks in retransmit queue.

However sctp_prsctp_prune_sent is a common function to check the chunks
in both transmitted and retransmit queue, it decrease outstanding_bytes
when moving a chunk into abandoned queue from either of them.

It could cause outstanding_bytes underflow, as it also decreases it's
value for the chunks in retransmit queue.

This patch fixes it by only updating outstanding_bytes for transmitted
queue when pruning queues for prsctp prio policy, the same fix is also
needed in sctp_check_transmitted.

Fixes: 8dbdf1f5b09c ("sctp: implement prsctp PRIO policy")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/sctp/outqueue.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 4db012a..7029f8b 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -377,7 +377,8 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,
 		asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
 		streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
 
-		if (!chk->tsn_gap_acked) {
+		if (queue != &asoc->outqueue.retransmit &&
+		    !chk->tsn_gap_acked) {
 			if (chk->transport)
 				chk->transport->flight_size - 						sctp_data_size(chk);
@@ -1434,7 +1435,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
 			/* If this chunk has not been acked, stop
 			 * considering it as 'outstanding'.
 			 */
-			if (!tchunk->tsn_gap_acked) {
+			if (transmitted_queue != &q->retransmit &&
+			    !tchunk->tsn_gap_acked) {
 				if (tchunk->transport)
 					tchunk->transport->flight_size - 							sctp_data_size(tchunk);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net 2/3] sctp: abandon the whole msg if one part of a fragmented message is abandoned
  2017-11-25 13:18   ` Xin Long
@ 2017-11-25 13:18     ` Xin Long
  -1 siblings, 0 replies; 18+ messages in thread
From: Xin Long @ 2017-11-25 13:18 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: davem, Marcelo Ricardo Leitner, Neil Horman

As rfc3758#section-3.1 demands:

   A3) When a TSN is "abandoned", if it is part of a fragmented message,
       all other TSN's within that fragmented message MUST be abandoned
       at the same time.

Besides, if it couldn't handle this, the rest frags would never get
assembled in peer side.

This patch supports it by adding abandoned flag in sctp_datamsg, when
one chunk is being abandoned, set chunk->msg->abandoned as well. Next
time when checking for abandoned, go checking chunk->msg->abandoned
first.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/structs.h |  3 ++-
 net/sctp/chunk.c           |  7 +++++++
 net/sctp/outqueue.c        | 12 ++++++++----
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 16f949e..2f8f93d 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -503,7 +503,8 @@ struct sctp_datamsg {
 	/* Did the messenge fail to send? */
 	int send_error;
 	u8 send_failed:1,
-	   can_delay;	    /* should this message be Nagle delayed */
+	   can_delay:1,	/* should this message be Nagle delayed */
+	   abandoned:1;	/* should this message be abandoned */
 };
 
 struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 7b261af..9213805 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -53,6 +53,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg)
 	msg->send_failed = 0;
 	msg->send_error = 0;
 	msg->can_delay = 1;
+	msg->abandoned = 0;
 	msg->expires_at = 0;
 	INIT_LIST_HEAD(&msg->chunks);
 }
@@ -304,6 +305,9 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 	if (!chunk->asoc->peer.prsctp_capable)
 		return 0;
 
+	if (chunk->msg->abandoned)
+		return 1;
+
 	if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
 	    time_after(jiffies, chunk->msg->expires_at)) {
 		struct sctp_stream_out *streamout =
@@ -316,6 +320,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 			chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
 			streamout->ext->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
 		}
+		chunk->msg->abandoned = 1;
 		return 1;
 	} else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
 		   chunk->sent_count > chunk->sinfo.sinfo_timetolive) {
@@ -324,10 +329,12 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 
 		chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
 		streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
+		chunk->msg->abandoned = 1;
 		return 1;
 	} else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) &&
 		   chunk->msg->expires_at &&
 		   time_after(jiffies, chunk->msg->expires_at)) {
+		chunk->msg->abandoned = 1;
 		return 1;
 	}
 	/* PRIO policy is processed by sendmsg, not here */
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 7029f8b..4ab164b 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,
 	list_for_each_entry_safe(chk, temp, queue, transmitted_list) {
 		struct sctp_stream_out *streamout;
 
-		if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
-		    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
+		if (!chk->msg->abandoned &&
+		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
+		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
 			continue;
 
+		chk->msg->abandoned = 1;
 		list_del_init(&chk->transmitted_list);
 		sctp_insert_list(&asoc->outqueue.abandoned,
 				 &chk->transmitted_list);
@@ -404,10 +406,12 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
 	q->sched->unsched_all(&asoc->stream);
 
 	list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
-		if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
-		    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
+		if (!chk->msg->abandoned &&
+		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
+		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
 			continue;
 
+		chk->msg->abandoned = 1;
 		sctp_sched_dequeue_common(q, chk);
 		asoc->sent_cnt_removable--;
 		asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net 2/3] sctp: abandon the whole msg if one part of a fragmented message is abandoned
@ 2017-11-25 13:18     ` Xin Long
  0 siblings, 0 replies; 18+ messages in thread
From: Xin Long @ 2017-11-25 13:18 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: davem, Marcelo Ricardo Leitner, Neil Horman

As rfc3758#section-3.1 demands:

   A3) When a TSN is "abandoned", if it is part of a fragmented message,
       all other TSN's within that fragmented message MUST be abandoned
       at the same time.

Besides, if it couldn't handle this, the rest frags would never get
assembled in peer side.

This patch supports it by adding abandoned flag in sctp_datamsg, when
one chunk is being abandoned, set chunk->msg->abandoned as well. Next
time when checking for abandoned, go checking chunk->msg->abandoned
first.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/structs.h |  3 ++-
 net/sctp/chunk.c           |  7 +++++++
 net/sctp/outqueue.c        | 12 ++++++++----
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 16f949e..2f8f93d 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -503,7 +503,8 @@ struct sctp_datamsg {
 	/* Did the messenge fail to send? */
 	int send_error;
 	u8 send_failed:1,
-	   can_delay;	    /* should this message be Nagle delayed */
+	   can_delay:1,	/* should this message be Nagle delayed */
+	   abandoned:1;	/* should this message be abandoned */
 };
 
 struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 7b261af..9213805 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -53,6 +53,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg)
 	msg->send_failed = 0;
 	msg->send_error = 0;
 	msg->can_delay = 1;
+	msg->abandoned = 0;
 	msg->expires_at = 0;
 	INIT_LIST_HEAD(&msg->chunks);
 }
@@ -304,6 +305,9 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 	if (!chunk->asoc->peer.prsctp_capable)
 		return 0;
 
+	if (chunk->msg->abandoned)
+		return 1;
+
 	if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
 	    time_after(jiffies, chunk->msg->expires_at)) {
 		struct sctp_stream_out *streamout @@ -316,6 +320,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 			chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
 			streamout->ext->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
 		}
+		chunk->msg->abandoned = 1;
 		return 1;
 	} else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
 		   chunk->sent_count > chunk->sinfo.sinfo_timetolive) {
@@ -324,10 +329,12 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 
 		chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
 		streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
+		chunk->msg->abandoned = 1;
 		return 1;
 	} else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) &&
 		   chunk->msg->expires_at &&
 		   time_after(jiffies, chunk->msg->expires_at)) {
+		chunk->msg->abandoned = 1;
 		return 1;
 	}
 	/* PRIO policy is processed by sendmsg, not here */
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 7029f8b..4ab164b 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,
 	list_for_each_entry_safe(chk, temp, queue, transmitted_list) {
 		struct sctp_stream_out *streamout;
 
-		if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
-		    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
+		if (!chk->msg->abandoned &&
+		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
+		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
 			continue;
 
+		chk->msg->abandoned = 1;
 		list_del_init(&chk->transmitted_list);
 		sctp_insert_list(&asoc->outqueue.abandoned,
 				 &chk->transmitted_list);
@@ -404,10 +406,12 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
 	q->sched->unsched_all(&asoc->stream);
 
 	list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
-		if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
-		    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
+		if (!chk->msg->abandoned &&
+		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
+		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
 			continue;
 
+		chk->msg->abandoned = 1;
 		sctp_sched_dequeue_common(q, chk);
 		asoc->sent_cnt_removable--;
 		asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net 3/3] sctp: do not abandon the other frags in unsent outq if one msg has outstanding frags
  2017-11-25 13:18     ` Xin Long
@ 2017-11-25 13:18       ` Xin Long
  -1 siblings, 0 replies; 18+ messages in thread
From: Xin Long @ 2017-11-25 13:18 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: davem, Marcelo Ricardo Leitner, Neil Horman

Now for the abandoned chunks in unsent outq, it would just free the chunks.
Because no tsn is assigned to them yet, there's no need to send fwd tsn to
peer, unlike for the abandoned chunks in sent outq.

The problem is when parts of the msg have been sent and the other frags
are still in unsent outq, if they are abandoned/dropped, the peer would
never get this msg reassembled.

So these frags in unsent outq can't be dropped if this msg already has
outstanding frags.

This patch does the check in sctp_chunk_abandoned and
sctp_prsctp_prune_unsent.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/sctp/chunk.c    | 4 ++++
 net/sctp/outqueue.c | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 9213805..7f8baa4 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -308,6 +308,10 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 	if (chunk->msg->abandoned)
 		return 1;
 
+	if (!chunk->has_tsn &&
+	    !(chunk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG))
+		return 0;
+
 	if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
 	    time_after(jiffies, chunk->msg->expires_at)) {
 		struct sctp_stream_out *streamout =
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 4ab164b..7d67fee 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -407,7 +407,8 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
 
 	list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
 		if (!chk->msg->abandoned &&
-		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
+		    (!(chk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG) ||
+		     !SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
 		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
 			continue;
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH net 3/3] sctp: do not abandon the other frags in unsent outq if one msg has outstanding frags
@ 2017-11-25 13:18       ` Xin Long
  0 siblings, 0 replies; 18+ messages in thread
From: Xin Long @ 2017-11-25 13:18 UTC (permalink / raw)
  To: network dev, linux-sctp; +Cc: davem, Marcelo Ricardo Leitner, Neil Horman

Now for the abandoned chunks in unsent outq, it would just free the chunks.
Because no tsn is assigned to them yet, there's no need to send fwd tsn to
peer, unlike for the abandoned chunks in sent outq.

The problem is when parts of the msg have been sent and the other frags
are still in unsent outq, if they are abandoned/dropped, the peer would
never get this msg reassembled.

So these frags in unsent outq can't be dropped if this msg already has
outstanding frags.

This patch does the check in sctp_chunk_abandoned and
sctp_prsctp_prune_unsent.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/sctp/chunk.c    | 4 ++++
 net/sctp/outqueue.c | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
index 9213805..7f8baa4 100644
--- a/net/sctp/chunk.c
+++ b/net/sctp/chunk.c
@@ -308,6 +308,10 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
 	if (chunk->msg->abandoned)
 		return 1;
 
+	if (!chunk->has_tsn &&
+	    !(chunk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG))
+		return 0;
+
 	if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
 	    time_after(jiffies, chunk->msg->expires_at)) {
 		struct sctp_stream_out *streamout diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 4ab164b..7d67fee 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -407,7 +407,8 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
 
 	list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
 		if (!chk->msg->abandoned &&
-		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
+		    (!(chk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG) ||
+		     !SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
 		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
 			continue;
 
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH net 1/3] sctp: only update outstanding_bytes for transmitted queue when doing prsctp_prune
  2017-11-25 13:18   ` Xin Long
@ 2017-11-27 12:26     ` Marcelo Ricardo Leitner
  -1 siblings, 0 replies; 18+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-11-27 12:26 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, davem, Neil Horman

On Sat, Nov 25, 2017 at 09:18:34PM +0800, Xin Long wrote:
> Now outstanding_bytes is only increased when appending chunks into one
> packet and sending it at 1st time, while decreased when it is about to
> move into retransmit queue. It means outstanding_bytes value is already
> decreased for all chunks in retransmit queue.
> 
> However sctp_prsctp_prune_sent is a common function to check the chunks
> in both transmitted and retransmit queue, it decrease outstanding_bytes
> when moving a chunk into abandoned queue from either of them.
> 
> It could cause outstanding_bytes underflow, as it also decreases it's
> value for the chunks in retransmit queue.
> 
> This patch fixes it by only updating outstanding_bytes for transmitted
> queue when pruning queues for prsctp prio policy, the same fix is also
> needed in sctp_check_transmitted.
> 
> Fixes: 8dbdf1f5b09c ("sctp: implement prsctp PRIO policy")
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>

> ---
>  net/sctp/outqueue.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
> index 4db012a..7029f8b 100644
> --- a/net/sctp/outqueue.c
> +++ b/net/sctp/outqueue.c
> @@ -377,7 +377,8 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,
>  		asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
>  		streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
>  
> -		if (!chk->tsn_gap_acked) {
> +		if (queue != &asoc->outqueue.retransmit &&
> +		    !chk->tsn_gap_acked) {
>  			if (chk->transport)
>  				chk->transport->flight_size -=
>  						sctp_data_size(chk);
> @@ -1434,7 +1435,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
>  			/* If this chunk has not been acked, stop
>  			 * considering it as 'outstanding'.
>  			 */
> -			if (!tchunk->tsn_gap_acked) {
> +			if (transmitted_queue != &q->retransmit &&
> +			    !tchunk->tsn_gap_acked) {
>  				if (tchunk->transport)
>  					tchunk->transport->flight_size -=
>  							sctp_data_size(tchunk);
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH net 1/3] sctp: only update outstanding_bytes for transmitted queue when doing prsctp_prun
@ 2017-11-27 12:26     ` Marcelo Ricardo Leitner
  0 siblings, 0 replies; 18+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-11-27 12:26 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, davem, Neil Horman

On Sat, Nov 25, 2017 at 09:18:34PM +0800, Xin Long wrote:
> Now outstanding_bytes is only increased when appending chunks into one
> packet and sending it at 1st time, while decreased when it is about to
> move into retransmit queue. It means outstanding_bytes value is already
> decreased for all chunks in retransmit queue.
> 
> However sctp_prsctp_prune_sent is a common function to check the chunks
> in both transmitted and retransmit queue, it decrease outstanding_bytes
> when moving a chunk into abandoned queue from either of them.
> 
> It could cause outstanding_bytes underflow, as it also decreases it's
> value for the chunks in retransmit queue.
> 
> This patch fixes it by only updating outstanding_bytes for transmitted
> queue when pruning queues for prsctp prio policy, the same fix is also
> needed in sctp_check_transmitted.
> 
> Fixes: 8dbdf1f5b09c ("sctp: implement prsctp PRIO policy")
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>

> ---
>  net/sctp/outqueue.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
> index 4db012a..7029f8b 100644
> --- a/net/sctp/outqueue.c
> +++ b/net/sctp/outqueue.c
> @@ -377,7 +377,8 @@ static int sctp_prsctp_prune_sent(struct sctp_association *asoc,
>  		asoc->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
>  		streamout->ext->abandoned_sent[SCTP_PR_INDEX(PRIO)]++;
>  
> -		if (!chk->tsn_gap_acked) {
> +		if (queue != &asoc->outqueue.retransmit &&
> +		    !chk->tsn_gap_acked) {
>  			if (chk->transport)
>  				chk->transport->flight_size ->  						sctp_data_size(chk);
> @@ -1434,7 +1435,8 @@ static void sctp_check_transmitted(struct sctp_outq *q,
>  			/* If this chunk has not been acked, stop
>  			 * considering it as 'outstanding'.
>  			 */
> -			if (!tchunk->tsn_gap_acked) {
> +			if (transmitted_queue != &q->retransmit &&
> +			    !tchunk->tsn_gap_acked) {
>  				if (tchunk->transport)
>  					tchunk->transport->flight_size ->  							sctp_data_size(tchunk);
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH net 2/3] sctp: abandon the whole msg if one part of a fragmented message is abandoned
  2017-11-25 13:18     ` Xin Long
@ 2017-11-27 12:26       ` Marcelo Ricardo Leitner
  -1 siblings, 0 replies; 18+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-11-27 12:26 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, davem, Neil Horman

On Sat, Nov 25, 2017 at 09:18:35PM +0800, Xin Long wrote:
> As rfc3758#section-3.1 demands:
> 
>    A3) When a TSN is "abandoned", if it is part of a fragmented message,
>        all other TSN's within that fragmented message MUST be abandoned
>        at the same time.
> 
> Besides, if it couldn't handle this, the rest frags would never get
> assembled in peer side.
> 
> This patch supports it by adding abandoned flag in sctp_datamsg, when
> one chunk is being abandoned, set chunk->msg->abandoned as well. Next
> time when checking for abandoned, go checking chunk->msg->abandoned
> first.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>

> ---
>  include/net/sctp/structs.h |  3 ++-
>  net/sctp/chunk.c           |  7 +++++++
>  net/sctp/outqueue.c        | 12 ++++++++----
>  3 files changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> index 16f949e..2f8f93d 100644
> --- a/include/net/sctp/structs.h
> +++ b/include/net/sctp/structs.h
> @@ -503,7 +503,8 @@ struct sctp_datamsg {
>  	/* Did the messenge fail to send? */
>  	int send_error;
>  	u8 send_failed:1,
> -	   can_delay;	    /* should this message be Nagle delayed */
> +	   can_delay:1,	/* should this message be Nagle delayed */
> +	   abandoned:1;	/* should this message be abandoned */
>  };
>  
>  struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
> diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> index 7b261af..9213805 100644
> --- a/net/sctp/chunk.c
> +++ b/net/sctp/chunk.c
> @@ -53,6 +53,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg)
>  	msg->send_failed = 0;
>  	msg->send_error = 0;
>  	msg->can_delay = 1;
> +	msg->abandoned = 0;
>  	msg->expires_at = 0;
>  	INIT_LIST_HEAD(&msg->chunks);
>  }
> @@ -304,6 +305,9 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
>  	if (!chunk->asoc->peer.prsctp_capable)
>  		return 0;
>  
> +	if (chunk->msg->abandoned)
> +		return 1;
> +
>  	if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
>  	    time_after(jiffies, chunk->msg->expires_at)) {
>  		struct sctp_stream_out *streamout =
> @@ -316,6 +320,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
>  			chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
>  			streamout->ext->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
>  		}
> +		chunk->msg->abandoned = 1;
>  		return 1;
>  	} else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
>  		   chunk->sent_count > chunk->sinfo.sinfo_timetolive) {
> @@ -324,10 +329,12 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
>  
>  		chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
>  		streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
> +		chunk->msg->abandoned = 1;
>  		return 1;
>  	} else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) &&
>  		   chunk->msg->expires_at &&
>  		   time_after(jiffies, chunk->msg->expires_at)) {
> +		chunk->msg->abandoned = 1;
>  		return 1;
>  	}
>  	/* PRIO policy is processed by sendmsg, not here */
> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
> index 7029f8b..4ab164b 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,
>  	list_for_each_entry_safe(chk, temp, queue, transmitted_list) {
>  		struct sctp_stream_out *streamout;
>  
> -		if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
> -		    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
> +		if (!chk->msg->abandoned &&
> +		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
> +		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
>  			continue;
>  
> +		chk->msg->abandoned = 1;
>  		list_del_init(&chk->transmitted_list);
>  		sctp_insert_list(&asoc->outqueue.abandoned,
>  				 &chk->transmitted_list);
> @@ -404,10 +406,12 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
>  	q->sched->unsched_all(&asoc->stream);
>  
>  	list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
> -		if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
> -		    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
> +		if (!chk->msg->abandoned &&
> +		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
> +		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
>  			continue;
>  
> +		chk->msg->abandoned = 1;
>  		sctp_sched_dequeue_common(q, chk);
>  		asoc->sent_cnt_removable--;
>  		asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH net 2/3] sctp: abandon the whole msg if one part of a fragmented message is abandoned
@ 2017-11-27 12:26       ` Marcelo Ricardo Leitner
  0 siblings, 0 replies; 18+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-11-27 12:26 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, davem, Neil Horman

On Sat, Nov 25, 2017 at 09:18:35PM +0800, Xin Long wrote:
> As rfc3758#section-3.1 demands:
> 
>    A3) When a TSN is "abandoned", if it is part of a fragmented message,
>        all other TSN's within that fragmented message MUST be abandoned
>        at the same time.
> 
> Besides, if it couldn't handle this, the rest frags would never get
> assembled in peer side.
> 
> This patch supports it by adding abandoned flag in sctp_datamsg, when
> one chunk is being abandoned, set chunk->msg->abandoned as well. Next
> time when checking for abandoned, go checking chunk->msg->abandoned
> first.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>

> ---
>  include/net/sctp/structs.h |  3 ++-
>  net/sctp/chunk.c           |  7 +++++++
>  net/sctp/outqueue.c        | 12 ++++++++----
>  3 files changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> index 16f949e..2f8f93d 100644
> --- a/include/net/sctp/structs.h
> +++ b/include/net/sctp/structs.h
> @@ -503,7 +503,8 @@ struct sctp_datamsg {
>  	/* Did the messenge fail to send? */
>  	int send_error;
>  	u8 send_failed:1,
> -	   can_delay;	    /* should this message be Nagle delayed */
> +	   can_delay:1,	/* should this message be Nagle delayed */
> +	   abandoned:1;	/* should this message be abandoned */
>  };
>  
>  struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *,
> diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> index 7b261af..9213805 100644
> --- a/net/sctp/chunk.c
> +++ b/net/sctp/chunk.c
> @@ -53,6 +53,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg)
>  	msg->send_failed = 0;
>  	msg->send_error = 0;
>  	msg->can_delay = 1;
> +	msg->abandoned = 0;
>  	msg->expires_at = 0;
>  	INIT_LIST_HEAD(&msg->chunks);
>  }
> @@ -304,6 +305,9 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
>  	if (!chunk->asoc->peer.prsctp_capable)
>  		return 0;
>  
> +	if (chunk->msg->abandoned)
> +		return 1;
> +
>  	if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
>  	    time_after(jiffies, chunk->msg->expires_at)) {
>  		struct sctp_stream_out *streamout > @@ -316,6 +320,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
>  			chunk->asoc->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
>  			streamout->ext->abandoned_unsent[SCTP_PR_INDEX(TTL)]++;
>  		}
> +		chunk->msg->abandoned = 1;
>  		return 1;
>  	} else if (SCTP_PR_RTX_ENABLED(chunk->sinfo.sinfo_flags) &&
>  		   chunk->sent_count > chunk->sinfo.sinfo_timetolive) {
> @@ -324,10 +329,12 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
>  
>  		chunk->asoc->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
>  		streamout->ext->abandoned_sent[SCTP_PR_INDEX(RTX)]++;
> +		chunk->msg->abandoned = 1;
>  		return 1;
>  	} else if (!SCTP_PR_POLICY(chunk->sinfo.sinfo_flags) &&
>  		   chunk->msg->expires_at &&
>  		   time_after(jiffies, chunk->msg->expires_at)) {
> +		chunk->msg->abandoned = 1;
>  		return 1;
>  	}
>  	/* PRIO policy is processed by sendmsg, not here */
> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
> index 7029f8b..4ab164b 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,
>  	list_for_each_entry_safe(chk, temp, queue, transmitted_list) {
>  		struct sctp_stream_out *streamout;
>  
> -		if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
> -		    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
> +		if (!chk->msg->abandoned &&
> +		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
> +		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
>  			continue;
>  
> +		chk->msg->abandoned = 1;
>  		list_del_init(&chk->transmitted_list);
>  		sctp_insert_list(&asoc->outqueue.abandoned,
>  				 &chk->transmitted_list);
> @@ -404,10 +406,12 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
>  	q->sched->unsched_all(&asoc->stream);
>  
>  	list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
> -		if (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
> -		    chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive)
> +		if (!chk->msg->abandoned &&
> +		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
> +		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
>  			continue;
>  
> +		chk->msg->abandoned = 1;
>  		sctp_sched_dequeue_common(q, chk);
>  		asoc->sent_cnt_removable--;
>  		asoc->abandoned_unsent[SCTP_PR_INDEX(PRIO)]++;
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH net 3/3] sctp: do not abandon the other frags in unsent outq if one msg has outstanding frags
  2017-11-25 13:18       ` Xin Long
@ 2017-11-27 12:26         ` Marcelo Ricardo Leitner
  -1 siblings, 0 replies; 18+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-11-27 12:26 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, davem, Neil Horman

On Sat, Nov 25, 2017 at 09:18:36PM +0800, Xin Long wrote:
> Now for the abandoned chunks in unsent outq, it would just free the chunks.
> Because no tsn is assigned to them yet, there's no need to send fwd tsn to
> peer, unlike for the abandoned chunks in sent outq.
> 
> The problem is when parts of the msg have been sent and the other frags
> are still in unsent outq, if they are abandoned/dropped, the peer would
> never get this msg reassembled.
> 
> So these frags in unsent outq can't be dropped if this msg already has
> outstanding frags.
> 
> This patch does the check in sctp_chunk_abandoned and
> sctp_prsctp_prune_unsent.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>

> ---
>  net/sctp/chunk.c    | 4 ++++
>  net/sctp/outqueue.c | 3 ++-
>  2 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> index 9213805..7f8baa4 100644
> --- a/net/sctp/chunk.c
> +++ b/net/sctp/chunk.c
> @@ -308,6 +308,10 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
>  	if (chunk->msg->abandoned)
>  		return 1;
>  
> +	if (!chunk->has_tsn &&
> +	    !(chunk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG))
> +		return 0;
> +
>  	if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
>  	    time_after(jiffies, chunk->msg->expires_at)) {
>  		struct sctp_stream_out *streamout =
> diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
> index 4ab164b..7d67fee 100644
> --- a/net/sctp/outqueue.c
> +++ b/net/sctp/outqueue.c
> @@ -407,7 +407,8 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
>  
>  	list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
>  		if (!chk->msg->abandoned &&
> -		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
> +		    (!(chk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG) ||
> +		     !SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
>  		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
>  			continue;
>  
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH net 3/3] sctp: do not abandon the other frags in unsent outq if one msg has outstanding f
@ 2017-11-27 12:26         ` Marcelo Ricardo Leitner
  0 siblings, 0 replies; 18+ messages in thread
From: Marcelo Ricardo Leitner @ 2017-11-27 12:26 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, davem, Neil Horman

On Sat, Nov 25, 2017 at 09:18:36PM +0800, Xin Long wrote:
> Now for the abandoned chunks in unsent outq, it would just free the chunks.
> Because no tsn is assigned to them yet, there's no need to send fwd tsn to
> peer, unlike for the abandoned chunks in sent outq.
> 
> The problem is when parts of the msg have been sent and the other frags
> are still in unsent outq, if they are abandoned/dropped, the peer would
> never get this msg reassembled.
> 
> So these frags in unsent outq can't be dropped if this msg already has
> outstanding frags.
> 
> This patch does the check in sctp_chunk_abandoned and
> sctp_prsctp_prune_unsent.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>

> ---
>  net/sctp/chunk.c    | 4 ++++
>  net/sctp/outqueue.c | 3 ++-
>  2 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c
> index 9213805..7f8baa4 100644
> --- a/net/sctp/chunk.c
> +++ b/net/sctp/chunk.c
> @@ -308,6 +308,10 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk)
>  	if (chunk->msg->abandoned)
>  		return 1;
>  
> +	if (!chunk->has_tsn &&
> +	    !(chunk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG))
> +		return 0;
> +
>  	if (SCTP_PR_TTL_ENABLED(chunk->sinfo.sinfo_flags) &&
>  	    time_after(jiffies, chunk->msg->expires_at)) {
>  		struct sctp_stream_out *streamout > diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
> index 4ab164b..7d67fee 100644
> --- a/net/sctp/outqueue.c
> +++ b/net/sctp/outqueue.c
> @@ -407,7 +407,8 @@ static int sctp_prsctp_prune_unsent(struct sctp_association *asoc,
>  
>  	list_for_each_entry_safe(chk, temp, &q->out_chunk_list, list) {
>  		if (!chk->msg->abandoned &&
> -		    (!SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
> +		    (!(chk->chunk_hdr->flags & SCTP_DATA_FIRST_FRAG) ||
> +		     !SCTP_PR_PRIO_ENABLED(chk->sinfo.sinfo_flags) ||
>  		     chk->sinfo.sinfo_timetolive <= sinfo->sinfo_timetolive))
>  			continue;
>  
> -- 
> 2.1.0
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH net 0/3] a couple of fixes for chunks abandoned in prsctp
  2017-11-25 13:18 ` Xin Long
@ 2017-11-27 13:58   ` Neil Horman
  -1 siblings, 0 replies; 18+ messages in thread
From: Neil Horman @ 2017-11-27 13:58 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner

On Sat, Nov 25, 2017 at 09:18:33PM +0800, Xin Long wrote:
> Now when abandoning chunks in prsctp, it doesn't consider for frags in
> one msg, which would cause peer can never receive the whole frags for
> one msg to get them reassembled, these pieces of this msg will stay in
> the reasm queue forever and block the following chunks' receiving.
> 
> This patchset is to fix them in patch 2 and 3, and also fix another
> issue for prsctp in patch 1.
> 
> Xin Long (3):
>   sctp: only update outstanding_bytes for transmitted queue when doing
>     prsctp_prune
>   sctp: abandon the whole msg if one part of a fragmented message is
>     abandoned
>   sctp: do not abandon the other frags in unsent outq if one msg has
>     outstanding frags
> 
>  include/net/sctp/structs.h |  3 ++-
>  net/sctp/chunk.c           | 11 +++++++++++
>  net/sctp/outqueue.c        | 19 +++++++++++++------
>  3 files changed, 26 insertions(+), 7 deletions(-)
> 
> -- 
> 2.1.0
> 
> 
Series
Acked-by: Neil Horman <nhorman@tuxdriver.com>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH net 0/3] a couple of fixes for chunks abandoned in prsctp
@ 2017-11-27 13:58   ` Neil Horman
  0 siblings, 0 replies; 18+ messages in thread
From: Neil Horman @ 2017-11-27 13:58 UTC (permalink / raw)
  To: Xin Long; +Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner

On Sat, Nov 25, 2017 at 09:18:33PM +0800, Xin Long wrote:
> Now when abandoning chunks in prsctp, it doesn't consider for frags in
> one msg, which would cause peer can never receive the whole frags for
> one msg to get them reassembled, these pieces of this msg will stay in
> the reasm queue forever and block the following chunks' receiving.
> 
> This patchset is to fix them in patch 2 and 3, and also fix another
> issue for prsctp in patch 1.
> 
> Xin Long (3):
>   sctp: only update outstanding_bytes for transmitted queue when doing
>     prsctp_prune
>   sctp: abandon the whole msg if one part of a fragmented message is
>     abandoned
>   sctp: do not abandon the other frags in unsent outq if one msg has
>     outstanding frags
> 
>  include/net/sctp/structs.h |  3 ++-
>  net/sctp/chunk.c           | 11 +++++++++++
>  net/sctp/outqueue.c        | 19 +++++++++++++------
>  3 files changed, 26 insertions(+), 7 deletions(-)
> 
> -- 
> 2.1.0
> 
> 
Series
Acked-by: Neil Horman <nhorman@tuxdriver.com>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH net 0/3] a couple of fixes for chunks abandoned in prsctp
  2017-11-25 13:18 ` Xin Long
@ 2017-11-27 19:52   ` David Miller
  -1 siblings, 0 replies; 18+ messages in thread
From: David Miller @ 2017-11-27 19:52 UTC (permalink / raw)
  To: lucien.xin; +Cc: netdev, linux-sctp, marcelo.leitner, nhorman

From: Xin Long <lucien.xin@gmail.com>
Date: Sat, 25 Nov 2017 21:18:33 +0800

> Now when abandoning chunks in prsctp, it doesn't consider for frags in
> one msg, which would cause peer can never receive the whole frags for
> one msg to get them reassembled, these pieces of this msg will stay in
> the reasm queue forever and block the following chunks' receiving.
> 
> This patchset is to fix them in patch 2 and 3, and also fix another
> issue for prsctp in patch 1.

Series applied, thank you.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH net 0/3] a couple of fixes for chunks abandoned in prsctp
@ 2017-11-27 19:52   ` David Miller
  0 siblings, 0 replies; 18+ messages in thread
From: David Miller @ 2017-11-27 19:52 UTC (permalink / raw)
  To: lucien.xin; +Cc: netdev, linux-sctp, marcelo.leitner, nhorman

From: Xin Long <lucien.xin@gmail.com>
Date: Sat, 25 Nov 2017 21:18:33 +0800

> Now when abandoning chunks in prsctp, it doesn't consider for frags in
> one msg, which would cause peer can never receive the whole frags for
> one msg to get them reassembled, these pieces of this msg will stay in
> the reasm queue forever and block the following chunks' receiving.
> 
> This patchset is to fix them in patch 2 and 3, and also fix another
> issue for prsctp in patch 1.

Series applied, thank you.

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2017-11-27 19:53 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-25 13:18 [PATCH net 0/3] a couple of fixes for chunks abandoned in prsctp Xin Long
2017-11-25 13:18 ` Xin Long
2017-11-25 13:18 ` [PATCH net 1/3] sctp: only update outstanding_bytes for transmitted queue when doing prsctp_prune Xin Long
2017-11-25 13:18   ` Xin Long
2017-11-25 13:18   ` [PATCH net 2/3] sctp: abandon the whole msg if one part of a fragmented message is abandoned Xin Long
2017-11-25 13:18     ` Xin Long
2017-11-25 13:18     ` [PATCH net 3/3] sctp: do not abandon the other frags in unsent outq if one msg has outstanding frags Xin Long
2017-11-25 13:18       ` Xin Long
2017-11-27 12:26       ` Marcelo Ricardo Leitner
2017-11-27 12:26         ` [PATCH net 3/3] sctp: do not abandon the other frags in unsent outq if one msg has outstanding f Marcelo Ricardo Leitner
2017-11-27 12:26     ` [PATCH net 2/3] sctp: abandon the whole msg if one part of a fragmented message is abandoned Marcelo Ricardo Leitner
2017-11-27 12:26       ` Marcelo Ricardo Leitner
2017-11-27 12:26   ` [PATCH net 1/3] sctp: only update outstanding_bytes for transmitted queue when doing prsctp_prune Marcelo Ricardo Leitner
2017-11-27 12:26     ` [PATCH net 1/3] sctp: only update outstanding_bytes for transmitted queue when doing prsctp_prun Marcelo Ricardo Leitner
2017-11-27 13:58 ` [PATCH net 0/3] a couple of fixes for chunks abandoned in prsctp Neil Horman
2017-11-27 13:58   ` Neil Horman
2017-11-27 19:52 ` David Miller
2017-11-27 19:52   ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.