diff mbox

[PATCHv2,net] sctp: change to save MSG_MORE flag into assoc

Message ID 6faab86dbae351f6ae3994c77dbaf56ac2d98ecf.1490545275.git.lucien.xin@gmail.com
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Xin Long March 26, 2017, 4:21 p.m. UTC
David Laight noticed the support for MSG_MORE with datamsg->force_delay
didn't really work as we expected, as the first msg with MSG_MORE set
would always block the following chunks' dequeuing.

This Patch is to rewrite it by saving the MSG_MORE flag into assoc as
David Laight suggested.

asoc->force_delay is used to save MSG_MORE flag before a msg is sent.
All chunks in queue would not be sent out if asoc->force_delay is set
by the msg with MSG_MORE flag, until a new msg without MSG_MORE flag
clears asoc->force_delay.

Note that this change would not affect the flush is generated by other
triggers, like asoc->state != ESTABLISHED, queue size > pmtu etc.

v1->v2:
  Not clear asoc->force_delay after sending the msg with MSG_MORE flag.

Fixes: 4ea0c32f5f42 ("sctp: add support for MSG_MORE")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 include/net/sctp/structs.h | 2 +-
 net/sctp/output.c          | 2 +-
 net/sctp/socket.c          | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

Comments

Marcelo Ricardo Leitner March 27, 2017, 10:43 p.m. UTC | #1
On Mon, Mar 27, 2017 at 12:21:15AM +0800, Xin Long wrote:
> David Laight noticed the support for MSG_MORE with datamsg->force_delay
> didn't really work as we expected, as the first msg with MSG_MORE set
> would always block the following chunks' dequeuing.
> 
> This Patch is to rewrite it by saving the MSG_MORE flag into assoc as
> David Laight suggested.
> 
> asoc->force_delay is used to save MSG_MORE flag before a msg is sent.
> All chunks in queue would not be sent out if asoc->force_delay is set
> by the msg with MSG_MORE flag, until a new msg without MSG_MORE flag
> clears asoc->force_delay.
> 
> Note that this change would not affect the flush is generated by other
> triggers, like asoc->state != ESTABLISHED, queue size > pmtu etc.
> 
> v1->v2:
>   Not clear asoc->force_delay after sending the msg with MSG_MORE flag.
> 
> Fixes: 4ea0c32f5f42 ("sctp: add support for MSG_MORE")
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
>  include/net/sctp/structs.h | 2 +-
>  net/sctp/output.c          | 2 +-
>  net/sctp/socket.c          | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> index 592dece..8caa5ee 100644
> --- a/include/net/sctp/structs.h
> +++ b/include/net/sctp/structs.h
> @@ -499,7 +499,6 @@ struct sctp_datamsg {
>  	/* Did the messenge fail to send? */
>  	int send_error;
>  	u8 send_failed:1,
> -	   force_delay:1,
>  	   can_delay;	    /* should this message be Nagle delayed */
>  };
>  
> @@ -1878,6 +1877,7 @@ struct sctp_association {
>  
>  	__u8 need_ecne:1,	/* Need to send an ECNE Chunk? */
>  	     temp:1,		/* Is it a temporary association? */
> +	     force_delay:1,
>  	     prsctp_enable:1,
>  	     reconf_enable:1;
>  
> diff --git a/net/sctp/output.c b/net/sctp/output.c
> index 1224421..73fd178 100644
> --- a/net/sctp/output.c
> +++ b/net/sctp/output.c
> @@ -704,7 +704,7 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
>  	 */
>  
>  	if ((sctp_sk(asoc->base.sk)->nodelay || inflight == 0) &&
> -	    !chunk->msg->force_delay)
> +	    !asoc->force_delay)

