| From foo@baz Mon Jan 18 21:18:36 PST 2016 |
| From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> |
| Date: Fri, 4 Dec 2015 15:14:04 -0200 |
| Subject: sctp: update the netstamp_needed counter when copying sockets |
| Status: RO |
| Content-Length: 2148 |
| Lines: 66 |
| |
| From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> |
| |
| [ Upstream commit 01ce63c90170283a9855d1db4fe81934dddce648 ] |
| |
| Dmitry Vyukov reported that SCTP was triggering a WARN on socket destroy |
| related to disabling sock timestamp. |
| |
| When SCTP accepts an association or peel one off, it copies sock flags |
| but forgot to call net_enable_timestamp() if a packet timestamping flag |
| was copied, leading to extra calls to net_disable_timestamp() whenever |
| such clones were closed. |
| |
| The fix is to call net_enable_timestamp() whenever we copy a sock with |
| that flag on, like tcp does. |
| |
| Reported-by: Dmitry Vyukov <dvyukov@google.com> |
| Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> |
| Acked-by: Vlad Yasevich <vyasevich@gmail.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| include/net/sock.h | 2 ++ |
| net/core/sock.c | 2 -- |
| net/sctp/socket.c | 3 +++ |
| 3 files changed, 5 insertions(+), 2 deletions(-) |
| |
| --- a/include/net/sock.h |
| +++ b/include/net/sock.h |
| @@ -672,6 +672,8 @@ enum sock_flags { |
| SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */ |
| }; |
| |
| +#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) |
| + |
| static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) |
| { |
| nsk->sk_flags = osk->sk_flags; |
| --- a/net/core/sock.c |
| +++ b/net/core/sock.c |
| @@ -419,8 +419,6 @@ static void sock_warn_obsolete_bsdism(co |
| } |
| } |
| |
| -#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE)) |
| - |
| static void sock_disable_timestamp(struct sock *sk, unsigned long flags) |
| { |
| if (sk->sk_flags & flags) { |
| --- a/net/sctp/socket.c |
| +++ b/net/sctp/socket.c |
| @@ -6969,6 +6969,9 @@ void sctp_copy_sock(struct sock *newsk, |
| newinet->mc_ttl = 1; |
| newinet->mc_index = 0; |
| newinet->mc_list = NULL; |
| + |
| + if (newsk->sk_flags & SK_FLAGS_TIMESTAMP) |
| + net_enable_timestamp(); |
| } |
| |
| static inline void sctp_copy_descendant(struct sock *sk_to, |