Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 313926
b: refs/heads/master
c: b48c80e
h: refs/heads/master
v: v3
  • Loading branch information
David S. Miller committed Jun 11, 2012
1 parent 5048147 commit 9704779
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 2 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: 46517008e1168dc926cf2c47d529efc07eca85c0
refs/heads/master: b48c80ece973e9eddb042f6685b482b261ff0d47
2 changes: 2 additions & 0 deletions trunk/include/net/inetpeer.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct inet_peer {
struct inet_peer_base {
struct inet_peer __rcu *root;
seqlock_t lock;
u32 flush_seq;
int total;
};

Expand Down Expand Up @@ -168,6 +169,7 @@ extern void inet_putpeer(struct inet_peer *p);
extern bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout);

extern void inetpeer_invalidate_tree(struct inet_peer_base *);
extern void inetpeer_invalidate_family(int family);

/*
* temporary check to make sure we dont access rid, ip_id_count, tcp_ts,
Expand Down
28 changes: 28 additions & 0 deletions trunk/net/ipv4/inetpeer.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,36 @@ void inet_peer_base_init(struct inet_peer_base *bp)
{
bp->root = peer_avl_empty_rcu;
seqlock_init(&bp->lock);
bp->flush_seq = ~0U;
bp->total = 0;
}
EXPORT_SYMBOL_GPL(inet_peer_base_init);

static atomic_t v4_seq = ATOMIC_INIT(0);
static atomic_t v6_seq = ATOMIC_INIT(0);

static atomic_t *inetpeer_seq_ptr(int family)
{
return (family == AF_INET ? &v4_seq : &v6_seq);
}

static inline void flush_check(struct inet_peer_base *base, int family)
{
atomic_t *fp = inetpeer_seq_ptr(family);

if (unlikely(base->flush_seq != atomic_read(fp))) {
inetpeer_invalidate_tree(base);
base->flush_seq = atomic_read(fp);
}
}

void inetpeer_invalidate_family(int family)
{
atomic_t *fp = inetpeer_seq_ptr(family);

atomic_inc(fp);
}

#define PEER_MAXDEPTH 40 /* sufficient for about 2^27 nodes */

/* Exported for sysctl_net_ipv4. */
Expand Down Expand Up @@ -437,6 +463,8 @@ struct inet_peer *inet_getpeer(struct inet_peer_base *base,
unsigned int sequence;
int invalidated, gccnt = 0;

flush_check(base, daddr->family);

/* Attempt a lockless lookup first.
* Because of a concurrent writer, we might not find an existing entry.
*/
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@ static void rt_cache_invalidate(struct net *net)

get_random_bytes(&shuffle, sizeof(shuffle));
atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
inetpeer_invalidate_tree(net->ipv4.peers);
inetpeer_invalidate_family(AF_INET);
}

/*
Expand Down

0 comments on commit 9704779

Please sign in to comment.