diff options
Diffstat (limited to 'include/net/inetpeer.h')
-rw-r--r-- | include/net/inetpeer.h | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index b84b32fd5df1..d432489e7109 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h | |||
@@ -71,6 +71,60 @@ struct inet_peer_base { | |||
71 | int total; | 71 | int total; |
72 | }; | 72 | }; |
73 | 73 | ||
74 | #define INETPEER_BASE_BIT 0x1UL | ||
75 | |||
76 | static inline struct inet_peer *inetpeer_ptr(unsigned long val) | ||
77 | { | ||
78 | BUG_ON(val & INETPEER_BASE_BIT); | ||
79 | return (struct inet_peer *) val; | ||
80 | } | ||
81 | |||
82 | static inline struct inet_peer_base *inetpeer_base_ptr(unsigned long val) | ||
83 | { | ||
84 | if (!(val & INETPEER_BASE_BIT)) | ||
85 | return NULL; | ||
86 | val &= ~INETPEER_BASE_BIT; | ||
87 | return (struct inet_peer_base *) val; | ||
88 | } | ||
89 | |||
90 | static inline bool inetpeer_ptr_is_peer(unsigned long val) | ||
91 | { | ||
92 | return !(val & INETPEER_BASE_BIT); | ||
93 | } | ||
94 | |||
95 | static inline void __inetpeer_ptr_set_peer(unsigned long *val, struct inet_peer *peer) | ||
96 | { | ||
97 | /* This implicitly clears INETPEER_BASE_BIT */ | ||
98 | *val = (unsigned long) peer; | ||
99 | } | ||
100 | |||
101 | static inline bool inetpeer_ptr_set_peer(unsigned long *ptr, struct inet_peer *peer) | ||
102 | { | ||
103 | unsigned long val = (unsigned long) peer; | ||
104 | unsigned long orig = *ptr; | ||
105 | |||
106 | if (!(orig & INETPEER_BASE_BIT) || !val || | ||
107 | cmpxchg(ptr, orig, val) != orig) | ||
108 | return false; | ||
109 | return true; | ||
110 | } | ||
111 | |||
112 | static inline void inetpeer_init_ptr(unsigned long *ptr, struct inet_peer_base *base) | ||
113 | { | ||
114 | *ptr = (unsigned long) base | INETPEER_BASE_BIT; | ||
115 | } | ||
116 | |||
117 | static inline void inetpeer_transfer_peer(unsigned long *to, unsigned long *from) | ||
118 | { | ||
119 | unsigned long val = *from; | ||
120 | |||
121 | *to = val; | ||
122 | if (inetpeer_ptr_is_peer(val)) { | ||
123 | struct inet_peer *peer = inetpeer_ptr(val); | ||
124 | atomic_inc(&peer->refcnt); | ||
125 | } | ||
126 | } | ||
127 | |||
74 | extern void inet_peer_base_init(struct inet_peer_base *); | 128 | extern void inet_peer_base_init(struct inet_peer_base *); |
75 | 129 | ||
76 | void inet_initpeers(void) __init; | 130 | void inet_initpeers(void) __init; |