hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/rxrpc/proc.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* /proc/net/ support for AF_RXRPC
23 *
34 * Copyright (C) 2007 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 #include <linux/module.h>
....@@ -111,7 +107,7 @@
111107 call->cid,
112108 call->call_id,
113109 rxrpc_is_service_call(call) ? "Svc" : "Clt",
114
- atomic_read(&call->usage),
110
+ refcount_read(&call->ref),
115111 rxrpc_call_states[call->state],
116112 call->abort_code,
117113 call->debug_id,
....@@ -169,7 +165,7 @@
169165 "Proto Local "
170166 " Remote "
171167 " SvID ConnID End Use State Key "
172
- " Serial ISerial\n"
168
+ " Serial ISerial CallId0 CallId1 CallId2 CallId3\n"
173169 );
174170 return 0;
175171 }
....@@ -193,7 +189,7 @@
193189 conn->service_id,
194190 conn->proto.cid,
195191 rxrpc_conn_is_service(conn) ? "Svc" : "Clt",
196
- atomic_read(&conn->usage),
192
+ refcount_read(&conn->ref),
197193 rxrpc_conn_states[conn->state],
198194 key_serial(conn->params.key),
199195 atomic_read(&conn->serial),
....@@ -212,3 +208,198 @@
212208 .stop = rxrpc_connection_seq_stop,
213209 .show = rxrpc_connection_seq_show,
214210 };
211
+
212
+/*
213
+ * generate a list of extant virtual peers in /proc/net/rxrpc/peers
214
+ */
215
+static int rxrpc_peer_seq_show(struct seq_file *seq, void *v)
216
+{
217
+ struct rxrpc_peer *peer;
218
+ time64_t now;
219
+ char lbuff[50], rbuff[50];
220
+
221
+ if (v == SEQ_START_TOKEN) {
222
+ seq_puts(seq,
223
+ "Proto Local "
224
+ " Remote "
225
+ " Use CW MTU LastUse RTT RTO\n"
226
+ );
227
+ return 0;
228
+ }
229
+
230
+ peer = list_entry(v, struct rxrpc_peer, hash_link);
231
+
232
+ sprintf(lbuff, "%pISpc", &peer->local->srx.transport);
233
+
234
+ sprintf(rbuff, "%pISpc", &peer->srx.transport);
235
+
236
+ now = ktime_get_seconds();
237
+ seq_printf(seq,
238
+ "UDP %-47.47s %-47.47s %3u"
239
+ " %3u %5u %6llus %8u %8u\n",
240
+ lbuff,
241
+ rbuff,
242
+ refcount_read(&peer->ref),
243
+ peer->cong_cwnd,
244
+ peer->mtu,
245
+ now - peer->last_tx_at,
246
+ peer->srtt_us >> 3,
247
+ jiffies_to_usecs(peer->rto_j));
248
+
249
+ return 0;
250
+}
251
+
252
+static void *rxrpc_peer_seq_start(struct seq_file *seq, loff_t *_pos)
253
+ __acquires(rcu)
254
+{
255
+ struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
256
+ unsigned int bucket, n;
257
+ unsigned int shift = 32 - HASH_BITS(rxnet->peer_hash);
258
+ void *p;
259
+
260
+ rcu_read_lock();
261
+
262
+ if (*_pos >= UINT_MAX)
263
+ return NULL;
264
+
265
+ n = *_pos & ((1U << shift) - 1);
266
+ bucket = *_pos >> shift;
267
+ for (;;) {
268
+ if (bucket >= HASH_SIZE(rxnet->peer_hash)) {
269
+ *_pos = UINT_MAX;
270
+ return NULL;
271
+ }
272
+ if (n == 0) {
273
+ if (bucket == 0)
274
+ return SEQ_START_TOKEN;
275
+ *_pos += 1;
276
+ n++;
277
+ }
278
+
279
+ p = seq_hlist_start_rcu(&rxnet->peer_hash[bucket], n - 1);
280
+ if (p)
281
+ return p;
282
+ bucket++;
283
+ n = 1;
284
+ *_pos = (bucket << shift) | n;
285
+ }
286
+}
287
+
288
+static void *rxrpc_peer_seq_next(struct seq_file *seq, void *v, loff_t *_pos)
289
+{
290
+ struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
291
+ unsigned int bucket, n;
292
+ unsigned int shift = 32 - HASH_BITS(rxnet->peer_hash);
293
+ void *p;
294
+
295
+ if (*_pos >= UINT_MAX)
296
+ return NULL;
297
+
298
+ bucket = *_pos >> shift;
299
+
300
+ p = seq_hlist_next_rcu(v, &rxnet->peer_hash[bucket], _pos);
301
+ if (p)
302
+ return p;
303
+
304
+ for (;;) {
305
+ bucket++;
306
+ n = 1;
307
+ *_pos = (bucket << shift) | n;
308
+
309
+ if (bucket >= HASH_SIZE(rxnet->peer_hash)) {
310
+ *_pos = UINT_MAX;
311
+ return NULL;
312
+ }
313
+ if (n == 0) {
314
+ *_pos += 1;
315
+ n++;
316
+ }
317
+
318
+ p = seq_hlist_start_rcu(&rxnet->peer_hash[bucket], n - 1);
319
+ if (p)
320
+ return p;
321
+ }
322
+}
323
+
324
+static void rxrpc_peer_seq_stop(struct seq_file *seq, void *v)
325
+ __releases(rcu)
326
+{
327
+ rcu_read_unlock();
328
+}
329
+
330
+
331
+const struct seq_operations rxrpc_peer_seq_ops = {
332
+ .start = rxrpc_peer_seq_start,
333
+ .next = rxrpc_peer_seq_next,
334
+ .stop = rxrpc_peer_seq_stop,
335
+ .show = rxrpc_peer_seq_show,
336
+};
337
+
338
+/*
339
+ * Generate a list of extant virtual local endpoints in /proc/net/rxrpc/locals
340
+ */
341
+static int rxrpc_local_seq_show(struct seq_file *seq, void *v)
342
+{
343
+ struct rxrpc_local *local;
344
+ char lbuff[50];
345
+
346
+ if (v == SEQ_START_TOKEN) {
347
+ seq_puts(seq,
348
+ "Proto Local "
349
+ " Use Act\n");
350
+ return 0;
351
+ }
352
+
353
+ local = hlist_entry(v, struct rxrpc_local, link);
354
+
355
+ sprintf(lbuff, "%pISpc", &local->srx.transport);
356
+
357
+ seq_printf(seq,
358
+ "UDP %-47.47s %3u %3u\n",
359
+ lbuff,
360
+ refcount_read(&local->ref),
361
+ atomic_read(&local->active_users));
362
+
363
+ return 0;
364
+}
365
+
366
+static void *rxrpc_local_seq_start(struct seq_file *seq, loff_t *_pos)
367
+ __acquires(rcu)
368
+{
369
+ struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
370
+ unsigned int n;
371
+
372
+ rcu_read_lock();
373
+
374
+ if (*_pos >= UINT_MAX)
375
+ return NULL;
376
+
377
+ n = *_pos;
378
+ if (n == 0)
379
+ return SEQ_START_TOKEN;
380
+
381
+ return seq_hlist_start_rcu(&rxnet->local_endpoints, n - 1);
382
+}
383
+
384
+static void *rxrpc_local_seq_next(struct seq_file *seq, void *v, loff_t *_pos)
385
+{
386
+ struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
387
+
388
+ if (*_pos >= UINT_MAX)
389
+ return NULL;
390
+
391
+ return seq_hlist_next_rcu(v, &rxnet->local_endpoints, _pos);
392
+}
393
+
394
+static void rxrpc_local_seq_stop(struct seq_file *seq, void *v)
395
+ __releases(rcu)
396
+{
397
+ rcu_read_unlock();
398
+}
399
+
400
+const struct seq_operations rxrpc_local_seq_ops = {
401
+ .start = rxrpc_local_seq_start,
402
+ .next = rxrpc_local_seq_next,
403
+ .stop = rxrpc_local_seq_stop,
404
+ .show = rxrpc_local_seq_show,
405
+};