How is this going to not block the flush on asoc->state != ESTABLISHED?
AFAICT b7018d0b6300 ("sctp: flush out queue once assoc state falls into
SHUTDOWN_PENDING") need to clear asoc->force_delay too.

Case I have in mind is the same old one:
- app send a msg with MSG_MORE
- close the asoc, without sending the final msg

>  		/* Nothing unacked */
>  		return SCTP_XMIT_OK;
>  
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index 0f378ea..baa269a 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -1965,7 +1965,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
>  		err = PTR_ERR(datamsg);
>  		goto out_free;
>  	}
> -	datamsg->force_delay = !!(msg->msg_flags & MSG_MORE);
> +	asoc->force_delay = !!(msg->msg_flags & MSG_MORE);
>  
>  	/* Now send the (possibly) fragmented message. */
>  	list_for_each_entry(chunk, &datamsg->chunks, frag_list) {
> -- 
> 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
>
Xin Long March 28, 2017, 4:17 a.m. UTC | #2
On Tue, Mar 28, 2017 at 6:43 AM, Marcelo Ricardo Leitner
<marcelo.leitner@gmail.com> wrote:
> On Mon, Mar 27, 2017 at 12:21:15AM +0800, Xin Long wrote:
>> David Laight noticed the support for MSG_MORE with datamsg->force_delay
>> didn't really work as we expected, as the first msg with MSG_MORE set
>> would always block the following chunks' dequeuing.
>>
>> This Patch is to rewrite it by saving the MSG_MORE flag into assoc as
>> David Laight suggested.
>>
>> asoc->force_delay is used to save MSG_MORE flag before a msg is sent.
>> All chunks in queue would not be sent out if asoc->force_delay is set
>> by the msg with MSG_MORE flag, until a new msg without MSG_MORE flag
>> clears asoc->force_delay.
>>
>> Note that this change would not affect the flush is generated by other
>> triggers, like asoc->state != ESTABLISHED, queue size > pmtu etc.
>>
>> v1->v2:
>>   Not clear asoc->force_delay after sending the msg with MSG_MORE flag.
>>
>> Fixes: 4ea0c32f5f42 ("sctp: add support for MSG_MORE")
>> Signed-off-by: Xin Long <lucien.xin@gmail.com>
>> ---
>>  include/net/sctp/structs.h | 2 +-
>>  net/sctp/output.c          | 2 +-
>>  net/sctp/socket.c          | 2 +-
>>  3 files changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
>> index 592dece..8caa5ee 100644
>> --- a/include/net/sctp/structs.h
>> +++ b/include/net/sctp/structs.h
>> @@ -499,7 +499,6 @@ struct sctp_datamsg {
>>       /* Did the messenge fail to send? */
>>       int send_error;
>>       u8 send_failed:1,
>> -        force_delay:1,
>>          can_delay;       /* should this message be Nagle delayed */
>>  };
>>
>> @@ -1878,6 +1877,7 @@ struct sctp_association {
>>
>>       __u8 need_ecne:1,       /* Need to send an ECNE Chunk? */
>>            temp:1,            /* Is it a temporary association? */
>> +          force_delay:1,
>>            prsctp_enable:1,
>>            reconf_enable:1;
>>
>> diff --git a/net/sctp/output.c b/net/sctp/output.c
>> index 1224421..73fd178 100644
>> --- a/net/sctp/output.c
>> +++ b/net/sctp/output.c
>> @@ -704,7 +704,7 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
>>        */
>>
>>       if ((sctp_sk(asoc->base.sk)->nodelay || inflight == 0) &&
>> -         !chunk->msg->force_delay)
>> +         !asoc->force_delay)
>
> How is this going to not block the flush on asoc->state != ESTABLISHED?
> AFAICT b7018d0b6300 ("sctp: flush out queue once assoc state falls into
> SHUTDOWN_PENDING") need to clear asoc->force_delay too.

It won't block  the flush on asoc->state != ESTABLISHED,
in sctp_packet_can_append_data [1].

        if ((sctp_sk(asoc->base.sk)->nodelay || inflight == 0) &&
            !chunk->msg->force_delay)
                /* Nothing unacked */
                return SCTP_XMIT_OK;

        if (!sctp_packet_empty(packet))
                /* Append to packet */
                return SCTP_XMIT_OK;

        if (!sctp_state(asoc, ESTABLISHED)) <-----[1]
                return SCTP_XMIT_OK;



>
> Case I have in mind is the same old one:
> - app send a msg with MSG_MORE
> - close the asoc, without sending the final msg
>
>>               /* Nothing unacked */
>>               return SCTP_XMIT_OK;
>>
>> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
>> index 0f378ea..baa269a 100644
>> --- a/net/sctp/socket.c
>> +++ b/net/sctp/socket.c
>> @@ -1965,7 +1965,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
>>               err = PTR_ERR(datamsg);
>>               goto out_free;
>>       }
>> -     datamsg->force_delay = !!(msg->msg_flags & MSG_MORE);
>> +     asoc->force_delay = !!(msg->msg_flags & MSG_MORE);
>>
>>       /* Now send the (possibly) fragmented message. */
>>       list_for_each_entry(chunk, &datamsg->chunks, frag_list) {
>> --
>> 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
>>
David Laight March 28, 2017, 10:12 a.m. UTC | #3
> -----Original Message-----
> From: Xin Long [mailto:lucien.xin@gmail.com]
> Sent: 26 March 2017 17:21
> To: network dev; linux-sctp@vger.kernel.org
> Cc: davem@davemloft.net; Marcelo Ricardo Leitner; Neil Horman; David Laight
> Subject: [PATCHv2 net] sctp: change to save MSG_MORE flag into assoc
> 
> David Laight noticed the support for MSG_MORE with datamsg->force_delay
> didn't really work as we expected, as the first msg with MSG_MORE set
> would always block the following chunks' dequeuing.
> 
> This Patch is to rewrite it by saving the MSG_MORE flag into assoc as
> David Laight suggested.
> 
> asoc->force_delay is used to save MSG_MORE flag before a msg is sent.
> All chunks in queue would not be sent out if asoc->force_delay is set
> by the msg with MSG_MORE flag, until a new msg without MSG_MORE flag
> clears asoc->force_delay.
> 
> Note that this change would not affect the flush is generated by other
> triggers, like asoc->state != ESTABLISHED, queue size > pmtu etc.
> 
> v1->v2:
>   Not clear asoc->force_delay after sending the msg with MSG_MORE flag.
> 
> Fixes: 4ea0c32f5f42 ("sctp: add support for MSG_MORE")
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---

Acked-by: David Laight <david.laight@aculab.com>

I'll get around to testing it yet :-)

	David
Marcelo Ricardo Leitner March 28, 2017, 6:04 p.m. UTC | #4
On Tue, Mar 28, 2017 at 12:17:00PM +0800, Xin Long wrote:
> On Tue, Mar 28, 2017 at 6:43 AM, Marcelo Ricardo Leitner
> <marcelo.leitner@gmail.com> wrote:
> > On Mon, Mar 27, 2017 at 12:21:15AM +0800, Xin Long wrote:
> >> David Laight noticed the support for MSG_MORE with datamsg->force_delay
> >> didn't really work as we expected, as the first msg with MSG_MORE set
> >> would always block the following chunks' dequeuing.
> >>
> >> This Patch is to rewrite it by saving the MSG_MORE flag into assoc as
> >> David Laight suggested.
> >>
> >> asoc->force_delay is used to save MSG_MORE flag before a msg is sent.
> >> All chunks in queue would not be sent out if asoc->force_delay is set
> >> by the msg with MSG_MORE flag, until a new msg without MSG_MORE flag
> >> clears asoc->force_delay.
> >>
> >> Note that this change would not affect the flush is generated by other
> >> triggers, like asoc->state != ESTABLISHED, queue size > pmtu etc.
> >>
> >> v1->v2:
> >>   Not clear asoc->force_delay after sending the msg with MSG_MORE flag.
> >>
> >> Fixes: 4ea0c32f5f42 ("sctp: add support for MSG_MORE")
> >> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> >> ---
> >>  include/net/sctp/structs.h | 2 +-
> >>  net/sctp/output.c          | 2 +-
> >>  net/sctp/socket.c          | 2 +-
> >>  3 files changed, 3 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> >> index 592dece..8caa5ee 100644
> >> --- a/include/net/sctp/structs.h
> >> +++ b/include/net/sctp/structs.h
> >> @@ -499,7 +499,6 @@ struct sctp_datamsg {
> >>       /* Did the messenge fail to send? */
> >>       int send_error;
> >>       u8 send_failed:1,
> >> -        force_delay:1,
> >>          can_delay;       /* should this message be Nagle delayed */
> >>  };
> >>
> >> @@ -1878,6 +1877,7 @@ struct sctp_association {
> >>
> >>       __u8 need_ecne:1,       /* Need to send an ECNE Chunk? */
> >>            temp:1,            /* Is it a temporary association? */
> >> +          force_delay:1,
> >>            prsctp_enable:1,
> >>            reconf_enable:1;
> >>
> >> diff --git a/net/sctp/output.c b/net/sctp/output.c
> >> index 1224421..73fd178 100644
> >> --- a/net/sctp/output.c
> >> +++ b/net/sctp/output.c
> >> @@ -704,7 +704,7 @@ static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
> >>        */
> >>
> >>       if ((sctp_sk(asoc->base.sk)->nodelay || inflight == 0) &&
> >> -         !chunk->msg->force_delay)
> >> +         !asoc->force_delay)
> >
> > How is this going to not block the flush on asoc->state != ESTABLISHED?
> > AFAICT b7018d0b6300 ("sctp: flush out queue once assoc state falls into
> > SHUTDOWN_PENDING") need to clear asoc->force_delay too.
> 
> It won't block  the flush on asoc->state != ESTABLISHED,
> in sctp_packet_can_append_data [1].
> 
>         if ((sctp_sk(asoc->base.sk)->nodelay || inflight == 0) &&
>             !chunk->msg->force_delay)
>                 /* Nothing unacked */
>                 return SCTP_XMIT_OK;
> 
>         if (!sctp_packet_empty(packet))
>                 /* Append to packet */
>                 return SCTP_XMIT_OK;
> 
>         if (!sctp_state(asoc, ESTABLISHED)) <-----[1]
>                 return SCTP_XMIT_OK;

Ah yes, okay.

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

> 
> 
> 
> >
> > Case I have in mind is the same old one:
> > - app send a msg with MSG_MORE
> > - close the asoc, without sending the final msg
> >
> >>               /* Nothing unacked */
> >>               return SCTP_XMIT_OK;
> >>
> >> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> >> index 0f378ea..baa269a 100644
> >> --- a/net/sctp/socket.c
> >> +++ b/net/sctp/socket.c
> >> @@ -1965,7 +1965,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
> >>               err = PTR_ERR(datamsg);
> >>               goto out_free;
> >>       }
> >> -     datamsg->force_delay = !!(msg->msg_flags & MSG_MORE);
> >> +     asoc->force_delay = !!(msg->msg_flags & MSG_MORE);
> >>
> >>       /* Now send the (possibly) fragmented message. */
> >>       list_for_each_entry(chunk, &datamsg->chunks, frag_list) {
> >> --
> >> 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
> >>
> --
> 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
>
David Miller March 29, 2017, 12:56 a.m. UTC | #5
From: Xin Long <lucien.xin@gmail.com>
Date: Mon, 27 Mar 2017 00:21:15 +0800

> David Laight noticed the support for MSG_MORE with datamsg->force_delay
> didn't really work as we expected, as the first msg with MSG_MORE set
> would always block the following chunks' dequeuing.
> 
> This Patch is to rewrite it by saving the MSG_MORE flag into assoc as
> David Laight suggested.
> 
> asoc->force_delay is used to save MSG_MORE flag before a msg is sent.
> All chunks in queue would not be sent out if asoc->force_delay is set
> by the msg with MSG_MORE flag, until a new msg without MSG_MORE flag
> clears asoc->force_delay.
> 
> Note that this change would not affect the flush is generated by other
> triggers, like asoc->state != ESTABLISHED, queue size > pmtu etc.
> 
> v1->v2:
>   Not clear asoc->force_delay after sending the msg with MSG_MORE flag.
> 
> Fixes: 4ea0c32f5f42 ("sctp: add support for MSG_MORE")
> Signed-off-by: Xin Long <lucien.xin@gmail.com>

Applied, thanks.
diff mbox

Patch

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 592dece..8caa5ee 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -499,7 +499,6 @@  struct sctp_datamsg {
 	/* Did the messenge fail to send? */
 	int send_error;
 	u8 send_failed:1,
-	   force_delay:1,
 	   can_delay;	    /* should this message be Nagle delayed */
 };
 
@@ -1878,6 +1877,7 @@  struct sctp_association {
 
 	__u8 need_ecne:1,	/* Need to send an ECNE Chunk? */
 	     temp:1,		/* Is it a temporary association? */
+	     force_delay:1,
 	     prsctp_enable:1,
 	     reconf_enable:1;
 
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 1224421..73fd178 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -704,7 +704,7 @@  static sctp_xmit_t sctp_packet_can_append_data(struct sctp_packet *packet,
 	 */
 
 	if ((sctp_sk(asoc->base.sk)->nodelay || inflight == 0) &&
-	    !chunk->msg->force_delay)
+	    !asoc->force_delay)
 		/* Nothing unacked */
 		return SCTP_XMIT_OK;
 
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 0f378ea..baa269a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1965,7 +1965,7 @@  static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
 		err = PTR_ERR(datamsg);
 		goto out_free;
 	}
-	datamsg->force_delay = !!(msg->msg_flags & MSG_MORE);
+	asoc->force_delay = !!(msg->msg_flags & MSG_MORE);
 
 	/* Now send the (possibly) fragmented message. */
 	list_for_each_entry(chunk, &datamsg->chunks, frag_list) {