mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-28 16:53:49 +00:00
rxrpc: Create a procfile to display outstanding client conn bundles
Create /proc/net/rxrpc/bundles to display outstanding rxrpc client connection bundles. Signed-off-by: David Howells <dhowells@redhat.com> cc: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org
This commit is contained in:
parent
98f9fda205
commit
d2ce4a84c2
@ -68,6 +68,7 @@ struct rxrpc_net {
|
||||
atomic_t nr_calls; /* Count of allocated calls */
|
||||
|
||||
atomic_t nr_conns;
|
||||
struct list_head bundle_proc_list; /* List of bundles for proc */
|
||||
struct list_head conn_proc_list; /* List of conns in this namespace for proc */
|
||||
struct list_head service_conns; /* Service conns in this namespace */
|
||||
rwlock_t conn_lock; /* Lock for ->conn_proc_list, ->service_conns */
|
||||
@ -432,6 +433,7 @@ struct rxrpc_bundle {
|
||||
struct rxrpc_local *local; /* Representation of local endpoint */
|
||||
struct rxrpc_peer *peer; /* Remote endpoint */
|
||||
struct key *key; /* Security details */
|
||||
struct list_head proc_link; /* Link in net->bundle_proc_list */
|
||||
const struct rxrpc_security *security; /* applied security module */
|
||||
refcount_t ref;
|
||||
atomic_t active; /* Number of active users */
|
||||
@ -445,6 +447,7 @@ struct rxrpc_bundle {
|
||||
struct rb_node local_node; /* Node in local->client_conns */
|
||||
struct list_head waiting_calls; /* Calls waiting for channels */
|
||||
unsigned long avail_chans; /* Mask of available channels */
|
||||
unsigned int conn_ids[4]; /* Connection IDs. */
|
||||
struct rxrpc_connection *conns[4]; /* The connections in the bundle (max 4) */
|
||||
};
|
||||
|
||||
@ -1167,6 +1170,7 @@ void rxrpc_put_peer(struct rxrpc_peer *, enum rxrpc_peer_trace);
|
||||
*/
|
||||
extern const struct seq_operations rxrpc_call_seq_ops;
|
||||
extern const struct seq_operations rxrpc_connection_seq_ops;
|
||||
extern const struct seq_operations rxrpc_bundle_seq_ops;
|
||||
extern const struct seq_operations rxrpc_peer_seq_ops;
|
||||
extern const struct seq_operations rxrpc_local_seq_ops;
|
||||
|
||||
|
@ -91,6 +91,10 @@ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_call *call,
|
||||
atomic_set(&bundle->active, 1);
|
||||
INIT_LIST_HEAD(&bundle->waiting_calls);
|
||||
trace_rxrpc_bundle(bundle->debug_id, 1, rxrpc_bundle_new);
|
||||
|
||||
write_lock(&bundle->local->rxnet->conn_lock);
|
||||
list_add_tail(&bundle->proc_link, &bundle->local->rxnet->bundle_proc_list);
|
||||
write_unlock(&bundle->local->rxnet->conn_lock);
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
@ -109,6 +113,9 @@ static void rxrpc_free_bundle(struct rxrpc_bundle *bundle)
|
||||
{
|
||||
trace_rxrpc_bundle(bundle->debug_id, refcount_read(&bundle->ref),
|
||||
rxrpc_bundle_free);
|
||||
write_lock(&bundle->local->rxnet->conn_lock);
|
||||
list_del(&bundle->proc_link);
|
||||
write_unlock(&bundle->local->rxnet->conn_lock);
|
||||
rxrpc_put_peer(bundle->peer, rxrpc_peer_put_bundle);
|
||||
key_put(bundle->key);
|
||||
kfree(bundle);
|
||||
@ -338,6 +345,7 @@ static bool rxrpc_add_conn_to_bundle(struct rxrpc_bundle *bundle,
|
||||
old = bundle->conns[slot];
|
||||
if (old) {
|
||||
bundle->conns[slot] = NULL;
|
||||
bundle->conn_ids[slot] = 0;
|
||||
trace_rxrpc_client(old, -1, rxrpc_client_replace);
|
||||
rxrpc_put_connection(old, rxrpc_conn_put_noreuse);
|
||||
}
|
||||
@ -351,6 +359,7 @@ static bool rxrpc_add_conn_to_bundle(struct rxrpc_bundle *bundle,
|
||||
rxrpc_activate_bundle(bundle);
|
||||
conn->bundle_shift = shift;
|
||||
bundle->conns[slot] = conn;
|
||||
bundle->conn_ids[slot] = conn->debug_id;
|
||||
for (i = 0; i < RXRPC_MAXCALLS; i++)
|
||||
set_bit(shift + i, &bundle->avail_chans);
|
||||
return true;
|
||||
@ -671,6 +680,7 @@ static void rxrpc_unbundle_conn(struct rxrpc_connection *conn)
|
||||
if (bundle->conns[bindex] == conn) {
|
||||
_debug("clear slot %u", bindex);
|
||||
bundle->conns[bindex] = NULL;
|
||||
bundle->conn_ids[bindex] = 0;
|
||||
for (i = 0; i < RXRPC_MAXCALLS; i++)
|
||||
clear_bit(conn->bundle_shift + i, &bundle->avail_chans);
|
||||
rxrpc_put_client_connection_id(bundle->local, conn);
|
||||
|
@ -45,6 +45,7 @@ static __net_init int rxrpc_init_net(struct net *net)
|
||||
atomic_set(&rxnet->nr_calls, 1);
|
||||
|
||||
atomic_set(&rxnet->nr_conns, 1);
|
||||
INIT_LIST_HEAD(&rxnet->bundle_proc_list);
|
||||
INIT_LIST_HEAD(&rxnet->conn_proc_list);
|
||||
INIT_LIST_HEAD(&rxnet->service_conns);
|
||||
rwlock_init(&rxnet->conn_lock);
|
||||
@ -78,6 +79,9 @@ static __net_init int rxrpc_init_net(struct net *net)
|
||||
proc_create_net("conns", 0444, rxnet->proc_net,
|
||||
&rxrpc_connection_seq_ops,
|
||||
sizeof(struct seq_net_private));
|
||||
proc_create_net("bundles", 0444, rxnet->proc_net,
|
||||
&rxrpc_bundle_seq_ops,
|
||||
sizeof(struct seq_net_private));
|
||||
proc_create_net("peers", 0444, rxnet->proc_net,
|
||||
&rxrpc_peer_seq_ops,
|
||||
sizeof(struct seq_net_private));
|
||||
|
@ -198,6 +198,82 @@ const struct seq_operations rxrpc_connection_seq_ops = {
|
||||
.show = rxrpc_connection_seq_show,
|
||||
};
|
||||
|
||||
/*
|
||||
* generate a list of extant virtual bundles in /proc/net/rxrpc/bundles
|
||||
*/
|
||||
static void *rxrpc_bundle_seq_start(struct seq_file *seq, loff_t *_pos)
|
||||
__acquires(rxnet->conn_lock)
|
||||
{
|
||||
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
|
||||
|
||||
read_lock(&rxnet->conn_lock);
|
||||
return seq_list_start_head(&rxnet->bundle_proc_list, *_pos);
|
||||
}
|
||||
|
||||
static void *rxrpc_bundle_seq_next(struct seq_file *seq, void *v,
|
||||
loff_t *pos)
|
||||
{
|
||||
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
|
||||
|
||||
return seq_list_next(v, &rxnet->bundle_proc_list, pos);
|
||||
}
|
||||
|
||||
static void rxrpc_bundle_seq_stop(struct seq_file *seq, void *v)
|
||||
__releases(rxnet->conn_lock)
|
||||
{
|
||||
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
|
||||
|
||||
read_unlock(&rxnet->conn_lock);
|
||||
}
|
||||
|
||||
static int rxrpc_bundle_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
struct rxrpc_bundle *bundle;
|
||||
struct rxrpc_net *rxnet = rxrpc_net(seq_file_net(seq));
|
||||
char lbuff[50], rbuff[50];
|
||||
|
||||
if (v == &rxnet->bundle_proc_list) {
|
||||
seq_puts(seq,
|
||||
"Proto Local "
|
||||
" Remote "
|
||||
" SvID Ref Act Flg Key |"
|
||||
" Bundle Conn_0 Conn_1 Conn_2 Conn_3\n"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bundle = list_entry(v, struct rxrpc_bundle, proc_link);
|
||||
|
||||
sprintf(lbuff, "%pISpc", &bundle->local->srx.transport);
|
||||
sprintf(rbuff, "%pISpc", &bundle->peer->srx.transport);
|
||||
seq_printf(seq,
|
||||
"UDP %-47.47s %-47.47s %4x %3u %3d"
|
||||
" %c%c%c %08x | %08x %08x %08x %08x %08x\n",
|
||||
lbuff,
|
||||
rbuff,
|
||||
bundle->service_id,
|
||||
refcount_read(&bundle->ref),
|
||||
atomic_read(&bundle->active),
|
||||
bundle->try_upgrade ? 'U' : '-',
|
||||
bundle->exclusive ? 'e' : '-',
|
||||
bundle->upgrade ? 'u' : '-',
|
||||
key_serial(bundle->key),
|
||||
bundle->debug_id,
|
||||
bundle->conn_ids[0],
|
||||
bundle->conn_ids[1],
|
||||
bundle->conn_ids[2],
|
||||
bundle->conn_ids[3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct seq_operations rxrpc_bundle_seq_ops = {
|
||||
.start = rxrpc_bundle_seq_start,
|
||||
.next = rxrpc_bundle_seq_next,
|
||||
.stop = rxrpc_bundle_seq_stop,
|
||||
.show = rxrpc_bundle_seq_show,
|
||||
};
|
||||
|
||||
/*
|
||||
* generate a list of extant virtual peers in /proc/net/rxrpc/peers
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user