Commit 494bc1d2 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

net/tcp: use deferred jump label for TCP acked data hook

User space can flip the clean_acked_data_enabled static branch
on and off with TLS offload when CONFIG_TLS_DEVICE is enabled.
jump_label.h suggests we use the delayed version in this case.

Deferred branches now also don't take the branch mutex on
decrement, so we avoid potential locking issues.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarSimon Horman <simon.horman@netronome.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 70610c92
...@@ -2198,7 +2198,7 @@ extern struct static_key_false tcp_have_smc; ...@@ -2198,7 +2198,7 @@ extern struct static_key_false tcp_have_smc;
void clean_acked_data_enable(struct inet_connection_sock *icsk, void clean_acked_data_enable(struct inet_connection_sock *icsk,
void (*cad)(struct sock *sk, u32 ack_seq)); void (*cad)(struct sock *sk, u32 ack_seq));
void clean_acked_data_disable(struct inet_connection_sock *icsk); void clean_acked_data_disable(struct inet_connection_sock *icsk);
void clean_acked_data_flush(void);
#endif #endif
#endif /* _TCP_H */ #endif /* _TCP_H */
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <linux/errqueue.h> #include <linux/errqueue.h>
#include <trace/events/tcp.h> #include <trace/events/tcp.h>
#include <linux/static_key.h> #include <linux/jump_label_ratelimit.h>
#include <net/busy_poll.h> #include <net/busy_poll.h>
int sysctl_tcp_max_orphans __read_mostly = NR_FILE; int sysctl_tcp_max_orphans __read_mostly = NR_FILE;
...@@ -113,22 +113,28 @@ int sysctl_tcp_max_orphans __read_mostly = NR_FILE; ...@@ -113,22 +113,28 @@ int sysctl_tcp_max_orphans __read_mostly = NR_FILE;
#define REXMIT_NEW 2 /* FRTO-style transmit of unsent/new packets */ #define REXMIT_NEW 2 /* FRTO-style transmit of unsent/new packets */
#if IS_ENABLED(CONFIG_TLS_DEVICE) #if IS_ENABLED(CONFIG_TLS_DEVICE)
static DEFINE_STATIC_KEY_FALSE(clean_acked_data_enabled); static DEFINE_STATIC_KEY_DEFERRED_FALSE(clean_acked_data_enabled, HZ);
void clean_acked_data_enable(struct inet_connection_sock *icsk, void clean_acked_data_enable(struct inet_connection_sock *icsk,
void (*cad)(struct sock *sk, u32 ack_seq)) void (*cad)(struct sock *sk, u32 ack_seq))
{ {
icsk->icsk_clean_acked = cad; icsk->icsk_clean_acked = cad;
static_branch_inc(&clean_acked_data_enabled); static_branch_inc(&clean_acked_data_enabled.key);
} }
EXPORT_SYMBOL_GPL(clean_acked_data_enable); EXPORT_SYMBOL_GPL(clean_acked_data_enable);
void clean_acked_data_disable(struct inet_connection_sock *icsk) void clean_acked_data_disable(struct inet_connection_sock *icsk)
{ {
static_branch_dec(&clean_acked_data_enabled); static_branch_slow_dec_deferred(&clean_acked_data_enabled);
icsk->icsk_clean_acked = NULL; icsk->icsk_clean_acked = NULL;
} }
EXPORT_SYMBOL_GPL(clean_acked_data_disable); EXPORT_SYMBOL_GPL(clean_acked_data_disable);
void clean_acked_data_flush(void)
{
static_key_deferred_flush(&clean_acked_data_enabled);
}
EXPORT_SYMBOL_GPL(clean_acked_data_flush);
#endif #endif
static void tcp_gro_dev_warn(struct sock *sk, const struct sk_buff *skb, static void tcp_gro_dev_warn(struct sock *sk, const struct sk_buff *skb,
...@@ -3598,7 +3604,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) ...@@ -3598,7 +3604,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
icsk->icsk_retransmits = 0; icsk->icsk_retransmits = 0;
#if IS_ENABLED(CONFIG_TLS_DEVICE) #if IS_ENABLED(CONFIG_TLS_DEVICE)
if (static_branch_unlikely(&clean_acked_data_enabled)) if (static_branch_unlikely(&clean_acked_data_enabled.key))
if (icsk->icsk_clean_acked) if (icsk->icsk_clean_acked)
icsk->icsk_clean_acked(sk, ack); icsk->icsk_clean_acked(sk, ack);
#endif #endif
......
...@@ -1036,4 +1036,5 @@ void __exit tls_device_cleanup(void) ...@@ -1036,4 +1036,5 @@ void __exit tls_device_cleanup(void)
{ {
unregister_netdevice_notifier(&tls_dev_notifier); unregister_netdevice_notifier(&tls_dev_notifier);
flush_work(&tls_device_gc_work); flush_work(&tls_device_gc_work);
clean_acked_data_flush();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment