ia64/linux-2.6.18-xen.hg

annotate net/rxrpc/proc.c @ 871:9cbcc9008446

xen/x86: don't initialize cpu_data[]'s apicid field on generic code

Afaict, this is not only redundant with the intialization done in
drivers/xen/core/smpboot.c, but actually results - at least for
secondary CPUs - in the Xen-specific value written to be later
overwritten with whatever the generic code determines (with no
guarantee that the two values are identical).

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu May 14 10:09:15 2009 +0100 (2009-05-14)
parents 831230e53067
children
rev   line source
ian@0 1 /* proc.c: /proc interface for RxRPC
ian@0 2 *
ian@0 3 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
ian@0 4 * Written by David Howells (dhowells@redhat.com)
ian@0 5 *
ian@0 6 * This program is free software; you can redistribute it and/or
ian@0 7 * modify it under the terms of the GNU General Public License
ian@0 8 * as published by the Free Software Foundation; either version
ian@0 9 * 2 of the License, or (at your option) any later version.
ian@0 10 */
ian@0 11
ian@0 12 #include <linux/sched.h>
ian@0 13 #include <linux/slab.h>
ian@0 14 #include <linux/module.h>
ian@0 15 #include <linux/proc_fs.h>
ian@0 16 #include <linux/seq_file.h>
ian@0 17 #include <rxrpc/rxrpc.h>
ian@0 18 #include <rxrpc/transport.h>
ian@0 19 #include <rxrpc/peer.h>
ian@0 20 #include <rxrpc/connection.h>
ian@0 21 #include <rxrpc/call.h>
ian@0 22 #include <rxrpc/message.h>
ian@0 23 #include "internal.h"
ian@0 24
ian@0 25 static struct proc_dir_entry *proc_rxrpc;
ian@0 26
ian@0 27 static int rxrpc_proc_transports_open(struct inode *inode, struct file *file);
ian@0 28 static void *rxrpc_proc_transports_start(struct seq_file *p, loff_t *pos);
ian@0 29 static void *rxrpc_proc_transports_next(struct seq_file *p, void *v, loff_t *pos);
ian@0 30 static void rxrpc_proc_transports_stop(struct seq_file *p, void *v);
ian@0 31 static int rxrpc_proc_transports_show(struct seq_file *m, void *v);
ian@0 32
ian@0 33 static struct seq_operations rxrpc_proc_transports_ops = {
ian@0 34 .start = rxrpc_proc_transports_start,
ian@0 35 .next = rxrpc_proc_transports_next,
ian@0 36 .stop = rxrpc_proc_transports_stop,
ian@0 37 .show = rxrpc_proc_transports_show,
ian@0 38 };
ian@0 39
ian@0 40 static struct file_operations rxrpc_proc_transports_fops = {
ian@0 41 .open = rxrpc_proc_transports_open,
ian@0 42 .read = seq_read,
ian@0 43 .llseek = seq_lseek,
ian@0 44 .release = seq_release,
ian@0 45 };
ian@0 46
ian@0 47 static int rxrpc_proc_peers_open(struct inode *inode, struct file *file);
ian@0 48 static void *rxrpc_proc_peers_start(struct seq_file *p, loff_t *pos);
ian@0 49 static void *rxrpc_proc_peers_next(struct seq_file *p, void *v, loff_t *pos);
ian@0 50 static void rxrpc_proc_peers_stop(struct seq_file *p, void *v);
ian@0 51 static int rxrpc_proc_peers_show(struct seq_file *m, void *v);
ian@0 52
ian@0 53 static struct seq_operations rxrpc_proc_peers_ops = {
ian@0 54 .start = rxrpc_proc_peers_start,
ian@0 55 .next = rxrpc_proc_peers_next,
ian@0 56 .stop = rxrpc_proc_peers_stop,
ian@0 57 .show = rxrpc_proc_peers_show,
ian@0 58 };
ian@0 59
ian@0 60 static struct file_operations rxrpc_proc_peers_fops = {
ian@0 61 .open = rxrpc_proc_peers_open,
ian@0 62 .read = seq_read,
ian@0 63 .llseek = seq_lseek,
ian@0 64 .release = seq_release,
ian@0 65 };
ian@0 66
ian@0 67 static int rxrpc_proc_conns_open(struct inode *inode, struct file *file);
ian@0 68 static void *rxrpc_proc_conns_start(struct seq_file *p, loff_t *pos);
ian@0 69 static void *rxrpc_proc_conns_next(struct seq_file *p, void *v, loff_t *pos);
ian@0 70 static void rxrpc_proc_conns_stop(struct seq_file *p, void *v);
ian@0 71 static int rxrpc_proc_conns_show(struct seq_file *m, void *v);
ian@0 72
ian@0 73 static struct seq_operations rxrpc_proc_conns_ops = {
ian@0 74 .start = rxrpc_proc_conns_start,
ian@0 75 .next = rxrpc_proc_conns_next,
ian@0 76 .stop = rxrpc_proc_conns_stop,
ian@0 77 .show = rxrpc_proc_conns_show,
ian@0 78 };
ian@0 79
ian@0 80 static struct file_operations rxrpc_proc_conns_fops = {
ian@0 81 .open = rxrpc_proc_conns_open,
ian@0 82 .read = seq_read,
ian@0 83 .llseek = seq_lseek,
ian@0 84 .release = seq_release,
ian@0 85 };
ian@0 86
ian@0 87 static int rxrpc_proc_calls_open(struct inode *inode, struct file *file);
ian@0 88 static void *rxrpc_proc_calls_start(struct seq_file *p, loff_t *pos);
ian@0 89 static void *rxrpc_proc_calls_next(struct seq_file *p, void *v, loff_t *pos);
ian@0 90 static void rxrpc_proc_calls_stop(struct seq_file *p, void *v);
ian@0 91 static int rxrpc_proc_calls_show(struct seq_file *m, void *v);
ian@0 92
ian@0 93 static struct seq_operations rxrpc_proc_calls_ops = {
ian@0 94 .start = rxrpc_proc_calls_start,
ian@0 95 .next = rxrpc_proc_calls_next,
ian@0 96 .stop = rxrpc_proc_calls_stop,
ian@0 97 .show = rxrpc_proc_calls_show,
ian@0 98 };
ian@0 99
ian@0 100 static struct file_operations rxrpc_proc_calls_fops = {
ian@0 101 .open = rxrpc_proc_calls_open,
ian@0 102 .read = seq_read,
ian@0 103 .llseek = seq_lseek,
ian@0 104 .release = seq_release,
ian@0 105 };
ian@0 106
ian@0 107 static const char *rxrpc_call_states7[] = {
ian@0 108 "complet",
ian@0 109 "error ",
ian@0 110 "rcv_op ",
ian@0 111 "rcv_arg",
ian@0 112 "got_arg",
ian@0 113 "snd_rpl",
ian@0 114 "fin_ack",
ian@0 115 "snd_arg",
ian@0 116 "rcv_rpl",
ian@0 117 "got_rpl"
ian@0 118 };
ian@0 119
ian@0 120 static const char *rxrpc_call_error_states7[] = {
ian@0 121 "no_err ",
ian@0 122 "loc_abt",
ian@0 123 "rmt_abt",
ian@0 124 "loc_err",
ian@0 125 "rmt_err"
ian@0 126 };
ian@0 127
ian@0 128 /*****************************************************************************/
ian@0 129 /*
ian@0 130 * initialise the /proc/net/rxrpc/ directory
ian@0 131 */
ian@0 132 int rxrpc_proc_init(void)
ian@0 133 {
ian@0 134 struct proc_dir_entry *p;
ian@0 135
ian@0 136 proc_rxrpc = proc_mkdir("rxrpc", proc_net);
ian@0 137 if (!proc_rxrpc)
ian@0 138 goto error;
ian@0 139 proc_rxrpc->owner = THIS_MODULE;
ian@0 140
ian@0 141 p = create_proc_entry("calls", 0, proc_rxrpc);
ian@0 142 if (!p)
ian@0 143 goto error_proc;
ian@0 144 p->proc_fops = &rxrpc_proc_calls_fops;
ian@0 145 p->owner = THIS_MODULE;
ian@0 146
ian@0 147 p = create_proc_entry("connections", 0, proc_rxrpc);
ian@0 148 if (!p)
ian@0 149 goto error_calls;
ian@0 150 p->proc_fops = &rxrpc_proc_conns_fops;
ian@0 151 p->owner = THIS_MODULE;
ian@0 152
ian@0 153 p = create_proc_entry("peers", 0, proc_rxrpc);
ian@0 154 if (!p)
ian@0 155 goto error_calls;
ian@0 156 p->proc_fops = &rxrpc_proc_peers_fops;
ian@0 157 p->owner = THIS_MODULE;
ian@0 158
ian@0 159 p = create_proc_entry("transports", 0, proc_rxrpc);
ian@0 160 if (!p)
ian@0 161 goto error_conns;
ian@0 162 p->proc_fops = &rxrpc_proc_transports_fops;
ian@0 163 p->owner = THIS_MODULE;
ian@0 164
ian@0 165 return 0;
ian@0 166
ian@0 167 error_conns:
ian@0 168 remove_proc_entry("connections", proc_rxrpc);
ian@0 169 error_calls:
ian@0 170 remove_proc_entry("calls", proc_rxrpc);
ian@0 171 error_proc:
ian@0 172 remove_proc_entry("rxrpc", proc_net);
ian@0 173 error:
ian@0 174 return -ENOMEM;
ian@0 175 } /* end rxrpc_proc_init() */
ian@0 176
ian@0 177 /*****************************************************************************/
ian@0 178 /*
ian@0 179 * clean up the /proc/net/rxrpc/ directory
ian@0 180 */
ian@0 181 void rxrpc_proc_cleanup(void)
ian@0 182 {
ian@0 183 remove_proc_entry("transports", proc_rxrpc);
ian@0 184 remove_proc_entry("peers", proc_rxrpc);
ian@0 185 remove_proc_entry("connections", proc_rxrpc);
ian@0 186 remove_proc_entry("calls", proc_rxrpc);
ian@0 187
ian@0 188 remove_proc_entry("rxrpc", proc_net);
ian@0 189
ian@0 190 } /* end rxrpc_proc_cleanup() */
ian@0 191
ian@0 192 /*****************************************************************************/
ian@0 193 /*
ian@0 194 * open "/proc/net/rxrpc/transports" which provides a summary of extant transports
ian@0 195 */
ian@0 196 static int rxrpc_proc_transports_open(struct inode *inode, struct file *file)
ian@0 197 {
ian@0 198 struct seq_file *m;
ian@0 199 int ret;
ian@0 200
ian@0 201 ret = seq_open(file, &rxrpc_proc_transports_ops);
ian@0 202 if (ret < 0)
ian@0 203 return ret;
ian@0 204
ian@0 205 m = file->private_data;
ian@0 206 m->private = PDE(inode)->data;
ian@0 207
ian@0 208 return 0;
ian@0 209 } /* end rxrpc_proc_transports_open() */
ian@0 210
ian@0 211 /*****************************************************************************/
ian@0 212 /*
ian@0 213 * set up the iterator to start reading from the transports list and return the first item
ian@0 214 */
ian@0 215 static void *rxrpc_proc_transports_start(struct seq_file *m, loff_t *_pos)
ian@0 216 {
ian@0 217 struct list_head *_p;
ian@0 218 loff_t pos = *_pos;
ian@0 219
ian@0 220 /* lock the list against modification */
ian@0 221 down_read(&rxrpc_proc_transports_sem);
ian@0 222
ian@0 223 /* allow for the header line */
ian@0 224 if (!pos)
ian@0 225 return SEQ_START_TOKEN;
ian@0 226 pos--;
ian@0 227
ian@0 228 /* find the n'th element in the list */
ian@0 229 list_for_each(_p, &rxrpc_proc_transports)
ian@0 230 if (!pos--)
ian@0 231 break;
ian@0 232
ian@0 233 return _p != &rxrpc_proc_transports ? _p : NULL;
ian@0 234 } /* end rxrpc_proc_transports_start() */
ian@0 235
ian@0 236 /*****************************************************************************/
ian@0 237 /*
ian@0 238 * move to next call in transports list
ian@0 239 */
ian@0 240 static void *rxrpc_proc_transports_next(struct seq_file *p, void *v, loff_t *pos)
ian@0 241 {
ian@0 242 struct list_head *_p;
ian@0 243
ian@0 244 (*pos)++;
ian@0 245
ian@0 246 _p = v;
ian@0 247 _p = (v == SEQ_START_TOKEN) ? rxrpc_proc_transports.next : _p->next;
ian@0 248
ian@0 249 return _p != &rxrpc_proc_transports ? _p : NULL;
ian@0 250 } /* end rxrpc_proc_transports_next() */
ian@0 251
ian@0 252 /*****************************************************************************/
ian@0 253 /*
ian@0 254 * clean up after reading from the transports list
ian@0 255 */
ian@0 256 static void rxrpc_proc_transports_stop(struct seq_file *p, void *v)
ian@0 257 {
ian@0 258 up_read(&rxrpc_proc_transports_sem);
ian@0 259
ian@0 260 } /* end rxrpc_proc_transports_stop() */
ian@0 261
ian@0 262 /*****************************************************************************/
ian@0 263 /*
ian@0 264 * display a header line followed by a load of call lines
ian@0 265 */
ian@0 266 static int rxrpc_proc_transports_show(struct seq_file *m, void *v)
ian@0 267 {
ian@0 268 struct rxrpc_transport *trans =
ian@0 269 list_entry(v, struct rxrpc_transport, proc_link);
ian@0 270
ian@0 271 /* display header on line 1 */
ian@0 272 if (v == SEQ_START_TOKEN) {
ian@0 273 seq_puts(m, "LOCAL USE\n");
ian@0 274 return 0;
ian@0 275 }
ian@0 276
ian@0 277 /* display one transport per line on subsequent lines */
ian@0 278 seq_printf(m, "%5hu %3d\n",
ian@0 279 trans->port,
ian@0 280 atomic_read(&trans->usage)
ian@0 281 );
ian@0 282
ian@0 283 return 0;
ian@0 284 } /* end rxrpc_proc_transports_show() */
ian@0 285
ian@0 286 /*****************************************************************************/
ian@0 287 /*
ian@0 288 * open "/proc/net/rxrpc/peers" which provides a summary of extant peers
ian@0 289 */
ian@0 290 static int rxrpc_proc_peers_open(struct inode *inode, struct file *file)
ian@0 291 {
ian@0 292 struct seq_file *m;
ian@0 293 int ret;
ian@0 294
ian@0 295 ret = seq_open(file, &rxrpc_proc_peers_ops);
ian@0 296 if (ret < 0)
ian@0 297 return ret;
ian@0 298
ian@0 299 m = file->private_data;
ian@0 300 m->private = PDE(inode)->data;
ian@0 301
ian@0 302 return 0;
ian@0 303 } /* end rxrpc_proc_peers_open() */
ian@0 304
ian@0 305 /*****************************************************************************/
ian@0 306 /*
ian@0 307 * set up the iterator to start reading from the peers list and return the
ian@0 308 * first item
ian@0 309 */
ian@0 310 static void *rxrpc_proc_peers_start(struct seq_file *m, loff_t *_pos)
ian@0 311 {
ian@0 312 struct list_head *_p;
ian@0 313 loff_t pos = *_pos;
ian@0 314
ian@0 315 /* lock the list against modification */
ian@0 316 down_read(&rxrpc_peers_sem);
ian@0 317
ian@0 318 /* allow for the header line */
ian@0 319 if (!pos)
ian@0 320 return SEQ_START_TOKEN;
ian@0 321 pos--;
ian@0 322
ian@0 323 /* find the n'th element in the list */
ian@0 324 list_for_each(_p, &rxrpc_peers)
ian@0 325 if (!pos--)
ian@0 326 break;
ian@0 327
ian@0 328 return _p != &rxrpc_peers ? _p : NULL;
ian@0 329 } /* end rxrpc_proc_peers_start() */
ian@0 330
ian@0 331 /*****************************************************************************/
ian@0 332 /*
ian@0 333 * move to next conn in peers list
ian@0 334 */
ian@0 335 static void *rxrpc_proc_peers_next(struct seq_file *p, void *v, loff_t *pos)
ian@0 336 {
ian@0 337 struct list_head *_p;
ian@0 338
ian@0 339 (*pos)++;
ian@0 340
ian@0 341 _p = v;
ian@0 342 _p = (v == SEQ_START_TOKEN) ? rxrpc_peers.next : _p->next;
ian@0 343
ian@0 344 return _p != &rxrpc_peers ? _p : NULL;
ian@0 345 } /* end rxrpc_proc_peers_next() */
ian@0 346
ian@0 347 /*****************************************************************************/
ian@0 348 /*
ian@0 349 * clean up after reading from the peers list
ian@0 350 */
ian@0 351 static void rxrpc_proc_peers_stop(struct seq_file *p, void *v)
ian@0 352 {
ian@0 353 up_read(&rxrpc_peers_sem);
ian@0 354
ian@0 355 } /* end rxrpc_proc_peers_stop() */
ian@0 356
ian@0 357 /*****************************************************************************/
ian@0 358 /*
ian@0 359 * display a header line followed by a load of conn lines
ian@0 360 */
ian@0 361 static int rxrpc_proc_peers_show(struct seq_file *m, void *v)
ian@0 362 {
ian@0 363 struct rxrpc_peer *peer = list_entry(v, struct rxrpc_peer, proc_link);
ian@0 364 long timeout;
ian@0 365
ian@0 366 /* display header on line 1 */
ian@0 367 if (v == SEQ_START_TOKEN) {
ian@0 368 seq_puts(m, "LOCAL REMOTE USAGE CONNS TIMEOUT"
ian@0 369 " MTU RTT(uS)\n");
ian@0 370 return 0;
ian@0 371 }
ian@0 372
ian@0 373 /* display one peer per line on subsequent lines */
ian@0 374 timeout = 0;
ian@0 375 if (!list_empty(&peer->timeout.link))
ian@0 376 timeout = (long) peer->timeout.timo_jif -
ian@0 377 (long) jiffies;
ian@0 378
ian@0 379 seq_printf(m, "%5hu %08x %5d %5d %8ld %5Zu %7lu\n",
ian@0 380 peer->trans->port,
ian@0 381 ntohl(peer->addr.s_addr),
ian@0 382 atomic_read(&peer->usage),
ian@0 383 atomic_read(&peer->conn_count),
ian@0 384 timeout,
ian@0 385 peer->if_mtu,
ian@0 386 (long) peer->rtt
ian@0 387 );
ian@0 388
ian@0 389 return 0;
ian@0 390 } /* end rxrpc_proc_peers_show() */
ian@0 391
ian@0 392 /*****************************************************************************/
ian@0 393 /*
ian@0 394 * open "/proc/net/rxrpc/connections" which provides a summary of extant
ian@0 395 * connections
ian@0 396 */
ian@0 397 static int rxrpc_proc_conns_open(struct inode *inode, struct file *file)
ian@0 398 {
ian@0 399 struct seq_file *m;
ian@0 400 int ret;
ian@0 401
ian@0 402 ret = seq_open(file, &rxrpc_proc_conns_ops);
ian@0 403 if (ret < 0)
ian@0 404 return ret;
ian@0 405
ian@0 406 m = file->private_data;
ian@0 407 m->private = PDE(inode)->data;
ian@0 408
ian@0 409 return 0;
ian@0 410 } /* end rxrpc_proc_conns_open() */
ian@0 411
ian@0 412 /*****************************************************************************/
ian@0 413 /*
ian@0 414 * set up the iterator to start reading from the conns list and return the
ian@0 415 * first item
ian@0 416 */
ian@0 417 static void *rxrpc_proc_conns_start(struct seq_file *m, loff_t *_pos)
ian@0 418 {
ian@0 419 struct list_head *_p;
ian@0 420 loff_t pos = *_pos;
ian@0 421
ian@0 422 /* lock the list against modification */
ian@0 423 down_read(&rxrpc_conns_sem);
ian@0 424
ian@0 425 /* allow for the header line */
ian@0 426 if (!pos)
ian@0 427 return SEQ_START_TOKEN;
ian@0 428 pos--;
ian@0 429
ian@0 430 /* find the n'th element in the list */
ian@0 431 list_for_each(_p, &rxrpc_conns)
ian@0 432 if (!pos--)
ian@0 433 break;
ian@0 434
ian@0 435 return _p != &rxrpc_conns ? _p : NULL;
ian@0 436 } /* end rxrpc_proc_conns_start() */
ian@0 437
ian@0 438 /*****************************************************************************/
ian@0 439 /*
ian@0 440 * move to next conn in conns list
ian@0 441 */
ian@0 442 static void *rxrpc_proc_conns_next(struct seq_file *p, void *v, loff_t *pos)
ian@0 443 {
ian@0 444 struct list_head *_p;
ian@0 445
ian@0 446 (*pos)++;
ian@0 447
ian@0 448 _p = v;
ian@0 449 _p = (v == SEQ_START_TOKEN) ? rxrpc_conns.next : _p->next;
ian@0 450
ian@0 451 return _p != &rxrpc_conns ? _p : NULL;
ian@0 452 } /* end rxrpc_proc_conns_next() */
ian@0 453
ian@0 454 /*****************************************************************************/
ian@0 455 /*
ian@0 456 * clean up after reading from the conns list
ian@0 457 */
ian@0 458 static void rxrpc_proc_conns_stop(struct seq_file *p, void *v)
ian@0 459 {
ian@0 460 up_read(&rxrpc_conns_sem);
ian@0 461
ian@0 462 } /* end rxrpc_proc_conns_stop() */
ian@0 463
ian@0 464 /*****************************************************************************/
ian@0 465 /*
ian@0 466 * display a header line followed by a load of conn lines
ian@0 467 */
ian@0 468 static int rxrpc_proc_conns_show(struct seq_file *m, void *v)
ian@0 469 {
ian@0 470 struct rxrpc_connection *conn;
ian@0 471 long timeout;
ian@0 472
ian@0 473 conn = list_entry(v, struct rxrpc_connection, proc_link);
ian@0 474
ian@0 475 /* display header on line 1 */
ian@0 476 if (v == SEQ_START_TOKEN) {
ian@0 477 seq_puts(m,
ian@0 478 "LOCAL REMOTE RPORT SRVC CONN END SERIALNO "
ian@0 479 "CALLNO MTU TIMEOUT"
ian@0 480 "\n");
ian@0 481 return 0;
ian@0 482 }
ian@0 483
ian@0 484 /* display one conn per line on subsequent lines */
ian@0 485 timeout = 0;
ian@0 486 if (!list_empty(&conn->timeout.link))
ian@0 487 timeout = (long) conn->timeout.timo_jif -
ian@0 488 (long) jiffies;
ian@0 489
ian@0 490 seq_printf(m,
ian@0 491 "%5hu %08x %5hu %04hx %08x %-3.3s %08x %08x %5Zu %8ld\n",
ian@0 492 conn->trans->port,
ian@0 493 ntohl(conn->addr.sin_addr.s_addr),
ian@0 494 ntohs(conn->addr.sin_port),
ian@0 495 ntohs(conn->service_id),
ian@0 496 ntohl(conn->conn_id),
ian@0 497 conn->out_clientflag ? "CLT" : "SRV",
ian@0 498 conn->serial_counter,
ian@0 499 conn->call_counter,
ian@0 500 conn->mtu_size,
ian@0 501 timeout
ian@0 502 );
ian@0 503
ian@0 504 return 0;
ian@0 505 } /* end rxrpc_proc_conns_show() */
ian@0 506
ian@0 507 /*****************************************************************************/
ian@0 508 /*
ian@0 509 * open "/proc/net/rxrpc/calls" which provides a summary of extant calls
ian@0 510 */
ian@0 511 static int rxrpc_proc_calls_open(struct inode *inode, struct file *file)
ian@0 512 {
ian@0 513 struct seq_file *m;
ian@0 514 int ret;
ian@0 515
ian@0 516 ret = seq_open(file, &rxrpc_proc_calls_ops);
ian@0 517 if (ret < 0)
ian@0 518 return ret;
ian@0 519
ian@0 520 m = file->private_data;
ian@0 521 m->private = PDE(inode)->data;
ian@0 522
ian@0 523 return 0;
ian@0 524 } /* end rxrpc_proc_calls_open() */
ian@0 525
ian@0 526 /*****************************************************************************/
ian@0 527 /*
ian@0 528 * set up the iterator to start reading from the calls list and return the
ian@0 529 * first item
ian@0 530 */
ian@0 531 static void *rxrpc_proc_calls_start(struct seq_file *m, loff_t *_pos)
ian@0 532 {
ian@0 533 struct list_head *_p;
ian@0 534 loff_t pos = *_pos;
ian@0 535
ian@0 536 /* lock the list against modification */
ian@0 537 down_read(&rxrpc_calls_sem);
ian@0 538
ian@0 539 /* allow for the header line */
ian@0 540 if (!pos)
ian@0 541 return SEQ_START_TOKEN;
ian@0 542 pos--;
ian@0 543
ian@0 544 /* find the n'th element in the list */
ian@0 545 list_for_each(_p, &rxrpc_calls)
ian@0 546 if (!pos--)
ian@0 547 break;
ian@0 548
ian@0 549 return _p != &rxrpc_calls ? _p : NULL;
ian@0 550 } /* end rxrpc_proc_calls_start() */
ian@0 551
ian@0 552 /*****************************************************************************/
ian@0 553 /*
ian@0 554 * move to next call in calls list
ian@0 555 */
ian@0 556 static void *rxrpc_proc_calls_next(struct seq_file *p, void *v, loff_t *pos)
ian@0 557 {
ian@0 558 struct list_head *_p;
ian@0 559
ian@0 560 (*pos)++;
ian@0 561
ian@0 562 _p = v;
ian@0 563 _p = (v == SEQ_START_TOKEN) ? rxrpc_calls.next : _p->next;
ian@0 564
ian@0 565 return _p != &rxrpc_calls ? _p : NULL;
ian@0 566 } /* end rxrpc_proc_calls_next() */
ian@0 567
ian@0 568 /*****************************************************************************/
ian@0 569 /*
ian@0 570 * clean up after reading from the calls list
ian@0 571 */
ian@0 572 static void rxrpc_proc_calls_stop(struct seq_file *p, void *v)
ian@0 573 {
ian@0 574 up_read(&rxrpc_calls_sem);
ian@0 575
ian@0 576 } /* end rxrpc_proc_calls_stop() */
ian@0 577
ian@0 578 /*****************************************************************************/
ian@0 579 /*
ian@0 580 * display a header line followed by a load of call lines
ian@0 581 */
ian@0 582 static int rxrpc_proc_calls_show(struct seq_file *m, void *v)
ian@0 583 {
ian@0 584 struct rxrpc_call *call = list_entry(v, struct rxrpc_call, call_link);
ian@0 585
ian@0 586 /* display header on line 1 */
ian@0 587 if (v == SEQ_START_TOKEN) {
ian@0 588 seq_puts(m,
ian@0 589 "LOCAL REMOT SRVC CONN CALL DIR USE "
ian@0 590 " L STATE OPCODE ABORT ERRNO\n"
ian@0 591 );
ian@0 592 return 0;
ian@0 593 }
ian@0 594
ian@0 595 /* display one call per line on subsequent lines */
ian@0 596 seq_printf(m,
ian@0 597 "%5hu %5hu %04hx %08x %08x %s %3u%c"
ian@0 598 " %c %-7.7s %6d %08x %5d\n",
ian@0 599 call->conn->trans->port,
ian@0 600 ntohs(call->conn->addr.sin_port),
ian@0 601 ntohs(call->conn->service_id),
ian@0 602 ntohl(call->conn->conn_id),
ian@0 603 ntohl(call->call_id),
ian@0 604 call->conn->service ? "SVC" : "CLT",
ian@0 605 atomic_read(&call->usage),
ian@0 606 waitqueue_active(&call->waitq) ? 'w' : ' ',
ian@0 607 call->app_last_rcv ? 'Y' : '-',
ian@0 608 (call->app_call_state!=RXRPC_CSTATE_ERROR ?
ian@0 609 rxrpc_call_states7[call->app_call_state] :
ian@0 610 rxrpc_call_error_states7[call->app_err_state]),
ian@0 611 call->app_opcode,
ian@0 612 call->app_abort_code,
ian@0 613 call->app_errno
ian@0 614 );
ian@0 615
ian@0 616 return 0;
ian@0 617 } /* end rxrpc_proc_calls_show() */