hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/rxrpc/conn_object.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* RxRPC virtual connection handler, common bits.
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
....@@ -45,8 +41,6 @@
4541 conn = kzalloc(sizeof(struct rxrpc_connection), gfp);
4642 if (conn) {
4743 INIT_LIST_HEAD(&conn->cache_link);
48
- spin_lock_init(&conn->channel_lock);
49
- INIT_LIST_HEAD(&conn->waiting_calls);
5044 timer_setup(&conn->timer, &rxrpc_connection_timer, 0);
5145 INIT_WORK(&conn->processor, &rxrpc_process_connection);
5246 INIT_LIST_HEAD(&conn->proc_link);
....@@ -86,11 +80,12 @@
8680
8781 _enter(",%x", sp->hdr.cid & RXRPC_CIDMASK);
8882
89
- if (rxrpc_extract_addr_from_skb(local, &srx, skb) < 0)
83
+ if (rxrpc_extract_addr_from_skb(&srx, skb) < 0)
9084 goto not_found;
9185
92
- /* We may have to handle mixing IPv4 and IPv6 */
93
- if (srx.transport.family != local->srx.transport.family) {
86
+ if (srx.transport.family != local->srx.transport.family &&
87
+ (srx.transport.family == AF_INET &&
88
+ local->srx.transport.family != AF_INET6)) {
9489 pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n",
9590 srx.transport.family,
9691 local->srx.transport.family);
....@@ -110,7 +105,7 @@
110105 goto not_found;
111106 *_peer = peer;
112107 conn = rxrpc_find_service_conn_rcu(peer, skb);
113
- if (!conn || atomic_read(&conn->usage) == 0)
108
+ if (!conn || refcount_read(&conn->ref) == 0)
114109 goto not_found;
115110 _leave(" = %p", conn);
116111 return conn;
....@@ -120,7 +115,7 @@
120115 */
121116 conn = idr_find(&rxrpc_client_conn_ids,
122117 sp->hdr.cid >> RXRPC_CIDSHIFT);
123
- if (!conn || atomic_read(&conn->usage) == 0) {
118
+ if (!conn || refcount_read(&conn->ref) == 0) {
124119 _debug("no conn");
125120 goto not_found;
126121 }
....@@ -189,7 +184,7 @@
189184 chan->last_type = RXRPC_PACKET_TYPE_ABORT;
190185 break;
191186 default:
192
- chan->last_abort = RX_USER_ABORT;
187
+ chan->last_abort = RX_CALL_DEAD;
193188 chan->last_type = RXRPC_PACKET_TYPE_ABORT;
194189 break;
195190 }
....@@ -222,11 +217,11 @@
222217 }
223218
224219 if (rxrpc_is_client_call(call))
225
- return rxrpc_disconnect_client_call(call);
220
+ return rxrpc_disconnect_client_call(conn->bundle, call);
226221
227
- spin_lock(&conn->channel_lock);
222
+ spin_lock(&conn->bundle->channel_lock);
228223 __rxrpc_disconnect_call(conn, call);
229
- spin_unlock(&conn->channel_lock);
224
+ spin_unlock(&conn->bundle->channel_lock);
230225
231226 set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
232227 conn->idle_timestamp = jiffies;
....@@ -269,11 +264,12 @@
269264 bool rxrpc_queue_conn(struct rxrpc_connection *conn)
270265 {
271266 const void *here = __builtin_return_address(0);
272
- int n = atomic_fetch_add_unless(&conn->usage, 1, 0);
273
- if (n == 0)
267
+ int r;
268
+
269
+ if (!__refcount_inc_not_zero(&conn->ref, &r))
274270 return false;
275271 if (rxrpc_queue_work(&conn->processor))
276
- trace_rxrpc_conn(conn->debug_id, rxrpc_conn_queued, n + 1, here);
272
+ trace_rxrpc_conn(conn->debug_id, rxrpc_conn_queued, r + 1, here);
277273 else
278274 rxrpc_put_connection(conn);
279275 return true;
....@@ -286,7 +282,7 @@
286282 {
287283 const void *here = __builtin_return_address(0);
288284 if (conn) {
289
- int n = atomic_read(&conn->usage);
285
+ int n = refcount_read(&conn->ref);
290286
291287 trace_rxrpc_conn(conn->debug_id, rxrpc_conn_seen, n, here);
292288 }
....@@ -295,12 +291,14 @@
295291 /*
296292 * Get a ref on a connection.
297293 */
298
-void rxrpc_get_connection(struct rxrpc_connection *conn)
294
+struct rxrpc_connection *rxrpc_get_connection(struct rxrpc_connection *conn)
299295 {
300296 const void *here = __builtin_return_address(0);
301
- int n = atomic_inc_return(&conn->usage);
297
+ int r;
302298
303
- trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, n, here);
299
+ __refcount_inc(&conn->ref, &r);
300
+ trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, r, here);
301
+ return conn;
304302 }
305303
306304 /*
....@@ -310,11 +308,11 @@
310308 rxrpc_get_connection_maybe(struct rxrpc_connection *conn)
311309 {
312310 const void *here = __builtin_return_address(0);
311
+ int r;
313312
314313 if (conn) {
315
- int n = atomic_fetch_add_unless(&conn->usage, 1, 0);
316
- if (n > 0)
317
- trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, n + 1, here);
314
+ if (__refcount_inc_not_zero(&conn->ref, &r))
315
+ trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, r + 1, here);
318316 else
319317 conn = NULL;
320318 }
....@@ -338,12 +336,11 @@
338336 {
339337 const void *here = __builtin_return_address(0);
340338 unsigned int debug_id = conn->debug_id;
341
- int n;
339
+ int r;
342340
343
- n = atomic_dec_return(&conn->usage);
344
- trace_rxrpc_conn(debug_id, rxrpc_conn_put_service, n, here);
345
- ASSERTCMP(n, >=, 0);
346
- if (n == 1)
341
+ __refcount_dec(&conn->ref, &r);
342
+ trace_rxrpc_conn(debug_id, rxrpc_conn_put_service, r - 1, here);
343
+ if (r - 1 == 1)
347344 rxrpc_set_service_reap_timer(conn->params.local->rxnet,
348345 jiffies + rxrpc_connection_expiry);
349346 }
....@@ -356,9 +353,9 @@
356353 struct rxrpc_connection *conn =
357354 container_of(rcu, struct rxrpc_connection, rcu);
358355
359
- _enter("{%d,u=%d}", conn->debug_id, atomic_read(&conn->usage));
356
+ _enter("{%d,u=%d}", conn->debug_id, refcount_read(&conn->ref));
360357
361
- ASSERTCMP(atomic_read(&conn->usage), ==, 0);
358
+ ASSERTCMP(refcount_read(&conn->ref), ==, 0);
362359
363360 _net("DESTROY CONN %d", conn->debug_id);
364361
....@@ -368,6 +365,7 @@
368365 conn->security->clear(conn);
369366 key_put(conn->params.key);
370367 key_put(conn->server_key);
368
+ rxrpc_put_bundle(conn->bundle);
371369 rxrpc_put_peer(conn->params.peer);
372370
373371 if (atomic_dec_and_test(&conn->params.local->rxnet->nr_conns))
....@@ -397,8 +395,8 @@
397395
398396 write_lock(&rxnet->conn_lock);
399397 list_for_each_entry_safe(conn, _p, &rxnet->service_conns, link) {
400
- ASSERTCMP(atomic_read(&conn->usage), >, 0);
401
- if (likely(atomic_read(&conn->usage) > 1))
398
+ ASSERTCMP(refcount_read(&conn->ref), >, 0);
399
+ if (likely(refcount_read(&conn->ref) > 1))
402400 continue;
403401 if (conn->state == RXRPC_CONN_SERVICE_PREALLOC)
404402 continue;
....@@ -410,7 +408,7 @@
410408 expire_at = idle_timestamp + rxrpc_closed_conn_expiry * HZ;
411409
412410 _debug("reap CONN %d { u=%d,t=%ld }",
413
- conn->debug_id, atomic_read(&conn->usage),
411
+ conn->debug_id, refcount_read(&conn->ref),
414412 (long)expire_at - (long)now);
415413
416414 if (time_before(now, expire_at)) {
....@@ -423,7 +421,7 @@
423421 /* The usage count sits at 1 whilst the object is unused on the
424422 * list; we reduce that to 0 to make the object unavailable.
425423 */
426
- if (atomic_cmpxchg(&conn->usage, 1, 0) != 1)
424
+ if (!refcount_dec_if_one(&conn->ref))
427425 continue;
428426 trace_rxrpc_conn(conn->debug_id, rxrpc_conn_reap_service, 0, NULL);
429427
....@@ -447,7 +445,7 @@
447445 link);
448446 list_del_init(&conn->link);
449447
450
- ASSERTCMP(atomic_read(&conn->usage), ==, 0);
448
+ ASSERTCMP(refcount_read(&conn->ref), ==, 0);
451449 rxrpc_kill_connection(conn);
452450 }
453451
....@@ -475,7 +473,7 @@
475473 write_lock(&rxnet->conn_lock);
476474 list_for_each_entry_safe(conn, _p, &rxnet->service_conns, link) {
477475 pr_err("AF_RXRPC: Leaked conn %p {%d}\n",
478
- conn, atomic_read(&conn->usage));
476
+ conn, refcount_read(&conn->ref));
479477 leak = true;
480478 }
481479 write_unlock(&rxnet->conn_lock);