On Thu, Jan 09, 2020 at 10:22 PM CET, John Fastabend wrote: > Jakub Sitnicki wrote: >> On Wed, Jan 08, 2020 at 10:14 PM CET, John Fastabend wrote: >> > When sockmap sock with TLS enabled is removed we cleanup bpf/psock state >> > and call tcp_update_ulp() to push updates to TLS ULP on top. However, we >> > don't push the write_space callback up and instead simply overwrite the >> > op with the psock stored previous op. This may or may not be correct so >> > to ensure we don't overwrite the TLS write space hook pass this field to >> > the ULP and have it fixup the ctx. >> > >> > This completes a previous fix that pushed the ops through to the ULP >> > but at the time missed doing this for write_space, presumably because >> > write_space TLS hook was added around the same time. >> > >> > Fixes: 95fa145479fbc ("bpf: sockmap/tls, close can race with map free") >> > Signed-off-by: John Fastabend <john.fastabend@xxxxxxxxx> >> > --- >> > include/linux/skmsg.h | 12 ++++++++---- >> > include/net/tcp.h | 6 ++++-- >> > net/ipv4/tcp_ulp.c | 6 ++++-- >> > net/tls/tls_main.c | 10 +++++++--- >> > 4 files changed, 23 insertions(+), 11 deletions(-) >> > >> > diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h >> > index b6afe01f8592..14d61bba0b79 100644 >> > --- a/include/linux/skmsg.h >> > +++ b/include/linux/skmsg.h >> > @@ -359,17 +359,21 @@ static inline void sk_psock_restore_proto(struct sock *sk, >> > struct sk_psock *psock) >> > { >> > sk->sk_prot->unhash = psock->saved_unhash; >> > - sk->sk_write_space = psock->saved_write_space; >> > >> > if (psock->sk_proto) { >> > struct inet_connection_sock *icsk = inet_csk(sk); >> > bool has_ulp = !!icsk->icsk_ulp_data; >> > >> > - if (has_ulp) >> > - tcp_update_ulp(sk, psock->sk_proto); >> > - else >> > + if (has_ulp) { >> > + tcp_update_ulp(sk, psock->sk_proto, >> > + psock->saved_write_space); >> > + } else { >> > sk->sk_prot = psock->sk_proto; >> > + sk->sk_write_space = psock->saved_write_space; >> > + } >> >> I'm wondering if we need the above fallback branch for no-ULP case? >> tcp_update_ulp repeats the ULP check and has the same fallback. Perhaps >> it can be reduced to: >> >> if (psock->sk_proto) { >> tcp_update_ulp(sk, psock->sk_proto, psock->saved_write_space); >> psock->sk_proto = NULL; >> } else { >> sk->sk_write_space = psock->saved_write_space; >> } > > Yeah that is a bit nicer. How about pushing it for bpf-next? I'm not > sure its needed for bpf and the patch I pushed is the minimal change > needed for the fix and pushes the saved_write_space around. Yeah, this is bpf-next material. >> Then there's the question if it's okay to leave psock->sk_proto set and >> potentially restore it more than once? Reading tls_update, the only user >> ULP 'update' callback, it looks fine. >> >> Can sk_psock_restore_proto be as simple as: >> >> static inline void sk_psock_restore_proto(struct sock *sk, >> struct sk_psock *psock) >> { >> tcp_update_ulp(sk, psock->sk_proto, psock->saved_write_space); >> } >> >> ... or am I missing something? > > I think that is good. bpf-next? Great, I needed to confirm my thinking. >> Asking becuase I have a patch [0] like this in the queue and haven't >> seen issues with it during testing. > > +1 Want to push it after we sort out this series? I've actually pushed it earlier today with next iteration of "Extend SOCKMAP to store listening sockets" to collect feedback [0]. I will adapt it once it shows up in bpf-next (or split it out and submit separately). -jkbs [0] https://lore.kernel.org/bpf/20200110105027.257877-1-jakub@xxxxxxxxxxxxxx/