File Index
Files and directories
Sign in
FILE

proc.c

File preview with syntax highlighting.

linux-6.19.14/net/rxrpc/proc.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/* /proc/net/ support for AF_RXRPC
  3 *
  4 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
  5 * Written by David Howells (dhowells@redhat.com)
  6 */
  7
  8#include <linux/module.h>
  9#include <net/sock.h>
 10#include <net/af_rxrpc.h>
 11#include "ar-internal.h"
 12
 13#define RXRPC_PROC_ADDRBUF_SIZE \
 14	(sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + \
 15	 sizeof(":12345"))
 16
 17static const char *const rxrpc_conn_states[RXRPC_CONN__NR_STATES] = {
 18	[RXRPC_CONN_UNUSED]			= "Unused  ",
 19	[RXRPC_CONN_CLIENT_UNSECURED]		= "ClUnsec ",
 20	[RXRPC_CONN_CLIENT]			= "Client  ",
 21	[RXRPC_CONN_SERVICE_PREALLOC]		= "SvPrealc",
 22	[RXRPC_CONN_SERVICE_UNSECURED]		= "SvUnsec ",
 23	[RXRPC_CONN_SERVICE_CHALLENGING]	= "SvChall ",
 24	[RXRPC_CONN_SERVICE]			= "SvSecure",
 25	[RXRPC_CONN_ABORTED]			= "Aborted ",
 26};
 27
 28/*
 29 * generate a list of extant and dead calls in /proc/net/rxrpc_calls
 30 */
 31static void *rxrpc_call_seq_start(struct seq_file *seq, loff_t *_pos)
 32	__acquires(rcu)
 33{
 34	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
 35
 36	rcu_read_lock();
 37	return seq_list_start_head_rcu(&rxnet->calls, *_pos);
 38}
 39
 40static void *rxrpc_call_seq_next(struct seq_file *seq, void *v, loff_t *pos)
 41{
 42	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
 43
 44	return seq_list_next_rcu(v, &rxnet->calls, pos);
 45}
 46
 47static void rxrpc_call_seq_stop(struct seq_file *seq, void *v)
 48	__releases(rcu)
 49{
 50	rcu_read_unlock();
 51}
 52
 53static int rxrpc_call_seq_show(struct seq_file *seq, void *v)
 54{
 55	struct rxrpc_local *local;
 56	struct rxrpc_call *call;
 57	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
 58	enum rxrpc_call_state state;
 59	rxrpc_seq_t tx_bottom;
 60	char lbuff[RXRPC_PROC_ADDRBUF_SIZE], rbuff[RXRPC_PROC_ADDRBUF_SIZE];
 61	long timeout = 0;
 62
 63	if (v == &rxnet->calls) {
 64		seq_puts(seq,
 65			 "Proto Local                                          "
 66			 " Remote                                         "
 67			 " SvID ConnID   CallID   End Use State    Abort   "
 68			 " DebugId  TxSeq    TW RxSeq    RW RxSerial CW RxTimo\n");
 69		return 0;
 70	}
 71
 72	call = list_entry(v, struct rxrpc_call, link);
 73
 74	local = call->local;
 75	if (local)
 76		scnprintf(lbuff, sizeof(lbuff), "%pISpc", &local->srx.transport);
 77	else
 78		strcpy(lbuff, "no_local");
 79
 80	scnprintf(rbuff, sizeof(rbuff), "%pISpc", &call->dest_srx.transport);
 81
 82	state = rxrpc_call_state(call);
 83	if (state != RXRPC_CALL_SERVER_PREALLOC)
 84		timeout = ktime_ms_delta(READ_ONCE(call->expect_rx_by), ktime_get_real());
 85
 86	tx_bottom = READ_ONCE(call->tx_bottom);
 87	seq_printf(seq,
 88		   "UDP   %-47.47s %-47.47s %4x %08x %08x %s %3u"
 89		   " %-8.8s %08x %08x %08x %02x %08x %02x %08x %02x %06lx\n",
 90		   lbuff,
 91		   rbuff,
 92		   call->dest_srx.srx_service,
 93		   call->cid,
 94		   call->call_id,
 95		   rxrpc_is_service_call(call) ? "Svc" : "Clt",
 96		   refcount_read(&call->ref),
 97		   rxrpc_call_states[state],
 98		   call->abort_code,
 99		   call->debug_id,
100		   tx_bottom, READ_ONCE(call->tx_top) - tx_bottom,
101		   call->ackr_window, call->ackr_wtop - call->ackr_window,
102		   call->rx_serial,
103		   call->cong_cwnd,
104		   timeout);
105
106	return 0;
107}
108
109const struct seq_operations rxrpc_call_seq_ops = {
110	.start  = rxrpc_call_seq_start,
111	.next   = rxrpc_call_seq_next,
112	.stop   = rxrpc_call_seq_stop,
113	.show   = rxrpc_call_seq_show,
114};
115
116/*
117 * generate a list of extant virtual connections in /proc/net/rxrpc_conns
118 */
119static void *rxrpc_connection_seq_start(struct seq_file *seq, loff_t *_pos)
120	__acquires(rxnet->conn_lock)
121{
122	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
123
124	read_lock(&rxnet->conn_lock);
125	return seq_list_start_head(&rxnet->conn_proc_list, *_pos);
126}
127
128static void *rxrpc_connection_seq_next(struct seq_file *seq, void *v,
129				       loff_t *pos)
130{
131	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
132
133	return seq_list_next(v, &rxnet->conn_proc_list, pos);
134}
135
136static void rxrpc_connection_seq_stop(struct seq_file *seq, void *v)
137	__releases(rxnet->conn_lock)
138{
139	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
140
141	read_unlock(&rxnet->conn_lock);
142}
143
144static int rxrpc_connection_seq_show(struct seq_file *seq, void *v)
145{
146	struct rxrpc_connection *conn;
147	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
148	const char *state;
149	char lbuff[RXRPC_PROC_ADDRBUF_SIZE], rbuff[RXRPC_PROC_ADDRBUF_SIZE];
150
151	if (v == &rxnet->conn_proc_list) {
152		seq_puts(seq,
153			 "Proto Local                                          "
154			 " Remote                                         "
155			 " SvID ConnID   End Ref Act State    Key     "
156			 " Serial   ISerial  CallId0  CallId1  CallId2  CallId3\n"
157			 );
158		return 0;
159	}
160
161	conn = list_entry(v, struct rxrpc_connection, proc_link);
162	if (conn->state == RXRPC_CONN_SERVICE_PREALLOC) {
163		strcpy(lbuff, "no_local");
164		strcpy(rbuff, "no_connection");
165		goto print;
166	}
167
168	scnprintf(lbuff, sizeof(lbuff), "%pISpc", &conn->local->srx.transport);
169	scnprintf(rbuff, sizeof(rbuff), "%pISpc", &conn->peer->srx.transport);
170print:
171	state = rxrpc_is_conn_aborted(conn) ?
172		rxrpc_call_completions[conn->completion] :
173		rxrpc_conn_states[conn->state];
174	seq_printf(seq,
175		   "UDP   %-47.47s %-47.47s %4x %08x %s %3u %3d"
176		   " %s %08x %08x %08x %08x %08x %08x %08x\n",
177		   lbuff,
178		   rbuff,
179		   conn->service_id,
180		   conn->proto.cid,
181		   rxrpc_conn_is_service(conn) ? "Svc" : "Clt",
182		   refcount_read(&conn->ref),
183		   atomic_read(&conn->active),
184		   state,
185		   key_serial(conn->key),
186		   conn->tx_serial,
187		   conn->hi_serial,
188		   conn->channels[0].call_id,
189		   conn->channels[1].call_id,
190		   conn->channels[2].call_id,
191		   conn->channels[3].call_id);
192
193	return 0;
194}
195
196const struct seq_operations rxrpc_connection_seq_ops = {
197	.start  = rxrpc_connection_seq_start,
198	.next   = rxrpc_connection_seq_next,
199	.stop   = rxrpc_connection_seq_stop,
200	.show   = rxrpc_connection_seq_show,
201};
202
203/*
204 * generate a list of extant virtual bundles in /proc/net/rxrpc/bundles
205 */
206static void *rxrpc_bundle_seq_start(struct seq_file *seq, loff_t *_pos)
207	__acquires(rxnet->conn_lock)
208{
209	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
210
211	read_lock(&rxnet->conn_lock);
212	return seq_list_start_head(&rxnet->bundle_proc_list, *_pos);
213}
214
215static void *rxrpc_bundle_seq_next(struct seq_file *seq, void *v,
216				       loff_t *pos)
217{
218	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
219
220	return seq_list_next(v, &rxnet->bundle_proc_list, pos);
221}
222
223static void rxrpc_bundle_seq_stop(struct seq_file *seq, void *v)
224	__releases(rxnet->conn_lock)
225{
226	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
227
228	read_unlock(&rxnet->conn_lock);
229}
230
231static int rxrpc_bundle_seq_show(struct seq_file *seq, void *v)
232{
233	struct rxrpc_bundle *bundle;
234	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
235	char lbuff[RXRPC_PROC_ADDRBUF_SIZE], rbuff[RXRPC_PROC_ADDRBUF_SIZE];
236
237	if (v == &rxnet->bundle_proc_list) {
238		seq_puts(seq,
239			 "Proto Local                                          "
240			 " Remote                                         "
241			 " SvID Ref Act Flg Key      |"
242			 " Bundle   Conn_0   Conn_1   Conn_2   Conn_3\n"
243			 );
244		return 0;
245	}
246
247	bundle = list_entry(v, struct rxrpc_bundle, proc_link);
248
249	scnprintf(lbuff, sizeof(lbuff), "%pISpc", &bundle->local->srx.transport);
250	scnprintf(rbuff, sizeof(rbuff), "%pISpc", &bundle->peer->srx.transport);
251	seq_printf(seq,
252		   "UDP   %-47.47s %-47.47s %4x %3u %3d"
253		   " %c%c%c %08x | %08x %08x %08x %08x %08x\n",
254		   lbuff,
255		   rbuff,
256		   bundle->service_id,
257		   refcount_read(&bundle->ref),
258		   atomic_read(&bundle->active),
259		   bundle->try_upgrade ? 'U' : '-',
260		   bundle->exclusive ? 'e' : '-',
261		   bundle->upgrade ? 'u' : '-',
262		   key_serial(bundle->key),
263		   bundle->debug_id,
264		   bundle->conn_ids[0],
265		   bundle->conn_ids[1],
266		   bundle->conn_ids[2],
267		   bundle->conn_ids[3]);
268
269	return 0;
270}
271
272const struct seq_operations rxrpc_bundle_seq_ops = {
273	.start  = rxrpc_bundle_seq_start,
274	.next   = rxrpc_bundle_seq_next,
275	.stop   = rxrpc_bundle_seq_stop,
276	.show   = rxrpc_bundle_seq_show,
277};
278
279/*
280 * generate a list of extant virtual peers in /proc/net/rxrpc/peers
281 */
282static int rxrpc_peer_seq_show(struct seq_file *seq, void *v)
283{
284	struct rxrpc_peer *peer;
285	time64_t now;
286	char lbuff[RXRPC_PROC_ADDRBUF_SIZE], rbuff[RXRPC_PROC_ADDRBUF_SIZE];
287
288	if (v == SEQ_START_TOKEN) {
289		seq_puts(seq,
290			 "Proto Local                                           Remote                                          Use SST   Maxd LastUse      RTT      RTO\n"
291			 );
292		return 0;
293	}
294
295	peer = list_entry(v, struct rxrpc_peer, hash_link);
296
297	scnprintf(lbuff, sizeof(lbuff), "%pISpc", &peer->local->srx.transport);
298
299	scnprintf(rbuff, sizeof(rbuff), "%pISpc", &peer->srx.transport);
300
301	now = ktime_get_seconds();
302	seq_printf(seq,
303		   "UDP   %-47.47s %-47.47s %3u %4u %5u %6ds %8d %8d\n",
304		   lbuff,
305		   rbuff,
306		   refcount_read(&peer->ref),
307		   peer->cong_ssthresh,
308		   peer->max_data,
309		   (s32)now - (s32)READ_ONCE(peer->last_tx_at),
310		   READ_ONCE(peer->recent_srtt_us),
311		   READ_ONCE(peer->recent_rto_us));
312
313	return 0;
314}
315
316static void *rxrpc_peer_seq_start(struct seq_file *seq, loff_t *_pos)
317	__acquires(rcu)
318{
319	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
320	unsigned int bucket, n;
321	unsigned int shift = 32 - HASH_BITS(rxnet->peer_hash);
322	void *p;
323
324	rcu_read_lock();
325
326	if (*_pos >= UINT_MAX)
327		return NULL;
328
329	n = *_pos & ((1U << shift) - 1);
330	bucket = *_pos >> shift;
331	for (;;) {
332		if (bucket >= HASH_SIZE(rxnet->peer_hash)) {
333			*_pos = UINT_MAX;
334			return NULL;
335		}
336		if (n == 0) {
337			if (bucket == 0)
338				return SEQ_START_TOKEN;
339			*_pos += 1;
340			n++;
341		}
342
343		p = seq_hlist_start_rcu(&rxnet->peer_hash[bucket], n - 1);
344		if (p)
345			return p;
346		bucket++;
347		n = 1;
348		*_pos = (bucket << shift) | n;
349	}
350}
351
352static void *rxrpc_peer_seq_next(struct seq_file *seq, void *v, loff_t *_pos)
353{
354	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
355	unsigned int bucket, n;
356	unsigned int shift = 32 - HASH_BITS(rxnet->peer_hash);
357	void *p;
358
359	if (*_pos >= UINT_MAX)
360		return NULL;
361
362	bucket = *_pos >> shift;
363
364	p = seq_hlist_next_rcu(v, &rxnet->peer_hash[bucket], _pos);
365	if (p)
366		return p;
367
368	for (;;) {
369		bucket++;
370		n = 1;
371		*_pos = (bucket << shift) | n;
372
373		if (bucket >= HASH_SIZE(rxnet->peer_hash)) {
374			*_pos = UINT_MAX;
375			return NULL;
376		}
377		if (n == 0) {
378			*_pos += 1;
379			n++;
380		}
381
382		p = seq_hlist_start_rcu(&rxnet->peer_hash[bucket], n - 1);
383		if (p)
384			return p;
385	}
386}
387
388static void rxrpc_peer_seq_stop(struct seq_file *seq, void *v)
389	__releases(rcu)
390{
391	rcu_read_unlock();
392}
393
394
395const struct seq_operations rxrpc_peer_seq_ops = {
396	.start  = rxrpc_peer_seq_start,
397	.next   = rxrpc_peer_seq_next,
398	.stop   = rxrpc_peer_seq_stop,
399	.show   = rxrpc_peer_seq_show,
400};
401
402/*
403 * Generate a list of extant virtual local endpoints in /proc/net/rxrpc/locals
404 */
405static int rxrpc_local_seq_show(struct seq_file *seq, void *v)
406{
407	struct rxrpc_local *local;
408	char lbuff[RXRPC_PROC_ADDRBUF_SIZE];
409
410	if (v == SEQ_START_TOKEN) {
411		seq_puts(seq,
412			 "Proto Local                                          "
413			 " Use Act RxQ\n");
414		return 0;
415	}
416
417	local = hlist_entry(v, struct rxrpc_local, link);
418
419	scnprintf(lbuff, sizeof(lbuff), "%pISpc", &local->srx.transport);
420
421	seq_printf(seq,
422		   "UDP   %-47.47s %3u %3u %3u\n",
423		   lbuff,
424		   refcount_read(&local->ref),
425		   atomic_read(&local->active_users),
426		   local->rx_queue.qlen);
427
428	return 0;
429}
430
431static void *rxrpc_local_seq_start(struct seq_file *seq, loff_t *_pos)
432	__acquires(rcu)
433{
434	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
435	unsigned int n;
436
437	rcu_read_lock();
438
439	if (*_pos >= UINT_MAX)
440		return NULL;
441
442	n = *_pos;
443	if (n == 0)
444		return SEQ_START_TOKEN;
445
446	return seq_hlist_start_rcu(&rxnet->local_endpoints, n - 1);
447}
448
449static void *rxrpc_local_seq_next(struct seq_file *seq, void *v, loff_t *_pos)
450{
451	struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
452
453	if (*_pos >= UINT_MAX)
454		return NULL;
455
456	return seq_hlist_next_rcu(v, &rxnet->local_endpoints, _pos);
457}
458
459static void rxrpc_local_seq_stop(struct seq_file *seq, void *v)
460	__releases(rcu)
461{
462	rcu_read_unlock();
463}
464
465const struct seq_operations rxrpc_local_seq_ops = {
466	.start  = rxrpc_local_seq_start,
467	.next   = rxrpc_local_seq_next,
468	.stop   = rxrpc_local_seq_stop,
469	.show   = rxrpc_local_seq_show,
470};
471
472/*
473 * Display stats in /proc/net/rxrpc/stats
474 */
475int rxrpc_stats_show(struct seq_file *seq, void *v)
476{
477	struct rxrpc_net *rxnet = rxrpc_net(seq_file_single_net(seq));
478
479	seq_printf(seq,
480		   "Data     : send=%u sendf=%u fail=%u emsz=%u\n",
481		   atomic_read(&rxnet->stat_tx_data_send),
482		   atomic_read(&rxnet->stat_tx_data_send_frag),
483		   atomic_read(&rxnet->stat_tx_data_send_fail),
484		   atomic_read(&rxnet->stat_tx_data_send_msgsize));
485	seq_printf(seq,
486		   "Data-Tx  : nr=%u retrans=%u uf=%u cwr=%u\n",
487		   atomic_read(&rxnet->stat_tx_data),
488		   atomic_read(&rxnet->stat_tx_data_retrans),
489		   atomic_read(&rxnet->stat_tx_data_underflow),
490		   atomic_read(&rxnet->stat_tx_data_cwnd_reset));
491	seq_printf(seq,
492		   "Data-Rx  : nr=%u reqack=%u jumbo=%u\n",
493		   atomic_read(&rxnet->stat_rx_data),
494		   atomic_read(&rxnet->stat_rx_data_reqack),
495		   atomic_read(&rxnet->stat_rx_data_jumbo));
496	seq_printf(seq,
497		   "Ack      : fill=%u send=%u skip=%u\n",
498		   atomic_read(&rxnet->stat_tx_ack_fill),
499		   atomic_read(&rxnet->stat_tx_ack_send),
500		   atomic_read(&rxnet->stat_tx_ack_skip));
501	seq_printf(seq,
502		   "Ack-Tx   : req=%u dup=%u oos=%u exw=%u nos=%u png=%u prs=%u dly=%u idl=%u\n",
503		   atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_REQUESTED]),
504		   atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_DUPLICATE]),
505		   atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_OUT_OF_SEQUENCE]),
506		   atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_EXCEEDS_WINDOW]),
507		   atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_NOSPACE]),
508		   atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_PING]),
509		   atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_PING_RESPONSE]),
510		   atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_DELAY]),
511		   atomic_read(&rxnet->stat_tx_acks[RXRPC_ACK_IDLE]));
512	seq_printf(seq,
513		   "Ack-Rx   : req=%u dup=%u oos=%u exw=%u nos=%u png=%u prs=%u dly=%u idl=%u z=%u\n",
514		   atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_REQUESTED]),
515		   atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_DUPLICATE]),
516		   atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_OUT_OF_SEQUENCE]),
517		   atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_EXCEEDS_WINDOW]),
518		   atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_NOSPACE]),
519		   atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_PING]),
520		   atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_PING_RESPONSE]),
521		   atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_DELAY]),
522		   atomic_read(&rxnet->stat_rx_acks[RXRPC_ACK_IDLE]),
523		   atomic_read(&rxnet->stat_rx_acks[0]));
524	seq_printf(seq,
525		   "Why-Req-A: acklost=%u mrtt=%u ortt=%u stall=%u jwin=%u\n",
526		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_ack_lost]),
527		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_more_rtt]),
528		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_old_rtt]),
529		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_app_stall]),
530		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_jumbo_win]));
531	seq_printf(seq,
532		   "Why-Req-A: nolast=%u retx=%u slows=%u smtxw=%u\n",
533		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_no_srv_last]),
534		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_retrans]),
535		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_slow_start]),
536		   atomic_read(&rxnet->stat_why_req_ack[rxrpc_reqack_small_txwin]));
537	seq_printf(seq,
538		   "Jumbo-Tx : %u,%u,%u,%u,%u,%u,%u,%u,%u,%u\n",
539		   atomic_read(&rxnet->stat_tx_jumbo[0]),
540		   atomic_read(&rxnet->stat_tx_jumbo[1]),
541		   atomic_read(&rxnet->stat_tx_jumbo[2]),
542		   atomic_read(&rxnet->stat_tx_jumbo[3]),
543		   atomic_read(&rxnet->stat_tx_jumbo[4]),
544		   atomic_read(&rxnet->stat_tx_jumbo[5]),
545		   atomic_read(&rxnet->stat_tx_jumbo[6]),
546		   atomic_read(&rxnet->stat_tx_jumbo[7]),
547		   atomic_read(&rxnet->stat_tx_jumbo[8]),
548		   atomic_read(&rxnet->stat_tx_jumbo[9]));
549	seq_printf(seq,
550		   "Jumbo-Rx : %u,%u,%u,%u,%u,%u,%u,%u,%u,%u\n",
551		   atomic_read(&rxnet->stat_rx_jumbo[0]),
552		   atomic_read(&rxnet->stat_rx_jumbo[1]),
553		   atomic_read(&rxnet->stat_rx_jumbo[2]),
554		   atomic_read(&rxnet->stat_rx_jumbo[3]),
555		   atomic_read(&rxnet->stat_rx_jumbo[4]),
556		   atomic_read(&rxnet->stat_rx_jumbo[5]),
557		   atomic_read(&rxnet->stat_rx_jumbo[6]),
558		   atomic_read(&rxnet->stat_rx_jumbo[7]),
559		   atomic_read(&rxnet->stat_rx_jumbo[8]),
560		   atomic_read(&rxnet->stat_rx_jumbo[9]));
561	seq_printf(seq,
562		   "Buffers  : txb=%u rxb=%u\n",
563		   atomic_read(&rxrpc_nr_txbuf),
564		   atomic_read(&rxrpc_n_rx_skbs));
565	seq_printf(seq,
566		   "IO-thread: loops=%u\n",
567		   atomic_read(&rxnet->stat_io_loop));
568	return 0;
569}
570
571/*
572 * Clear stats if /proc/net/rxrpc/stats is written to.
573 */
574int rxrpc_stats_clear(struct file *file, char *buf, size_t size)
575{
576	struct seq_file *m = file->private_data;
577	struct rxrpc_net *rxnet = rxrpc_net(seq_file_single_net(m));
578
579	if (size > 1 || (size == 1 && buf[0] != '\n'))
580		return -EINVAL;
581
582	atomic_set(&rxnet->stat_tx_data, 0);
583	atomic_set(&rxnet->stat_tx_data_retrans, 0);
584	atomic_set(&rxnet->stat_tx_data_underflow, 0);
585	atomic_set(&rxnet->stat_tx_data_cwnd_reset, 0);
586	atomic_set(&rxnet->stat_tx_data_send, 0);
587	atomic_set(&rxnet->stat_tx_data_send_frag, 0);
588	atomic_set(&rxnet->stat_tx_data_send_fail, 0);
589	atomic_set(&rxnet->stat_rx_data, 0);
590	atomic_set(&rxnet->stat_rx_data_reqack, 0);
591	atomic_set(&rxnet->stat_rx_data_jumbo, 0);
592
593	atomic_set(&rxnet->stat_tx_ack_fill, 0);
594	atomic_set(&rxnet->stat_tx_ack_send, 0);
595	atomic_set(&rxnet->stat_tx_ack_skip, 0);
596	memset(&rxnet->stat_tx_acks, 0, sizeof(rxnet->stat_tx_acks));
597	memset(&rxnet->stat_rx_acks, 0, sizeof(rxnet->stat_rx_acks));
598	memset(&rxnet->stat_tx_jumbo, 0, sizeof(rxnet->stat_tx_jumbo));
599	memset(&rxnet->stat_rx_jumbo, 0, sizeof(rxnet->stat_rx_jumbo));
600
601	memset(&rxnet->stat_why_req_ack, 0, sizeof(rxnet->stat_why_req_ack));
602
603	atomic_set(&rxnet->stat_io_loop, 0);
604	return size;
605}
~/ Read-only file preview.