|
@@ -1419,8 +1419,12 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
|
|
|
}
|
|
|
EXPORT_SYMBOL(sk_alloc);
|
|
|
|
|
|
-void sk_destruct(struct sock *sk)
|
|
|
+/* Sockets having SOCK_RCU_FREE will call this function after one RCU
|
|
|
+ * grace period. This is the case for UDP sockets and TCP listeners.
|
|
|
+ */
|
|
|
+static void __sk_destruct(struct rcu_head *head)
|
|
|
{
|
|
|
+ struct sock *sk = container_of(head, struct sock, sk_rcu);
|
|
|
struct sk_filter *filter;
|
|
|
|
|
|
if (sk->sk_destruct)
|
|
@@ -1449,6 +1453,14 @@ void sk_destruct(struct sock *sk)
|
|
|
sk_prot_free(sk->sk_prot_creator, sk);
|
|
|
}
|
|
|
|
|
|
+void sk_destruct(struct sock *sk)
|
|
|
+{
|
|
|
+ if (sock_flag(sk, SOCK_RCU_FREE))
|
|
|
+ call_rcu(&sk->sk_rcu, __sk_destruct);
|
|
|
+ else
|
|
|
+ __sk_destruct(&sk->sk_rcu);
|
|
|
+}
|
|
|
+
|
|
|
static void __sk_free(struct sock *sk)
|
|
|
{
|
|
|
if (unlikely(sock_diag_has_destroy_listeners(sk) && sk->sk_net_refcnt))
|