inetpeer.c (e5451c8f8330e03ad3cfa16048b4daf961af434f) | inetpeer.c (1cc9a98b59ba92fece1277f76aa43e05f34936a6) |
---|---|
1/* 2 * INETPEER - A storage for permanent information about peers 3 * 4 * This source is covered by the GNU GPL, the same as all kernel sources. 5 * 6 * Authors: Andrey V. Savochkin <saw@msu.ru> 7 */ 8 --- 101 unchanged lines hidden (view full) --- 110 c = rcu_dereference_protected(p->avl_right, 1); 111 if (c != peer_avl_empty) { 112 list_add_tail(&c->gc_list, &list); 113 p->avl_right = peer_avl_empty_rcu; 114 } 115 116 n = list_entry(p->gc_list.next, struct inet_peer, gc_list); 117 | 1/* 2 * INETPEER - A storage for permanent information about peers 3 * 4 * This source is covered by the GNU GPL, the same as all kernel sources. 5 * 6 * Authors: Andrey V. Savochkin <saw@msu.ru> 7 */ 8 --- 101 unchanged lines hidden (view full) --- 110 c = rcu_dereference_protected(p->avl_right, 1); 111 if (c != peer_avl_empty) { 112 list_add_tail(&c->gc_list, &list); 113 p->avl_right = peer_avl_empty_rcu; 114 } 115 116 n = list_entry(p->gc_list.next, struct inet_peer, gc_list); 117 |
118 if (!atomic_read(&p->refcnt)) { | 118 if (refcount_read(&p->refcnt) == 1) { |
119 list_del(&p->gc_list); 120 kmem_cache_free(peer_cachep, p); 121 } 122 } 123 124 if (list_empty(&list)) 125 return; 126 --- 70 unchanged lines hidden (view full) --- 197{ 198 struct inet_peer *u = rcu_dereference(base->root); 199 int count = 0; 200 201 while (u != peer_avl_empty) { 202 int cmp = inetpeer_addr_cmp(daddr, &u->daddr); 203 if (cmp == 0) { 204 /* Before taking a reference, check if this entry was | 119 list_del(&p->gc_list); 120 kmem_cache_free(peer_cachep, p); 121 } 122 } 123 124 if (list_empty(&list)) 125 return; 126 --- 70 unchanged lines hidden (view full) --- 197{ 198 struct inet_peer *u = rcu_dereference(base->root); 199 int count = 0; 200 201 while (u != peer_avl_empty) { 202 int cmp = inetpeer_addr_cmp(daddr, &u->daddr); 203 if (cmp == 0) { 204 /* Before taking a reference, check if this entry was |
205 * deleted (refcnt=-1) | 205 * deleted (refcnt=0) |
206 */ | 206 */ |
207 if (!atomic_add_unless(&u->refcnt, 1, -1)) | 207 if (!refcount_inc_not_zero(&u->refcnt)) { |
208 u = NULL; | 208 u = NULL; |
209 } |
|
209 return u; 210 } 211 if (cmp == -1) 212 u = rcu_dereference(u->avl_left); 213 else 214 u = rcu_dereference(u->avl_right); 215 if (unlikely(++count == PEER_MAXDEPTH)) 216 break; --- 160 unchanged lines hidden (view full) --- 377 else 378 ttl = inet_peer_maxttl 379 - (inet_peer_maxttl - inet_peer_minttl) / HZ * 380 base->total / inet_peer_threshold * HZ; 381 stackptr--; /* last stack slot is peer_avl_empty */ 382 while (stackptr > stack) { 383 stackptr--; 384 p = rcu_deref_locked(**stackptr, base); | 210 return u; 211 } 212 if (cmp == -1) 213 u = rcu_dereference(u->avl_left); 214 else 215 u = rcu_dereference(u->avl_right); 216 if (unlikely(++count == PEER_MAXDEPTH)) 217 break; --- 160 unchanged lines hidden (view full) --- 378 else 379 ttl = inet_peer_maxttl 380 - (inet_peer_maxttl - inet_peer_minttl) / HZ * 381 base->total / inet_peer_threshold * HZ; 382 stackptr--; /* last stack slot is peer_avl_empty */ 383 while (stackptr > stack) { 384 stackptr--; 385 p = rcu_deref_locked(**stackptr, base); |
385 if (atomic_read(&p->refcnt) == 0) { | 386 if (refcount_read(&p->refcnt) == 1) { |
386 smp_rmb(); 387 delta = (__u32)jiffies - p->dtime; | 387 smp_rmb(); 388 delta = (__u32)jiffies - p->dtime; |
388 if (delta >= ttl && 389 atomic_cmpxchg(&p->refcnt, 0, -1) == 0) { | 389 if (delta >= ttl && refcount_dec_if_one(&p->refcnt)) { |
390 p->gc_next = gchead; 391 gchead = p; 392 } 393 } 394 } 395 while ((p = gchead) != NULL) { 396 gchead = p->gc_next; 397 cnt++; --- 29 unchanged lines hidden (view full) --- 427 428 /* retry an exact lookup, taking the lock before. 429 * At least, nodes should be hot in our cache. 430 */ 431 write_seqlock_bh(&base->lock); 432relookup: 433 p = lookup(daddr, stack, base); 434 if (p != peer_avl_empty) { | 390 p->gc_next = gchead; 391 gchead = p; 392 } 393 } 394 } 395 while ((p = gchead) != NULL) { 396 gchead = p->gc_next; 397 cnt++; --- 29 unchanged lines hidden (view full) --- 427 428 /* retry an exact lookup, taking the lock before. 429 * At least, nodes should be hot in our cache. 430 */ 431 write_seqlock_bh(&base->lock); 432relookup: 433 p = lookup(daddr, stack, base); 434 if (p != peer_avl_empty) { |
435 atomic_inc(&p->refcnt); | 435 refcount_inc(&p->refcnt); |
436 write_sequnlock_bh(&base->lock); 437 return p; 438 } 439 if (!gccnt) { 440 gccnt = inet_peer_gc(base, stack, stackptr); 441 if (gccnt && create) 442 goto relookup; 443 } 444 p = create ? kmem_cache_alloc(peer_cachep, GFP_ATOMIC) : NULL; 445 if (p) { 446 p->daddr = *daddr; | 436 write_sequnlock_bh(&base->lock); 437 return p; 438 } 439 if (!gccnt) { 440 gccnt = inet_peer_gc(base, stack, stackptr); 441 if (gccnt && create) 442 goto relookup; 443 } 444 p = create ? kmem_cache_alloc(peer_cachep, GFP_ATOMIC) : NULL; 445 if (p) { 446 p->daddr = *daddr; |
447 atomic_set(&p->refcnt, 1); | 447 refcount_set(&p->refcnt, 2); |
448 atomic_set(&p->rid, 0); 449 p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; 450 p->rate_tokens = 0; 451 /* 60*HZ is arbitrary, but chosen enough high so that the first 452 * calculation of tokens is at its maximum. 453 */ 454 p->rate_last = jiffies - 60*HZ; 455 INIT_LIST_HEAD(&p->gc_list); --- 7 unchanged lines hidden (view full) --- 463 return p; 464} 465EXPORT_SYMBOL_GPL(inet_getpeer); 466 467void inet_putpeer(struct inet_peer *p) 468{ 469 p->dtime = (__u32)jiffies; 470 smp_mb__before_atomic(); | 448 atomic_set(&p->rid, 0); 449 p->metrics[RTAX_LOCK-1] = INETPEER_METRICS_NEW; 450 p->rate_tokens = 0; 451 /* 60*HZ is arbitrary, but chosen enough high so that the first 452 * calculation of tokens is at its maximum. 453 */ 454 p->rate_last = jiffies - 60*HZ; 455 INIT_LIST_HEAD(&p->gc_list); --- 7 unchanged lines hidden (view full) --- 463 return p; 464} 465EXPORT_SYMBOL_GPL(inet_getpeer); 466 467void inet_putpeer(struct inet_peer *p) 468{ 469 p->dtime = (__u32)jiffies; 470 smp_mb__before_atomic(); |
471 atomic_dec(&p->refcnt); | 471 refcount_dec(&p->refcnt); |
472} 473EXPORT_SYMBOL_GPL(inet_putpeer); 474 475/* 476 * Check transmit rate limitation for given message. 477 * The rate information is held in the inet_peer entries now. 478 * This function is generic and could be used for other purposes 479 * too. It uses a Token bucket filter as suggested by Alexey Kuznetsov. --- 63 unchanged lines hidden --- | 472} 473EXPORT_SYMBOL_GPL(inet_putpeer); 474 475/* 476 * Check transmit rate limitation for given message. 477 * The rate information is held in the inet_peer entries now. 478 * This function is generic and could be used for other purposes 479 * too. It uses a Token bucket filter as suggested by Alexey Kuznetsov. --- 63 unchanged lines hidden --- |