--- zzzz-none-000/linux-2.6.28.10/include/net/addrconf.h 2009-05-02 18:54:43.000000000 +0000 +++ puma5-6360-529/linux-2.6.28.10/include/net/addrconf.h 2009-12-11 11:48:18.000000000 +0000 @@ -178,6 +178,78 @@ return rcu_dereference(dev->ip6_ptr); } +#ifdef CONFIG_DEV_REFCNT_DEBUG + +#include "linux/kallsyms.h" + +static inline void in6_show_here(char *func, struct net_device *dev, + int refcnt, char *fn, int ln, + unsigned long ip) +{ + printk(KERN_DEBUG "%s: in6 %d dev %d %s() %s:%d", + dev->name, refcnt, atomic_read(&dev->refcnt), + func, fn, ln); + print_ip_sym(ip); +} + +#define in6_dev_get(dev) ____in6_dev_get(dev, __FILE__, __LINE__) + +static inline struct inet6_dev * +____in6_dev_get(struct net_device *dev, char *fn, int ln) +{ + struct inet6_dev *idev = NULL; + rcu_read_lock(); + idev = __in6_dev_get(dev); + if (idev) { + atomic_inc(&idev->refcnt); + in6_show_here("in6_dev_get", idev->dev, atomic_read(&idev->refcnt), + fn, ln, + (unsigned long)__builtin_return_address(0)); + } + rcu_read_unlock(); + return idev; +} + +extern void in6_dev_finish_destroy(struct inet6_dev *idev); + +#define in6_dev_put(idev) ____in6_dev_put(idev, __FILE__, __LINE__) + +static inline void +____in6_dev_put(struct inet6_dev *idev, char *fn, int ln) +{ + int tmp = atomic_dec_and_test(&idev->refcnt); + + in6_show_here("in6_dev_put", idev->dev, atomic_read(&idev->refcnt), + fn, ln, + (unsigned long)__builtin_return_address(0)); + if (tmp) + in6_dev_finish_destroy(idev); +} + +#define __in6_dev_put(idev) ______in6_dev_put(idev, __FILE__, __LINE__) + +static inline void +______in6_dev_put(struct inet6_dev *idev, char *fn, int ln) +{ + atomic_dec(&(idev)->refcnt); + in6_show_here("__in6_dev_put", idev->dev, atomic_read(&idev->refcnt), + fn, ln, + (unsigned long)__builtin_return_address(0)); +} + +#define in6_dev_hold(idev) ____in6_dev_hold(idev, __FILE__, __LINE__) + +static inline void +____in6_dev_hold(struct inet6_dev *idev, char *fn, int ln) +{ + atomic_inc(&(idev)->refcnt); + in6_show_here("__in6_dev_put", idev->dev, atomic_read(&idev->refcnt), + fn, ln, + (unsigned long)__builtin_return_address(0)); +} + +#else + static inline struct inet6_dev * in6_dev_get(struct net_device *dev) { @@ -201,6 +273,7 @@ #define __in6_dev_put(idev) atomic_dec(&(idev)->refcnt) #define in6_dev_hold(idev) atomic_inc(&(idev)->refcnt) +#endif extern void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp);