hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/net/rxrpc/local_object.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* Local endpoint object management
23 *
34 * Copyright (C) 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 Licence
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the Licence, or (at your option) any later version.
106 */
117
128 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -82,16 +78,16 @@
8278
8379 local = kzalloc(sizeof(struct rxrpc_local), GFP_KERNEL);
8480 if (local) {
85
- atomic_set(&local->usage, 1);
81
+ refcount_set(&local->ref, 1);
8682 atomic_set(&local->active_users, 1);
8783 local->rxnet = rxnet;
88
- INIT_LIST_HEAD(&local->link);
84
+ INIT_HLIST_NODE(&local->link);
8985 INIT_WORK(&local->processor, rxrpc_local_processor);
9086 init_rwsem(&local->defrag_sem);
9187 skb_queue_head_init(&local->reject_queue);
9288 skb_queue_head_init(&local->event_queue);
93
- local->client_conns = RB_ROOT;
94
- spin_lock_init(&local->client_conns_lock);
89
+ local->client_bundles = RB_ROOT;
90
+ spin_lock_init(&local->client_bundles_lock);
9591 spin_lock_init(&local->lock);
9692 rwlock_init(&local->services_lock);
9793 local->debug_id = atomic_inc_return(&rxrpc_debug_id);
....@@ -111,7 +107,7 @@
111107 static int rxrpc_open_socket(struct rxrpc_local *local, struct net *net)
112108 {
113109 struct sock *usk;
114
- int ret, opt;
110
+ int ret;
115111
116112 _enter("%p{%d,%d}",
117113 local, local->srx.transport_type, local->srx.transport.family);
....@@ -161,45 +157,21 @@
161157 switch (local->srx.transport.family) {
162158 case AF_INET6:
163159 /* we want to receive ICMPv6 errors */
164
- opt = 1;
165
- ret = kernel_setsockopt(local->socket, SOL_IPV6, IPV6_RECVERR,
166
- (char *) &opt, sizeof(opt));
167
- if (ret < 0) {
168
- _debug("setsockopt failed");
169
- goto error;
170
- }
160
+ ip6_sock_set_recverr(local->socket->sk);
171161
172162 /* Fall through and set IPv4 options too otherwise we don't get
173163 * errors from IPv4 packets sent through the IPv6 socket.
174164 */
175
-
165
+ fallthrough;
176166 case AF_INET:
177167 /* we want to receive ICMP errors */
178
- opt = 1;
179
- ret = kernel_setsockopt(local->socket, SOL_IP, IP_RECVERR,
180
- (char *) &opt, sizeof(opt));
181
- if (ret < 0) {
182
- _debug("setsockopt failed");
183
- goto error;
184
- }
168
+ ip_sock_set_recverr(local->socket->sk);
185169
186170 /* we want to set the don't fragment bit */
187
- opt = IP_PMTUDISC_DO;
188
- ret = kernel_setsockopt(local->socket, SOL_IP, IP_MTU_DISCOVER,
189
- (char *) &opt, sizeof(opt));
190
- if (ret < 0) {
191
- _debug("setsockopt failed");
192
- goto error;
193
- }
171
+ ip_sock_set_mtu_discover(local->socket->sk, IP_PMTUDISC_DO);
194172
195173 /* We want receive timestamps. */
196
- opt = 1;
197
- ret = kernel_setsockopt(local->socket, SOL_SOCKET, SO_TIMESTAMPNS,
198
- (char *)&opt, sizeof(opt));
199
- if (ret < 0) {
200
- _debug("setsockopt failed");
201
- goto error;
202
- }
174
+ sock_enable_timestamps(local->socket->sk);
203175 break;
204176
205177 default:
....@@ -227,7 +199,7 @@
227199 {
228200 struct rxrpc_local *local;
229201 struct rxrpc_net *rxnet = rxrpc_net(net);
230
- struct list_head *cursor;
202
+ struct hlist_node *cursor;
231203 const char *age;
232204 long diff;
233205 int ret;
....@@ -237,16 +209,12 @@
237209
238210 mutex_lock(&rxnet->local_mutex);
239211
240
- for (cursor = rxnet->local_endpoints.next;
241
- cursor != &rxnet->local_endpoints;
242
- cursor = cursor->next) {
243
- local = list_entry(cursor, struct rxrpc_local, link);
212
+ hlist_for_each(cursor, &rxnet->local_endpoints) {
213
+ local = hlist_entry(cursor, struct rxrpc_local, link);
244214
245215 diff = rxrpc_local_cmp_key(local, srx);
246
- if (diff < 0)
216
+ if (diff != 0)
247217 continue;
248
- if (diff > 0)
249
- break;
250218
251219 /* Services aren't allowed to share transport sockets, so
252220 * reject that here. It is possible that the object is dying -
....@@ -258,9 +226,10 @@
258226 goto addr_in_use;
259227 }
260228
261
- /* Found a match. We replace a dying object. Attempting to
262
- * bind the transport socket may still fail if we're attempting
263
- * to use a local address that the dying object is still using.
229
+ /* Found a match. We want to replace a dying object.
230
+ * Attempting to bind the transport socket may still fail if
231
+ * we're attempting to use a local address that the dying
232
+ * object is still using.
264233 */
265234 if (!rxrpc_use_local(local))
266235 break;
....@@ -277,10 +246,12 @@
277246 if (ret < 0)
278247 goto sock_error;
279248
280
- if (cursor != &rxnet->local_endpoints)
281
- list_replace_init(cursor, &local->link);
282
- else
283
- list_add_tail(&local->link, cursor);
249
+ if (cursor) {
250
+ hlist_replace_rcu(cursor, &local->link);
251
+ cursor->pprev = NULL;
252
+ } else {
253
+ hlist_add_head_rcu(&local->link, &rxnet->local_endpoints);
254
+ }
284255 age = "new";
285256
286257 found:
....@@ -313,10 +284,10 @@
313284 struct rxrpc_local *rxrpc_get_local(struct rxrpc_local *local)
314285 {
315286 const void *here = __builtin_return_address(0);
316
- int n;
287
+ int r;
317288
318
- n = atomic_inc_return(&local->usage);
319
- trace_rxrpc_local(local->debug_id, rxrpc_local_got, n, here);
289
+ __refcount_inc(&local->ref, &r);
290
+ trace_rxrpc_local(local->debug_id, rxrpc_local_got, r + 1, here);
320291 return local;
321292 }
322293
....@@ -326,12 +297,12 @@
326297 struct rxrpc_local *rxrpc_get_local_maybe(struct rxrpc_local *local)
327298 {
328299 const void *here = __builtin_return_address(0);
300
+ int r;
329301
330302 if (local) {
331
- int n = atomic_fetch_add_unless(&local->usage, 1, 0);
332
- if (n > 0)
303
+ if (__refcount_inc_not_zero(&local->ref, &r))
333304 trace_rxrpc_local(local->debug_id, rxrpc_local_got,
334
- n + 1, here);
305
+ r + 1, here);
335306 else
336307 local = NULL;
337308 }
....@@ -345,10 +316,10 @@
345316 {
346317 const void *here = __builtin_return_address(0);
347318 unsigned int debug_id = local->debug_id;
348
- int n = atomic_read(&local->usage);
319
+ int r = refcount_read(&local->ref);
349320
350321 if (rxrpc_queue_work(&local->processor))
351
- trace_rxrpc_local(debug_id, rxrpc_local_queued, n, here);
322
+ trace_rxrpc_local(debug_id, rxrpc_local_queued, r + 1, here);
352323 else
353324 rxrpc_put_local(local);
354325 }
....@@ -360,15 +331,16 @@
360331 {
361332 const void *here = __builtin_return_address(0);
362333 unsigned int debug_id;
363
- int n;
334
+ bool dead;
335
+ int r;
364336
365337 if (local) {
366338 debug_id = local->debug_id;
367339
368
- n = atomic_dec_return(&local->usage);
369
- trace_rxrpc_local(debug_id, rxrpc_local_put, n, here);
340
+ dead = __refcount_dec_and_test(&local->ref, &r);
341
+ trace_rxrpc_local(debug_id, rxrpc_local_put, r, here);
370342
371
- if (n == 0)
343
+ if (dead)
372344 call_rcu(&local->rcu, rxrpc_local_rcu);
373345 }
374346 }
....@@ -421,7 +393,7 @@
421393 local->dead = true;
422394
423395 mutex_lock(&rxnet->local_mutex);
424
- list_del_init(&local->link);
396
+ hlist_del_init_rcu(&local->link);
425397 mutex_unlock(&rxnet->local_mutex);
426398
427399 rxrpc_clean_up_local_conns(local);
....@@ -452,8 +424,11 @@
452424 container_of(work, struct rxrpc_local, processor);
453425 bool again;
454426
427
+ if (local->dead)
428
+ return;
429
+
455430 trace_rxrpc_local(local->debug_id, rxrpc_local_processing,
456
- atomic_read(&local->usage), NULL);
431
+ refcount_read(&local->ref), NULL);
457432
458433 do {
459434 again = false;
....@@ -505,11 +480,11 @@
505480
506481 flush_workqueue(rxrpc_workqueue);
507482
508
- if (!list_empty(&rxnet->local_endpoints)) {
483
+ if (!hlist_empty(&rxnet->local_endpoints)) {
509484 mutex_lock(&rxnet->local_mutex);
510
- list_for_each_entry(local, &rxnet->local_endpoints, link) {
485
+ hlist_for_each_entry(local, &rxnet->local_endpoints, link) {
511486 pr_err("AF_RXRPC: Leaked local %p {%d}\n",
512
- local, atomic_read(&local->usage));
487
+ local, refcount_read(&local->ref));
513488 }
514489 mutex_unlock(&rxnet->local_mutex);
515490 BUG();