diff options
Diffstat (limited to 'include/net/sock.h')
-rw-r--r-- | include/net/sock.h | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/include/net/sock.h b/include/net/sock.h index e9b1dbab90d0..11b81551041e 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -491,6 +491,9 @@ extern int sk_wait_data(struct sock *sk, long *timeo); | |||
491 | 491 | ||
492 | struct request_sock_ops; | 492 | struct request_sock_ops; |
493 | 493 | ||
494 | /* Here is the right place to enable sock refcounting debugging */ | ||
495 | #define SOCK_REFCNT_DEBUG | ||
496 | |||
494 | /* Networking protocol blocks we attach to sockets. | 497 | /* Networking protocol blocks we attach to sockets. |
495 | * socket layer -> transport layer interface | 498 | * socket layer -> transport layer interface |
496 | * transport -> network interface is defined by struct inet_proto | 499 | * transport -> network interface is defined by struct inet_proto |
@@ -561,7 +564,9 @@ struct proto { | |||
561 | char name[32]; | 564 | char name[32]; |
562 | 565 | ||
563 | struct list_head node; | 566 | struct list_head node; |
564 | 567 | #ifdef SOCK_REFCNT_DEBUG | |
568 | atomic_t socks; | ||
569 | #endif | ||
565 | struct { | 570 | struct { |
566 | int inuse; | 571 | int inuse; |
567 | u8 __pad[SMP_CACHE_BYTES - sizeof(int)]; | 572 | u8 __pad[SMP_CACHE_BYTES - sizeof(int)]; |
@@ -571,6 +576,31 @@ struct proto { | |||
571 | extern int proto_register(struct proto *prot, int alloc_slab); | 576 | extern int proto_register(struct proto *prot, int alloc_slab); |
572 | extern void proto_unregister(struct proto *prot); | 577 | extern void proto_unregister(struct proto *prot); |
573 | 578 | ||
579 | #ifdef SOCK_REFCNT_DEBUG | ||
580 | static inline void sk_refcnt_debug_inc(struct sock *sk) | ||
581 | { | ||
582 | atomic_inc(&sk->sk_prot->socks); | ||
583 | } | ||
584 | |||
585 | static inline void sk_refcnt_debug_dec(struct sock *sk) | ||
586 | { | ||
587 | atomic_dec(&sk->sk_prot->socks); | ||
588 | printk(KERN_DEBUG "%s socket %p released, %d are still alive\n", | ||
589 | sk->sk_prot->name, sk, atomic_read(&sk->sk_prot->socks)); | ||
590 | } | ||
591 | |||
592 | static inline void sk_refcnt_debug_release(const struct sock *sk) | ||
593 | { | ||
594 | if (atomic_read(&sk->sk_refcnt) != 1) | ||
595 | printk(KERN_DEBUG "Destruction of the %s socket %p delayed, refcnt=%d\n", | ||
596 | sk->sk_prot->name, sk, atomic_read(&sk->sk_refcnt)); | ||
597 | } | ||
598 | #else /* SOCK_REFCNT_DEBUG */ | ||
599 | #define sk_refcnt_debug_inc(sk) do { } while (0) | ||
600 | #define sk_refcnt_debug_dec(sk) do { } while (0) | ||
601 | #define sk_refcnt_debug_release(sk) do { } while (0) | ||
602 | #endif /* SOCK_REFCNT_DEBUG */ | ||
603 | |||
574 | /* Called with local bh disabled */ | 604 | /* Called with local bh disabled */ |
575 | static __inline__ void sock_prot_inc_use(struct proto *prot) | 605 | static __inline__ void sock_prot_inc_use(struct proto *prot) |
576 | { | 606 | { |