hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/net/rxrpc/peer_object.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* RxRPC remote transport endpoint record management
23 *
34 * Copyright (C) 2007, 2016 Red Hat, Inc. All Rights Reserved.
45 * Written by David Howells (dhowells@redhat.com)
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the License, or (at your option) any later version.
106 */
117
128 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -125,7 +121,7 @@
125121
126122 hash_for_each_possible_rcu(rxnet->peer_hash, peer, hash_link, hash_key) {
127123 if (rxrpc_peer_cmp_key(peer, local, srx, hash_key) == 0 &&
128
- atomic_read(&peer->usage) > 0)
124
+ refcount_read(&peer->ref) > 0)
129125 return peer;
130126 }
131127
....@@ -144,7 +140,7 @@
144140 peer = __rxrpc_lookup_peer_rcu(local, srx, hash_key);
145141 if (peer) {
146142 _net("PEER %d {%pISp}", peer->debug_id, &peer->srx.transport);
147
- _leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
143
+ _leave(" = %p {u=%d}", peer, refcount_read(&peer->ref));
148144 }
149145 return peer;
150146 }
....@@ -213,13 +209,14 @@
213209 */
214210 struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp)
215211 {
212
+ const void *here = __builtin_return_address(0);
216213 struct rxrpc_peer *peer;
217214
218215 _enter("");
219216
220217 peer = kzalloc(sizeof(struct rxrpc_peer), gfp);
221218 if (peer) {
222
- atomic_set(&peer->usage, 1);
219
+ refcount_set(&peer->ref, 1);
223220 peer->local = rxrpc_get_local(local);
224221 INIT_HLIST_HEAD(&peer->error_targets);
225222 peer->service_conns = RB_ROOT;
....@@ -228,12 +225,15 @@
228225 spin_lock_init(&peer->rtt_input_lock);
229226 peer->debug_id = atomic_inc_return(&rxrpc_debug_id);
230227
228
+ rxrpc_peer_init_rtt(peer);
229
+
231230 if (RXRPC_TX_SMSS > 2190)
232231 peer->cong_cwnd = 2;
233232 else if (RXRPC_TX_SMSS > 1095)
234233 peer->cong_cwnd = 3;
235234 else
236235 peer->cong_cwnd = 4;
236
+ trace_rxrpc_peer(peer->debug_id, rxrpc_peer_new, 1, here);
237237 }
238238
239239 _leave(" = %p", peer);
....@@ -378,7 +378,7 @@
378378
379379 _net("PEER %d {%pISp}", peer->debug_id, &peer->srx.transport);
380380
381
- _leave(" = %p {u=%d}", peer, atomic_read(&peer->usage));
381
+ _leave(" = %p {u=%d}", peer, refcount_read(&peer->ref));
382382 return peer;
383383 }
384384
....@@ -388,10 +388,10 @@
388388 struct rxrpc_peer *rxrpc_get_peer(struct rxrpc_peer *peer)
389389 {
390390 const void *here = __builtin_return_address(0);
391
- int n;
391
+ int r;
392392
393
- n = atomic_inc_return(&peer->usage);
394
- trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, n, here);
393
+ __refcount_inc(&peer->ref, &r);
394
+ trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, r + 1, here);
395395 return peer;
396396 }
397397
....@@ -401,11 +401,11 @@
401401 struct rxrpc_peer *rxrpc_get_peer_maybe(struct rxrpc_peer *peer)
402402 {
403403 const void *here = __builtin_return_address(0);
404
+ int r;
404405
405406 if (peer) {
406
- int n = atomic_fetch_add_unless(&peer->usage, 1, 0);
407
- if (n > 0)
408
- trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, n + 1, here);
407
+ if (__refcount_inc_not_zero(&peer->ref, &r))
408
+ trace_rxrpc_peer(peer->debug_id, rxrpc_peer_got, r + 1, here);
409409 else
410410 peer = NULL;
411411 }
....@@ -436,13 +436,14 @@
436436 {
437437 const void *here = __builtin_return_address(0);
438438 unsigned int debug_id;
439
- int n;
439
+ bool dead;
440
+ int r;
440441
441442 if (peer) {
442443 debug_id = peer->debug_id;
443
- n = atomic_dec_return(&peer->usage);
444
- trace_rxrpc_peer(debug_id, rxrpc_peer_put, n, here);
445
- if (n == 0)
444
+ dead = __refcount_dec_and_test(&peer->ref, &r);
445
+ trace_rxrpc_peer(debug_id, rxrpc_peer_put, r - 1, here);
446
+ if (dead)
446447 __rxrpc_put_peer(peer);
447448 }
448449 }
....@@ -455,11 +456,12 @@
455456 {
456457 const void *here = __builtin_return_address(0);
457458 unsigned int debug_id = peer->debug_id;
458
- int n;
459
+ bool dead;
460
+ int r;
459461
460
- n = atomic_dec_return(&peer->usage);
461
- trace_rxrpc_peer(debug_id, rxrpc_peer_put, n, here);
462
- if (n == 0) {
462
+ dead = __refcount_dec_and_test(&peer->ref, &r);
463
+ trace_rxrpc_peer(debug_id, rxrpc_peer_put, r - 1, here);
464
+ if (dead) {
463465 hash_del_rcu(&peer->hash_link);
464466 list_del_init(&peer->keepalive_link);
465467 rxrpc_free_peer(peer);
....@@ -481,7 +483,7 @@
481483 hlist_for_each_entry(peer, &rxnet->peer_hash[i], hash_link) {
482484 pr_err("Leaked peer %u {%u} %pISp\n",
483485 peer->debug_id,
484
- atomic_read(&peer->usage),
486
+ refcount_read(&peer->ref),
485487 &peer->srx.transport);
486488 }
487489 }
....@@ -503,14 +505,24 @@
503505 EXPORT_SYMBOL(rxrpc_kernel_get_peer);
504506
505507 /**
506
- * rxrpc_kernel_get_rtt - Get a call's peer RTT
508
+ * rxrpc_kernel_get_srtt - Get a call's peer smoothed RTT
507509 * @sock: The socket on which the call is in progress.
508510 * @call: The call to query
511
+ * @_srtt: Where to store the SRTT value.
509512 *
510
- * Get the call's peer RTT.
513
+ * Get the call's peer smoothed RTT in uS.
511514 */
512
-u64 rxrpc_kernel_get_rtt(struct socket *sock, struct rxrpc_call *call)
515
+bool rxrpc_kernel_get_srtt(struct socket *sock, struct rxrpc_call *call,
516
+ u32 *_srtt)
513517 {
514
- return call->peer->rtt;
518
+ struct rxrpc_peer *peer = call->peer;
519
+
520
+ if (peer->rtt_count == 0) {
521
+ *_srtt = 1000000; /* 1S */
522
+ return false;
523
+ }
524
+
525
+ *_srtt = call->peer->srtt_us >> 3;
526
+ return true;
515527 }
516
-EXPORT_SYMBOL(rxrpc_kernel_get_rtt);
528
+EXPORT_SYMBOL(rxrpc_kernel_get_srtt);