summaryrefslogtreecommitdiff
path: root/include/linux/inetdevice.h
diff options
context:
space:
mode:
authorDavid S. Miller <davem@nuts.davemloft.net>2004-08-12 02:42:07 -0700
committerJames Morris <jmorris@redhat.com>2004-08-12 02:42:07 -0700
commit1bffa251c91cbd6ba0c5449286a57cb9059496da (patch)
tree8d9f45437905205b9f38f1e7cc8ac265e5b527fd /include/linux/inetdevice.h
parentd98e8833683a51ca67ac9efc4edbd837d7282b54 (diff)
[IPV4]: Move inetdev/ifa locking over to RCU.
Multicast ipv4 address handling still uses rwlock and spinlock synchronization. Signed-off-by: David S. Miller <davem@redhat.com>
Diffstat (limited to 'include/linux/inetdevice.h')
-rw-r--r--include/linux/inetdevice.h28
1 files changed, 17 insertions, 11 deletions
diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h
index 27a5d0a97dbc..29d1135f1201 100644
--- a/include/linux/inetdevice.h
+++ b/include/linux/inetdevice.h
@@ -3,6 +3,8 @@
#ifdef __KERNEL__
+#include <linux/rcupdate.h>
+
struct ipv4_devconf
{
int accept_redirects;
@@ -31,13 +33,13 @@ extern struct ipv4_devconf ipv4_devconf;
struct in_device
{
- struct net_device *dev;
+ struct net_device *dev;
atomic_t refcnt;
- rwlock_t lock;
int dead;
struct in_ifaddr *ifa_list; /* IP ifaddr chain */
+ rwlock_t mc_list_lock;
struct ip_mc_list *mc_list; /* IP multicast filter chain */
- rwlock_t mc_lock; /* for mc_tomb */
+ spinlock_t mc_tomb_lock;
struct ip_mc_list *mc_tomb;
unsigned long mr_v1_seen;
unsigned long mr_v2_seen;
@@ -50,6 +52,7 @@ struct in_device
struct neigh_parms *arp_parms;
struct ipv4_devconf cnf;
+ struct rcu_head rcu_head;
};
#define IN_DEV_FORWARD(in_dev) ((in_dev)->cnf.forwarding)
@@ -80,6 +83,7 @@ struct in_ifaddr
{
struct in_ifaddr *ifa_next;
struct in_device *ifa_dev;
+ struct rcu_head rcu_head;
u32 ifa_local;
u32 ifa_address;
u32 ifa_mask;
@@ -133,19 +137,16 @@ static __inline__ int bad_mask(u32 mask, u32 addr)
#define endfor_ifa(in_dev) }
-extern rwlock_t inetdev_lock;
-
-
static __inline__ struct in_device *
in_dev_get(const struct net_device *dev)
{
struct in_device *in_dev;
- read_lock(&inetdev_lock);
+ rcu_read_lock();
in_dev = dev->ip_ptr;
if (in_dev)
atomic_inc(&in_dev->refcnt);
- read_unlock(&inetdev_lock);
+ rcu_read_unlock();
return in_dev;
}
@@ -157,11 +158,16 @@ __in_dev_get(const struct net_device *dev)
extern void in_dev_finish_destroy(struct in_device *idev);
-static __inline__ void
-in_dev_put(struct in_device *idev)
+static inline void in_dev_rcu_destroy(struct rcu_head *head)
+{
+ struct in_device *idev = container_of(head, struct in_device, rcu_head);
+ in_dev_finish_destroy(idev);
+}
+
+static inline void in_dev_put(struct in_device *idev)
{
if (atomic_dec_and_test(&idev->refcnt))
- in_dev_finish_destroy(idev);
+ call_rcu(&idev->rcu_head, in_dev_rcu_destroy);
}
#define __in_dev_put(idev) atomic_dec(&(idev)->refcnt)