Thread (30 messages) flat view 30 messages, 4 authors, 2021-03-10

Re: [Patch bpf-next v2 2/9] sock: introduce sk_prot->update_proto()

From: Lorenz Bauer <hidden>
Date: 2021-03-03 03:55:37
Also in: bpf

On Tue, 2 Mar 2021 at 02:37, Cong Wang [off-list ref] wrote:

...
quoted hunk ↗ jump to hunk
@@ -350,25 +351,12 @@ static inline void sk_psock_cork_free(struct sk_psock *psock)
        }
 }

-static inline void sk_psock_update_proto(struct sock *sk,
-                                        struct sk_psock *psock,
-                                        struct proto *ops)
-{
-       /* Pairs with lockless read in sk_clone_lock() */
-       WRITE_ONCE(sk->sk_prot, ops);
-}
-
 static inline void sk_psock_restore_proto(struct sock *sk,
                                          struct sk_psock *psock)
 {
        sk->sk_prot->unhash = psock->saved_unhash;
Not related to your patch set, but why do an extra restore of
sk_prot->unhash here? At this point sk->sk_prot is one of our tcp_bpf
/ udp_bpf protos, so overwriting that seems wrong?
quoted hunk ↗ jump to hunk
-       if (inet_csk_has_ulp(sk)) {
-               tcp_update_ulp(sk, psock->sk_proto, psock->saved_write_space);
-       } else {
-               sk->sk_write_space = psock->saved_write_space;
-               /* Pairs with lockless read in sk_clone_lock() */
-               WRITE_ONCE(sk->sk_prot, psock->sk_proto);
-       }
+       if (psock->saved_update_proto)
+               psock->saved_update_proto(sk, true);
 }

 static inline void sk_psock_set_state(struct sk_psock *psock,
diff --git a/include/net/sock.h b/include/net/sock.h
index 636810ddcd9b..0e8577c917e8 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1184,6 +1184,9 @@ struct proto {
        void                    (*unhash)(struct sock *sk);
        void                    (*rehash)(struct sock *sk);
        int                     (*get_port)(struct sock *sk, unsigned short snum);
+#ifdef CONFIG_BPF_SYSCALL
+       int                     (*update_proto)(struct sock *sk, bool restore);
Kind of a nit, but this name suggests that the callback is a lot more
generic than it really is. The only thing you can use it for is to
prep the socket to be sockmap ready since we hardwire sockmap_unhash,
etc. It's also not at all clear that this only works if sk has an
sk_psock associated with it. Calling it without one would crash the
kernel since the update_proto functions don't check for !sk_psock.

Might as well call it install_sockmap_hooks or something and have a
valid sk_psock be passed in to the callback. Additionally, I'd prefer
if the function returned a struct proto * like it does at the moment.
That way we keep sk->sk_prot manipulation confined to the sockmap code
and don't have to copy paste it into every proto.
quoted hunk ↗ jump to hunk
diff --git a/net/core/sock_map.c b/net/core/sock_map.c
index 3bddd9dd2da2..13d2af5bb81c 100644
--- a/net/core/sock_map.c
+++ b/net/core/sock_map.c
@@ -184,26 +184,10 @@ static void sock_map_unref(struct sock *sk, void *link_raw)

 static int sock_map_init_proto(struct sock *sk, struct sk_psock *psock)
 {
-       struct proto *prot;
-
-       switch (sk->sk_type) {
-       case SOCK_STREAM:
-               prot = tcp_bpf_get_proto(sk, psock);
-               break;
-
-       case SOCK_DGRAM:
-               prot = udp_bpf_get_proto(sk, psock);
-               break;
-
-       default:
+       if (!sk->sk_prot->update_proto)
                return -EINVAL;
-       }
-
-       if (IS_ERR(prot))
-               return PTR_ERR(prot);
-
-       sk_psock_update_proto(sk, psock, prot);
-       return 0;
+       psock->saved_update_proto = sk->sk_prot->update_proto;
+       return sk->sk_prot->update_proto(sk, false);
I think reads / writes from sk_prot need READ_ONCE / WRITE_ONCE. We've
not been diligent about this so far, but I think it makes sense to be
careful in new code.

-- 
Lorenz Bauer  |  Systems Engineer
6th Floor, County Hall/The Riverside Building, SE1 7PB, UK

www.cloudflare.com
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help