Commit e6848976 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by David S. Miller
Browse files

[NET]: Cleanup INET_REFCNT_DEBUG code


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d13964f4
...@@ -29,7 +29,6 @@ extern unsigned int inet_poll(struct file * file, struct socket *sock, struct p ...@@ -29,7 +29,6 @@ extern unsigned int inet_poll(struct file * file, struct socket *sock, struct p
extern int inet_listen(struct socket *sock, int backlog); extern int inet_listen(struct socket *sock, int backlog);
extern void inet_sock_destruct(struct sock *sk); extern void inet_sock_destruct(struct sock *sk);
extern atomic_t inet_sock_nr;
extern int inet_bind(struct socket *sock, extern int inet_bind(struct socket *sock,
struct sockaddr *uaddr, int addr_len); struct sockaddr *uaddr, int addr_len);
......
...@@ -145,7 +145,6 @@ DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6); ...@@ -145,7 +145,6 @@ DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
#define UDP6_INC_STATS(field) SNMP_INC_STATS(udp_stats_in6, field) #define UDP6_INC_STATS(field) SNMP_INC_STATS(udp_stats_in6, field)
#define UDP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_stats_in6, field) #define UDP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_stats_in6, field)
#define UDP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_stats_in6, field) #define UDP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_stats_in6, field)
extern atomic_t inet6_sock_nr;
int snmp6_register_dev(struct inet6_dev *idev); int snmp6_register_dev(struct inet6_dev *idev);
int snmp6_unregister_dev(struct inet6_dev *idev); int snmp6_unregister_dev(struct inet6_dev *idev);
......
...@@ -491,6 +491,9 @@ extern int sk_wait_data(struct sock *sk, long *timeo); ...@@ -491,6 +491,9 @@ extern int sk_wait_data(struct sock *sk, long *timeo);
struct request_sock_ops; struct request_sock_ops;
/* Here is the right place to enable sock refcounting debugging */
#define SOCK_REFCNT_DEBUG
/* Networking protocol blocks we attach to sockets. /* Networking protocol blocks we attach to sockets.
* socket layer -> transport layer interface * socket layer -> transport layer interface
* transport -> network interface is defined by struct inet_proto * transport -> network interface is defined by struct inet_proto
...@@ -561,7 +564,9 @@ struct proto { ...@@ -561,7 +564,9 @@ struct proto {
char name[32]; char name[32];
struct list_head node; struct list_head node;
#ifdef SOCK_REFCNT_DEBUG
atomic_t socks;
#endif
struct { struct {
int inuse; int inuse;
u8 __pad[SMP_CACHE_BYTES - sizeof(int)]; u8 __pad[SMP_CACHE_BYTES - sizeof(int)];
...@@ -571,6 +576,31 @@ struct proto { ...@@ -571,6 +576,31 @@ struct proto {
extern int proto_register(struct proto *prot, int alloc_slab); extern int proto_register(struct proto *prot, int alloc_slab);
extern void proto_unregister(struct proto *prot); extern void proto_unregister(struct proto *prot);
#ifdef SOCK_REFCNT_DEBUG
static inline void sk_refcnt_debug_inc(struct sock *sk)
{
atomic_inc(&sk->sk_prot->socks);
}
static inline void sk_refcnt_debug_dec(struct sock *sk)
{
atomic_dec(&sk->sk_prot->socks);
printk(KERN_DEBUG "%s socket %p released, %d are still alive\n",
sk->sk_prot->name, sk, atomic_read(&sk->sk_prot->socks));
}
static inline void sk_refcnt_debug_release(const struct sock *sk)
{
if (atomic_read(&sk->sk_refcnt) != 1)
printk(KERN_DEBUG "Destruction of the %s socket %p delayed, refcnt=%d\n",
sk->sk_prot->name, sk, atomic_read(&sk->sk_refcnt));
}
#else /* SOCK_REFCNT_DEBUG */
#define sk_refcnt_debug_inc(sk) do { } while (0)
#define sk_refcnt_debug_dec(sk) do { } while (0)
#define sk_refcnt_debug_release(sk) do { } while (0)
#endif /* SOCK_REFCNT_DEBUG */
/* Called with local bh disabled */ /* Called with local bh disabled */
static __inline__ void sock_prot_inc_use(struct proto *prot) static __inline__ void sock_prot_inc_use(struct proto *prot)
{ {
......
...@@ -306,7 +306,7 @@ extern kmem_cache_t *tcp_timewait_cachep; ...@@ -306,7 +306,7 @@ extern kmem_cache_t *tcp_timewait_cachep;
static inline void tcp_tw_put(struct tcp_tw_bucket *tw) static inline void tcp_tw_put(struct tcp_tw_bucket *tw)
{ {
if (atomic_dec_and_test(&tw->tw_refcnt)) { if (atomic_dec_and_test(&tw->tw_refcnt)) {
#ifdef INET_REFCNT_DEBUG #ifdef SOCK_REFCNT_DEBUG
printk(KERN_DEBUG "tw_bucket %p released\n", tw); printk(KERN_DEBUG "tw_bucket %p released\n", tw);
#endif #endif
kmem_cache_free(tcp_timewait_cachep, tw); kmem_cache_free(tcp_timewait_cachep, tw);
......
...@@ -1367,11 +1367,7 @@ void sk_common_release(struct sock *sk) ...@@ -1367,11 +1367,7 @@ void sk_common_release(struct sock *sk)
xfrm_sk_free_policy(sk); xfrm_sk_free_policy(sk);
#ifdef INET_REFCNT_DEBUG sk_refcnt_debug_release(sk);
if (atomic_read(&sk->sk_refcnt) != 1)
printk(KERN_DEBUG "Destruction of the socket %p delayed, c=%d\n",
sk, atomic_read(&sk->sk_refcnt));
#endif
sock_put(sk); sock_put(sk);
} }
......
...@@ -114,10 +114,6 @@ ...@@ -114,10 +114,6 @@
DEFINE_SNMP_STAT(struct linux_mib, net_statistics); DEFINE_SNMP_STAT(struct linux_mib, net_statistics);
#ifdef INET_REFCNT_DEBUG
atomic_t inet_sock_nr;
#endif
extern void ip_mc_drop_socket(struct sock *sk); extern void ip_mc_drop_socket(struct sock *sk);
/* The inetsw table contains everything that inet_create needs to /* The inetsw table contains everything that inet_create needs to
...@@ -153,11 +149,7 @@ void inet_sock_destruct(struct sock *sk) ...@@ -153,11 +149,7 @@ void inet_sock_destruct(struct sock *sk)
if (inet->opt) if (inet->opt)
kfree(inet->opt); kfree(inet->opt);
dst_release(sk->sk_dst_cache); dst_release(sk->sk_dst_cache);
#ifdef INET_REFCNT_DEBUG sk_refcnt_debug_dec(sk);
atomic_dec(&inet_sock_nr);
printk(KERN_DEBUG "INET socket %p released, %d are still alive\n",
sk, atomic_read(&inet_sock_nr));
#endif
} }
/* /*
...@@ -317,9 +309,7 @@ static int inet_create(struct socket *sock, int protocol) ...@@ -317,9 +309,7 @@ static int inet_create(struct socket *sock, int protocol)
inet->mc_index = 0; inet->mc_index = 0;
inet->mc_list = NULL; inet->mc_list = NULL;
#ifdef INET_REFCNT_DEBUG sk_refcnt_debug_inc(sk);
atomic_inc(&inet_sock_nr);
#endif
if (inet->num) { if (inet->num) {
/* It assumes that any protocol which allows /* It assumes that any protocol which allows
...@@ -1205,7 +1195,3 @@ EXPORT_SYMBOL(inet_stream_ops); ...@@ -1205,7 +1195,3 @@ EXPORT_SYMBOL(inet_stream_ops);
EXPORT_SYMBOL(inet_unregister_protosw); EXPORT_SYMBOL(inet_unregister_protosw);
EXPORT_SYMBOL(net_statistics); EXPORT_SYMBOL(net_statistics);
EXPORT_SYMBOL(sysctl_ip_nonlocal_bind); EXPORT_SYMBOL(sysctl_ip_nonlocal_bind);
#ifdef INET_REFCNT_DEBUG
EXPORT_SYMBOL(inet_sock_nr);
#endif
...@@ -1580,12 +1580,7 @@ void tcp_destroy_sock(struct sock *sk) ...@@ -1580,12 +1580,7 @@ void tcp_destroy_sock(struct sock *sk)
xfrm_sk_free_policy(sk); xfrm_sk_free_policy(sk);
#ifdef INET_REFCNT_DEBUG sk_refcnt_debug_release(sk);
if (atomic_read(&sk->sk_refcnt) != 1) {
printk(KERN_DEBUG "Destruction TCP %p delayed, c=%d\n",
sk, atomic_read(&sk->sk_refcnt));
}
#endif
atomic_dec(&tcp_orphan_count); atomic_dec(&tcp_orphan_count);
sock_put(sk); sock_put(sk);
......
...@@ -84,7 +84,7 @@ static void tcp_timewait_kill(struct tcp_tw_bucket *tw) ...@@ -84,7 +84,7 @@ static void tcp_timewait_kill(struct tcp_tw_bucket *tw)
tcp_bucket_destroy(tb); tcp_bucket_destroy(tb);
spin_unlock(&bhead->lock); spin_unlock(&bhead->lock);
#ifdef INET_REFCNT_DEBUG #ifdef SOCK_REFCNT_DEBUG
if (atomic_read(&tw->tw_refcnt) != 1) { if (atomic_read(&tw->tw_refcnt) != 1) {
printk(KERN_DEBUG "tw_bucket %p refcnt=%d\n", tw, printk(KERN_DEBUG "tw_bucket %p refcnt=%d\n", tw,
atomic_read(&tw->tw_refcnt)); atomic_read(&tw->tw_refcnt));
...@@ -799,9 +799,21 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, ...@@ -799,9 +799,21 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
newsk->sk_err = 0; newsk->sk_err = 0;
newsk->sk_priority = 0; newsk->sk_priority = 0;
atomic_set(&newsk->sk_refcnt, 2); atomic_set(&newsk->sk_refcnt, 2);
#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet_sock_nr); /*
#endif * Increment the counter in the same struct proto as the master
* sock (sk_refcnt_debug_inc uses newsk->sk_prot->socks, that
* is the same as sk->sk_prot->socks, as this field was copied
* with memcpy), same rationale as the first comment in this
* function.
*
* This _changes_ the previous behaviour, where
* tcp_create_openreq_child always was incrementing the
* equivalent to tcp_prot->socks (inet_sock_nr), so this have
* to be taken into account in all callers. -acme
*/
sk_refcnt_debug_inc(newsk);
atomic_inc(&tcp_sockets_allocated); atomic_inc(&tcp_sockets_allocated);
if (sock_flag(newsk, SOCK_KEEPOPEN)) if (sock_flag(newsk, SOCK_KEEPOPEN))
......
...@@ -86,26 +86,12 @@ extern void if6_proc_exit(void); ...@@ -86,26 +86,12 @@ extern void if6_proc_exit(void);
int sysctl_ipv6_bindv6only; int sysctl_ipv6_bindv6only;
#ifdef INET_REFCNT_DEBUG
atomic_t inet6_sock_nr;
EXPORT_SYMBOL(inet6_sock_nr);
#endif
/* The inetsw table contains everything that inet_create needs to /* The inetsw table contains everything that inet_create needs to
* build a new socket. * build a new socket.
*/ */
static struct list_head inetsw6[SOCK_MAX]; static struct list_head inetsw6[SOCK_MAX];
static DEFINE_SPINLOCK(inetsw6_lock); static DEFINE_SPINLOCK(inetsw6_lock);
static void inet6_sock_destruct(struct sock *sk)
{
inet_sock_destruct(sk);
#ifdef INET_REFCNT_DEBUG
atomic_dec(&inet6_sock_nr);
#endif
}
static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
{ {
const int offset = sk->sk_prot->obj_size - sizeof(struct ipv6_pinfo); const int offset = sk->sk_prot->obj_size - sizeof(struct ipv6_pinfo);
...@@ -186,7 +172,7 @@ static int inet6_create(struct socket *sock, int protocol) ...@@ -186,7 +172,7 @@ static int inet6_create(struct socket *sock, int protocol)
inet->hdrincl = 1; inet->hdrincl = 1;
} }
sk->sk_destruct = inet6_sock_destruct; sk->sk_destruct = inet_sock_destruct;
sk->sk_family = PF_INET6; sk->sk_family = PF_INET6;
sk->sk_protocol = protocol; sk->sk_protocol = protocol;
...@@ -213,12 +199,17 @@ static int inet6_create(struct socket *sock, int protocol) ...@@ -213,12 +199,17 @@ static int inet6_create(struct socket *sock, int protocol)
inet->pmtudisc = IP_PMTUDISC_DONT; inet->pmtudisc = IP_PMTUDISC_DONT;
else else
inet->pmtudisc = IP_PMTUDISC_WANT; inet->pmtudisc = IP_PMTUDISC_WANT;
/*
* Increment only the relevant sk_prot->socks debug field, this changes
* the previous behaviour of incrementing both the equivalent to
* answer->prot->socks (inet6_sock_nr) and inet_sock_nr.
*
* This allows better debug granularity as we'll know exactly how many
* UDPv6, TCPv6, etc socks were allocated, not the sum of all IPv6
* transport protocol socks. -acme
*/
sk_refcnt_debug_inc(sk);
#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet6_sock_nr);
atomic_inc(&inet_sock_nr);
#endif
if (inet->num) { if (inet->num) {
/* It assumes that any protocol which allows /* It assumes that any protocol which allows
* the user to assign a number at socket * the user to assign a number at socket
......
...@@ -163,6 +163,13 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, ...@@ -163,6 +163,13 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
fl6_free_socklist(sk); fl6_free_socklist(sk);
ipv6_sock_mc_close(sk); ipv6_sock_mc_close(sk);
/*
* Sock is moving from IPv6 to IPv4 (sk_prot), so
* remove it from the refcnt debug socks count in the
* original family...
*/
sk_refcnt_debug_dec(sk);
if (sk->sk_protocol == IPPROTO_TCP) { if (sk->sk_protocol == IPPROTO_TCP) {
struct tcp_sock *tp = tcp_sk(sk); struct tcp_sock *tp = tcp_sk(sk);
...@@ -192,9 +199,11 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname, ...@@ -192,9 +199,11 @@ int ipv6_setsockopt(struct sock *sk, int level, int optname,
kfree_skb(pktopt); kfree_skb(pktopt);
sk->sk_destruct = inet_sock_destruct; sk->sk_destruct = inet_sock_destruct;
#ifdef INET_REFCNT_DEBUG /*
atomic_dec(&inet6_sock_nr); * ... and add it to the refcnt debug socks count
#endif * in the new family. -acme
*/
sk_refcnt_debug_inc(sk);
module_put(THIS_MODULE); module_put(THIS_MODULE);
retv = 0; retv = 0;
break; break;
......
...@@ -1407,12 +1407,11 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, ...@@ -1407,12 +1407,11 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
newnp->mcast_oif = tcp_v6_iif(skb); newnp->mcast_oif = tcp_v6_iif(skb);
newnp->mcast_hops = skb->nh.ipv6h->hop_limit; newnp->mcast_hops = skb->nh.ipv6h->hop_limit;
/* Charge newly allocated IPv6 socket. Though it is mapped, /*
* it is IPv6 yet. * No need to charge this sock to the relevant IPv6 refcnt debug socks count
* here, tcp_create_openreq_child now does this for us, see the comment in
* that function for the gory details. -acme
*/ */
#ifdef INET_REFCNT_DEBUG
atomic_inc(&inet6_sock_nr);
#endif
/* It is tricky place. Until this moment IPv4 tcp /* It is tricky place. Until this moment IPv4 tcp
worked with IPv6 af_tcp.af_specific. worked with IPv6 af_tcp.af_specific.
...@@ -1467,10 +1466,11 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, ...@@ -1467,10 +1466,11 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
if (newsk == NULL) if (newsk == NULL)
goto out; goto out;
/* Charge newly allocated IPv6 socket */ /*
#ifdef INET_REFCNT_DEBUG * No need to charge this sock to the relevant IPv6 refcnt debug socks
atomic_inc(&inet6_sock_nr); * count here, tcp_create_openreq_child now does this for us, see the
#endif * comment in that function for the gory details. -acme
*/
ip6_dst_store(newsk, dst, NULL); ip6_dst_store(newsk, dst, NULL);
newsk->sk_route_caps = dst->dev->features & newsk->sk_route_caps = dst->dev->features &
......
...@@ -641,10 +641,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk, ...@@ -641,10 +641,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock *sk,
else else
newinet->pmtudisc = IP_PMTUDISC_WANT; newinet->pmtudisc = IP_PMTUDISC_WANT;
#ifdef INET_REFCNT_DEBUG sk_refcnt_debug_inc(newsk);
atomic_inc(&inet6_sock_nr);
atomic_inc(&inet_sock_nr);
#endif
if (newsk->sk_prot->init(newsk)) { if (newsk->sk_prot->init(newsk)) {
sk_common_release(newsk); sk_common_release(newsk);
......
...@@ -593,9 +593,7 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk, ...@@ -593,9 +593,7 @@ static struct sock *sctp_v4_create_accept_sk(struct sock *sk,
newinet->mc_index = 0; newinet->mc_index = 0;
newinet->mc_list = NULL; newinet->mc_list = NULL;
#ifdef INET_REFCNT_DEBUG sk_refcnt_debug_inc(newsk);
atomic_inc(&inet_sock_nr);
#endif
if (newsk->sk_prot->init(newsk)) { if (newsk->sk_prot->init(newsk)) {
sk_common_release(newsk); sk_common_release(newsk);
......
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