diff options
Diffstat (limited to 'include/net/inetpeer.h')
-rw-r--r-- | include/net/inetpeer.h | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index 8a159cc3d68b..78c83e62218f 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
14 | #include <linux/rtnetlink.h> | 14 | #include <linux/rtnetlink.h> |
15 | #include <net/ipv6.h> | 15 | #include <net/ipv6.h> |
16 | #include <asm/atomic.h> | 16 | #include <linux/atomic.h> |
17 | 17 | ||
18 | struct inetpeer_addr_base { | 18 | struct inetpeer_addr_base { |
19 | union { | 19 | union { |
@@ -32,13 +32,17 @@ struct inet_peer { | |||
32 | struct inet_peer __rcu *avl_left, *avl_right; | 32 | struct inet_peer __rcu *avl_left, *avl_right; |
33 | struct inetpeer_addr daddr; | 33 | struct inetpeer_addr daddr; |
34 | __u32 avl_height; | 34 | __u32 avl_height; |
35 | struct list_head unused; | 35 | |
36 | __u32 dtime; /* the time of last use of not | 36 | u32 metrics[RTAX_MAX]; |
37 | * referenced entries */ | 37 | u32 rate_tokens; /* rate limiting for ICMP */ |
38 | atomic_t refcnt; | 38 | unsigned long rate_last; |
39 | unsigned long pmtu_expires; | ||
40 | u32 pmtu_orig; | ||
41 | u32 pmtu_learned; | ||
42 | struct inetpeer_addr_base redirect_learned; | ||
39 | /* | 43 | /* |
40 | * Once inet_peer is queued for deletion (refcnt == -1), following fields | 44 | * Once inet_peer is queued for deletion (refcnt == -1), following fields |
41 | * are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp, metrics | 45 | * are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp |
42 | * We can share memory with rcu_head to help keep inet_peer small. | 46 | * We can share memory with rcu_head to help keep inet_peer small. |
43 | */ | 47 | */ |
44 | union { | 48 | union { |
@@ -47,16 +51,14 @@ struct inet_peer { | |||
47 | atomic_t ip_id_count; /* IP ID for the next packet */ | 51 | atomic_t ip_id_count; /* IP ID for the next packet */ |
48 | __u32 tcp_ts; | 52 | __u32 tcp_ts; |
49 | __u32 tcp_ts_stamp; | 53 | __u32 tcp_ts_stamp; |
50 | u32 metrics[RTAX_MAX]; | ||
51 | u32 rate_tokens; /* rate limiting for ICMP */ | ||
52 | unsigned long rate_last; | ||
53 | unsigned long pmtu_expires; | ||
54 | u32 pmtu_orig; | ||
55 | u32 pmtu_learned; | ||
56 | struct inetpeer_addr_base redirect_learned; | ||
57 | }; | 54 | }; |
58 | struct rcu_head rcu; | 55 | struct rcu_head rcu; |
56 | struct inet_peer *gc_next; | ||
59 | }; | 57 | }; |
58 | |||
59 | /* following fields might be frequently dirtied */ | ||
60 | __u32 dtime; /* the time of last use of not referenced entries */ | ||
61 | atomic_t refcnt; | ||
60 | }; | 62 | }; |
61 | 63 | ||
62 | void inet_initpeers(void) __init; | 64 | void inet_initpeers(void) __init; |
@@ -69,7 +71,7 @@ static inline bool inet_metrics_new(const struct inet_peer *p) | |||
69 | } | 71 | } |
70 | 72 | ||
71 | /* can be called with or without local BH being disabled */ | 73 | /* can be called with or without local BH being disabled */ |
72 | struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create); | 74 | struct inet_peer *inet_getpeer(const struct inetpeer_addr *daddr, int create); |
73 | 75 | ||
74 | static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) | 76 | static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create) |
75 | { | 77 | { |
@@ -104,11 +106,18 @@ static inline void inet_peer_refcheck(const struct inet_peer *p) | |||
104 | 106 | ||
105 | 107 | ||
106 | /* can be called with or without local BH being disabled */ | 108 | /* can be called with or without local BH being disabled */ |
107 | static inline __u16 inet_getid(struct inet_peer *p, int more) | 109 | static inline int inet_getid(struct inet_peer *p, int more) |
108 | { | 110 | { |
111 | int old, new; | ||
109 | more++; | 112 | more++; |
110 | inet_peer_refcheck(p); | 113 | inet_peer_refcheck(p); |
111 | return atomic_add_return(more, &p->ip_id_count) - more; | 114 | do { |
115 | old = atomic_read(&p->ip_id_count); | ||
116 | new = old + more; | ||
117 | if (!new) | ||
118 | new = 1; | ||
119 | } while (atomic_cmpxchg(&p->ip_id_count, old, new) != old); | ||
120 | return new; | ||
112 | } | 121 | } |
113 | 122 | ||
114 | #endif /* _NET_INETPEER_H */ | 123 | #endif /* _NET_INETPEER_H */ |