Commit 152da81deb9a4870aeac352336184b2b14d4b2ba
Committed by
David S. Miller
1 parent
d670119132
Exists in
master
and in
7 other branches
[INET]: Uninline the __inet_hash function.
This one is used in quite many places in the networking code and seems to big to be inline. After the patch net/ipv4/build-in.o loses ~650 bytes: add/remove: 2/0 grow/shrink: 0/5 up/down: 461/-1114 (-653) function old new delta __inet_hash_nolisten - 282 +282 __inet_hash - 179 +179 tcp_sacktag_write_queue 2255 2254 -1 __inet_lookup_listener 284 274 -10 tcp_v4_syn_recv_sock 755 493 -262 tcp_v4_hash 389 35 -354 inet_hash_connect 1086 599 -487 This version addresses the issue pointed by Eric, that while being inline this function was optimized by gcc in respect to the 'listen_possible' argument. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 4 changed files with 49 additions and 30 deletions Side-by-side Diff
include/net/inet_hashtables.h
... | ... | @@ -264,37 +264,14 @@ |
264 | 264 | wake_up(&hashinfo->lhash_wait); |
265 | 265 | } |
266 | 266 | |
267 | -static inline void __inet_hash(struct inet_hashinfo *hashinfo, | |
268 | - struct sock *sk, const int listen_possible) | |
269 | -{ | |
270 | - struct hlist_head *list; | |
271 | - rwlock_t *lock; | |
267 | +extern void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk); | |
268 | +extern void __inet_hash_nolisten(struct inet_hashinfo *hinfo, struct sock *sk); | |
272 | 269 | |
273 | - BUG_TRAP(sk_unhashed(sk)); | |
274 | - if (listen_possible && sk->sk_state == TCP_LISTEN) { | |
275 | - list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; | |
276 | - lock = &hashinfo->lhash_lock; | |
277 | - inet_listen_wlock(hashinfo); | |
278 | - } else { | |
279 | - struct inet_ehash_bucket *head; | |
280 | - sk->sk_hash = inet_sk_ehashfn(sk); | |
281 | - head = inet_ehash_bucket(hashinfo, sk->sk_hash); | |
282 | - list = &head->chain; | |
283 | - lock = inet_ehash_lockp(hashinfo, sk->sk_hash); | |
284 | - write_lock(lock); | |
285 | - } | |
286 | - __sk_add_node(sk, list); | |
287 | - sock_prot_inc_use(sk->sk_prot); | |
288 | - write_unlock(lock); | |
289 | - if (listen_possible && sk->sk_state == TCP_LISTEN) | |
290 | - wake_up(&hashinfo->lhash_wait); | |
291 | -} | |
292 | - | |
293 | 270 | static inline void inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk) |
294 | 271 | { |
295 | 272 | if (sk->sk_state != TCP_CLOSE) { |
296 | 273 | local_bh_disable(); |
297 | - __inet_hash(hashinfo, sk, 1); | |
274 | + __inet_hash(hashinfo, sk); | |
298 | 275 | local_bh_enable(); |
299 | 276 | } |
300 | 277 | } |
net/dccp/ipv4.c
net/ipv4/inet_hashtables.c
... | ... | @@ -267,6 +267,48 @@ |
267 | 267 | inet->dport); |
268 | 268 | } |
269 | 269 | |
270 | +void __inet_hash_nolisten(struct inet_hashinfo *hashinfo, struct sock *sk) | |
271 | +{ | |
272 | + struct hlist_head *list; | |
273 | + rwlock_t *lock; | |
274 | + struct inet_ehash_bucket *head; | |
275 | + | |
276 | + BUG_TRAP(sk_unhashed(sk)); | |
277 | + | |
278 | + sk->sk_hash = inet_sk_ehashfn(sk); | |
279 | + head = inet_ehash_bucket(hashinfo, sk->sk_hash); | |
280 | + list = &head->chain; | |
281 | + lock = inet_ehash_lockp(hashinfo, sk->sk_hash); | |
282 | + | |
283 | + write_lock(lock); | |
284 | + __sk_add_node(sk, list); | |
285 | + sock_prot_inc_use(sk->sk_prot); | |
286 | + write_unlock(lock); | |
287 | +} | |
288 | +EXPORT_SYMBOL_GPL(__inet_hash_nolisten); | |
289 | + | |
290 | +void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk) | |
291 | +{ | |
292 | + struct hlist_head *list; | |
293 | + rwlock_t *lock; | |
294 | + | |
295 | + if (sk->sk_state != TCP_LISTEN) { | |
296 | + __inet_hash_nolisten(hashinfo, sk); | |
297 | + return; | |
298 | + } | |
299 | + | |
300 | + BUG_TRAP(sk_unhashed(sk)); | |
301 | + list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; | |
302 | + lock = &hashinfo->lhash_lock; | |
303 | + | |
304 | + inet_listen_wlock(hashinfo); | |
305 | + __sk_add_node(sk, list); | |
306 | + sock_prot_inc_use(sk->sk_prot); | |
307 | + write_unlock(lock); | |
308 | + wake_up(&hashinfo->lhash_wait); | |
309 | +} | |
310 | +EXPORT_SYMBOL_GPL(__inet_hash); | |
311 | + | |
270 | 312 | /* |
271 | 313 | * Bind a port for a connect operation and hash it. |
272 | 314 | */ |
... | ... | @@ -334,7 +376,7 @@ |
334 | 376 | inet_bind_hash(sk, tb, port); |
335 | 377 | if (sk_unhashed(sk)) { |
336 | 378 | inet_sk(sk)->sport = htons(port); |
337 | - __inet_hash(hinfo, sk, 0); | |
379 | + __inet_hash_nolisten(hinfo, sk); | |
338 | 380 | } |
339 | 381 | spin_unlock(&head->lock); |
340 | 382 | |
... | ... | @@ -351,7 +393,7 @@ |
351 | 393 | tb = inet_csk(sk)->icsk_bind_hash; |
352 | 394 | spin_lock_bh(&head->lock); |
353 | 395 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { |
354 | - __inet_hash(hinfo, sk, 0); | |
396 | + __inet_hash_nolisten(hinfo, sk); | |
355 | 397 | spin_unlock_bh(&head->lock); |
356 | 398 | return 0; |
357 | 399 | } else { |
net/ipv4/tcp_ipv4.c