From: Christoph Paasch <cpaa...@openai.com>

Add a helper to check if RFS is needed or not. Allows to make the code a
bit cleaner and the next patch to have MPTCP use this helper to decide
whether or not to iterate over the subflows.

tun_flow_update() was calling sock_rps_record_flow_hash() regardless of
the state of rfs_needed. This was not really a bug as sock_flow_table
simply ends up being NULL and thus everything will be fine.
This commit here thus also implicitly makes tun_flow_update() respect
the state of rfs_needed.

Suggested-by: Matthieu Baerts <matt...@kernel.org>
Signed-off-by: Christoph Paasch <cpaa...@openai.com>
Acked-by: Matthieu Baerts (NGI0) <matt...@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matt...@kernel.org>
---
 include/net/rps.h | 85 ++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 56 insertions(+), 29 deletions(-)

diff --git a/include/net/rps.h b/include/net/rps.h
index 
9917dce42ca457e9c25d9e84ee450235f771d09b..f1794cd2e7fb32a36bde9959fab651663ab190fd
 100644
--- a/include/net/rps.h
+++ b/include/net/rps.h
@@ -85,11 +85,8 @@ static inline void rps_record_sock_flow(struct 
rps_sock_flow_table *table,
                WRITE_ONCE(table->ents[index], val);
 }
 
-#endif /* CONFIG_RPS */
-
-static inline void sock_rps_record_flow_hash(__u32 hash)
+static inline void _sock_rps_record_flow_hash(__u32 hash)
 {
-#ifdef CONFIG_RPS
        struct rps_sock_flow_table *sock_flow_table;
 
        if (!hash)
@@ -99,42 +96,33 @@ static inline void sock_rps_record_flow_hash(__u32 hash)
        if (sock_flow_table)
                rps_record_sock_flow(sock_flow_table, hash);
        rcu_read_unlock();
-#endif
 }
 
-static inline void sock_rps_record_flow(const struct sock *sk)
+static inline void _sock_rps_record_flow(const struct sock *sk)
 {
-#ifdef CONFIG_RPS
-       if (static_branch_unlikely(&rfs_needed)) {
-               /* Reading sk->sk_rxhash might incur an expensive cache line
-                * miss.
-                *
-                * TCP_ESTABLISHED does cover almost all states where RFS
-                * might be useful, and is cheaper [1] than testing :
-                *      IPv4: inet_sk(sk)->inet_daddr
-                *      IPv6: ipv6_addr_any(&sk->sk_v6_daddr)
-                * OR   an additional socket flag
-                * [1] : sk_state and sk_prot are in the same cache line.
+       /* Reading sk->sk_rxhash might incur an expensive cache line
+        * miss.
+        *
+        * TCP_ESTABLISHED does cover almost all states where RFS
+        * might be useful, and is cheaper [1] than testing :
+        *      IPv4: inet_sk(sk)->inet_daddr
+        *      IPv6: ipv6_addr_any(&sk->sk_v6_daddr)
+        * OR   an additional socket flag
+        * [1] : sk_state and sk_prot are in the same cache line.
+        */
+       if (sk->sk_state == TCP_ESTABLISHED) {
+               /* This READ_ONCE() is paired with the WRITE_ONCE()
+                * from sock_rps_save_rxhash() and sock_rps_reset_rxhash().
                 */
-               if (sk->sk_state == TCP_ESTABLISHED) {
-                       /* This READ_ONCE() is paired with the WRITE_ONCE()
-                        * from sock_rps_save_rxhash() and 
sock_rps_reset_rxhash().
-                        */
-                       sock_rps_record_flow_hash(READ_ONCE(sk->sk_rxhash));
-               }
+               _sock_rps_record_flow_hash(READ_ONCE(sk->sk_rxhash));
        }
-#endif
 }
 
-static inline void sock_rps_delete_flow(const struct sock *sk)
+static inline void _sock_rps_delete_flow(const struct sock *sk)
 {
-#ifdef CONFIG_RPS
        struct rps_sock_flow_table *table;
        u32 hash, index;
 
-       if (!static_branch_unlikely(&rfs_needed))
-               return;
-
        hash = READ_ONCE(sk->sk_rxhash);
        if (!hash)
                return;
@@ -147,6 +135,45 @@ static inline void sock_rps_delete_flow(const struct sock 
*sk)
                        WRITE_ONCE(table->ents[index], RPS_NO_CPU);
        }
        rcu_read_unlock();
+}
+#endif /* CONFIG_RPS */
+
+static inline bool rfs_is_needed(void)
+{
+#ifdef CONFIG_RPS
+       return static_branch_unlikely(&rfs_needed);
+#else
+       return false;
+#endif
+}
+
+static inline void sock_rps_record_flow_hash(__u32 hash)
+{
+#ifdef CONFIG_RPS
+       if (!rfs_is_needed())
+               return;
+
+       _sock_rps_record_flow_hash(hash);
+#endif
+}
+
+static inline void sock_rps_record_flow(const struct sock *sk)
+{
+#ifdef CONFIG_RPS
+       if (!rfs_is_needed())
+               return;
+
+       _sock_rps_record_flow(sk);
+#endif
+}
+
+static inline void sock_rps_delete_flow(const struct sock *sk)
+{
+#ifdef CONFIG_RPS
+       if (!rfs_is_needed())
+               return;
+
+       _sock_rps_delete_flow(sk);
 #endif
 }
 

-- 
2.51.0


Reply via email to