Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 202948
b: refs/heads/master
c: d73f33b
h: refs/heads/master
v: v3
  • Loading branch information
Eric Dumazet authored and Patrick McHardy committed Jun 15, 2010
1 parent f842780 commit 16b420c
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0b041f8d1e6fb11a6134d37230da8c2182f99110
refs/heads/master: d73f33b168831e53972fbf7c85db87950a41436c
48 changes: 29 additions & 19 deletions trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ struct clusterip_config {
#endif
enum clusterip_hashmode hash_mode; /* which hashing mode */
u_int32_t hash_initval; /* hash initialization */
struct rcu_head rcu;
};

static LIST_HEAD(clusterip_configs);

/* clusterip_lock protects the clusterip_configs list */
static DEFINE_RWLOCK(clusterip_lock);
static DEFINE_SPINLOCK(clusterip_lock);

#ifdef CONFIG_PROC_FS
static const struct file_operations clusterip_proc_fops;
Expand All @@ -71,11 +72,17 @@ clusterip_config_get(struct clusterip_config *c)
atomic_inc(&c->refcount);
}


static void clusterip_config_rcu_free(struct rcu_head *head)
{
kfree(container_of(head, struct clusterip_config, rcu));
}

static inline void
clusterip_config_put(struct clusterip_config *c)
{
if (atomic_dec_and_test(&c->refcount))
kfree(c);
call_rcu_bh(&c->rcu, clusterip_config_rcu_free);
}

/* decrease the count of entries using/referencing this config. If last
Expand All @@ -84,10 +91,11 @@ clusterip_config_put(struct clusterip_config *c)
static inline void
clusterip_config_entry_put(struct clusterip_config *c)
{
write_lock_bh(&clusterip_lock);
if (atomic_dec_and_test(&c->entries)) {
list_del(&c->list);
write_unlock_bh(&clusterip_lock);
local_bh_disable();
if (atomic_dec_and_lock(&c->entries, &clusterip_lock)) {
list_del_rcu(&c->list);
spin_unlock(&clusterip_lock);
local_bh_enable();

dev_mc_del(c->dev, c->clustermac);
dev_put(c->dev);
Expand All @@ -100,15 +108,15 @@ clusterip_config_entry_put(struct clusterip_config *c)
#endif
return;
}
write_unlock_bh(&clusterip_lock);
local_bh_enable();
}

static struct clusterip_config *
__clusterip_config_find(__be32 clusterip)
{
struct clusterip_config *c;

list_for_each_entry(c, &clusterip_configs, list) {
list_for_each_entry_rcu(c, &clusterip_configs, list) {
if (c->clusterip == clusterip)
return c;
}
Expand All @@ -121,16 +129,15 @@ clusterip_config_find_get(__be32 clusterip, int entry)
{
struct clusterip_config *c;

read_lock_bh(&clusterip_lock);
rcu_read_lock_bh();
c = __clusterip_config_find(clusterip);
if (!c) {
read_unlock_bh(&clusterip_lock);
return NULL;
if (c) {
if (unlikely(!atomic_inc_not_zero(&c->refcount)))
c = NULL;
else if (entry)
atomic_inc(&c->entries);
}
atomic_inc(&c->refcount);
if (entry)
atomic_inc(&c->entries);
read_unlock_bh(&clusterip_lock);
rcu_read_unlock_bh();

return c;
}
Expand Down Expand Up @@ -181,9 +188,9 @@ clusterip_config_init(const struct ipt_clusterip_tgt_info *i, __be32 ip,
}
#endif

write_lock_bh(&clusterip_lock);
list_add(&c->list, &clusterip_configs);
write_unlock_bh(&clusterip_lock);
spin_lock_bh(&clusterip_lock);
list_add_rcu(&c->list, &clusterip_configs);
spin_unlock_bh(&clusterip_lock);

return c;
}
Expand Down Expand Up @@ -733,6 +740,9 @@ static void __exit clusterip_tg_exit(void)
#endif
nf_unregister_hook(&cip_arp_ops);
xt_unregister_target(&clusterip_tg_reg);

/* Wait for completion of call_rcu_bh()'s (clusterip_config_rcu_free) */
rcu_barrier_bh();
}

module_init(clusterip_tg_init);
Expand Down

0 comments on commit 16b420c

Please sign in to comment.