Skip to content

Commit

Permalink
SUNRPC: add a handful of per-xprt counters
Browse files Browse the repository at this point in the history
Monitor generic transport events.  Add a transport switch callout to
format transport counters for export to user-land.

Test plan:
Compile kernel with CONFIG_NFS enabled.

Signed-off-by: Chuck Lever <cel@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
  • Loading branch information
Chuck Lever authored and Trond Myklebust committed Mar 20, 2006
1 parent e19b63d commit 262ca07
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 6 deletions.
13 changes: 13 additions & 0 deletions include/linux/sunrpc/xprt.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ struct rpc_xprt_ops {
void (*release_request)(struct rpc_task *task);
void (*close)(struct rpc_xprt *xprt);
void (*destroy)(struct rpc_xprt *xprt);
void (*print_stats)(struct rpc_xprt *xprt, struct seq_file *seq);
};

struct rpc_xprt {
Expand Down Expand Up @@ -187,6 +188,18 @@ struct rpc_xprt {

struct list_head recv;

struct {
unsigned long bind_count, /* total number of binds */
connect_count, /* total number of connects */
connect_start, /* connect start timestamp */
connect_time, /* jiffies waiting for connect */
sends, /* how many complete requests */
recvs, /* how many complete requests */
bad_xids; /* lookup_rqst didn't find XID */

unsigned long long req_u, /* average requests on the wire */
bklog_u; /* backlog queue utilization */
} stat;

void (*old_data_ready)(struct sock *, int);
void (*old_state_change)(struct sock *);
Expand Down
1 change: 1 addition & 0 deletions net/sunrpc/pmap_clnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ rpc_getport(struct rpc_task *task, struct rpc_clnt *clnt)
rpc_call_setup(child, &msg, 0);

/* ... and run the child task */
task->tk_xprt->stat.bind_count++;
rpc_run_child(task, child, pmap_getport_done);
return;

Expand Down
21 changes: 15 additions & 6 deletions net/sunrpc/xprt.c
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,7 @@ void xprt_connect(struct rpc_task *task)

task->tk_timeout = xprt->connect_timeout;
rpc_sleep_on(&xprt->pending, task, xprt_connect_status, NULL);
xprt->stat.connect_start = jiffies;
xprt->ops->connect(task);
}
return;
Expand All @@ -558,6 +559,8 @@ static void xprt_connect_status(struct rpc_task *task)
struct rpc_xprt *xprt = task->tk_xprt;

if (task->tk_status >= 0) {
xprt->stat.connect_count++;
xprt->stat.connect_time += (long)jiffies - xprt->stat.connect_start;
dprintk("RPC: %4d xprt_connect_status: connection established\n",
task->tk_pid);
return;
Expand Down Expand Up @@ -601,16 +604,14 @@ static void xprt_connect_status(struct rpc_task *task)
struct rpc_rqst *xprt_lookup_rqst(struct rpc_xprt *xprt, u32 xid)
{
struct list_head *pos;
struct rpc_rqst *req = NULL;

list_for_each(pos, &xprt->recv) {
struct rpc_rqst *entry = list_entry(pos, struct rpc_rqst, rq_list);
if (entry->rq_xid == xid) {
req = entry;
break;
}
if (entry->rq_xid == xid)
return entry;
}
return req;
xprt->stat.bad_xids++;
return NULL;
}

/**
Expand Down Expand Up @@ -646,6 +647,7 @@ void xprt_complete_rqst(struct rpc_task *task, int copied)
dprintk("RPC: %5u xid %08x complete (%d bytes received)\n",
task->tk_pid, ntohl(req->rq_xid), copied);

task->tk_xprt->stat.recvs++;
list_del_init(&req->rq_list);
req->rq_received = req->rq_private_buf.len = copied;
rpc_wake_up_task(task);
Expand Down Expand Up @@ -744,12 +746,19 @@ void xprt_transmit(struct rpc_task *task)
if (status == 0) {
dprintk("RPC: %4d xmit complete\n", task->tk_pid);
spin_lock_bh(&xprt->transport_lock);

xprt->ops->set_retrans_timeout(task);

xprt->stat.sends++;
xprt->stat.req_u += xprt->stat.sends - xprt->stat.recvs;
xprt->stat.bklog_u += xprt->backlog.qlen;

/* Don't race with disconnect */
if (!xprt_connected(xprt))
task->tk_status = -ENOTCONN;
else if (!req->rq_received)
rpc_sleep_on(&xprt->pending, task, NULL, xprt_timer);

xprt->ops->release_xprt(xprt, task);
spin_unlock_bh(&xprt->transport_lock);
return;
Expand Down
48 changes: 48 additions & 0 deletions net/sunrpc/xprtsock.c
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,8 @@ static void xs_tcp_connect_worker(void *args)
}

/* Tell the socket layer to start connecting... */
xprt->stat.connect_count++;
xprt->stat.connect_start = jiffies;
status = sock->ops->connect(sock, (struct sockaddr *) &xprt->addr,
sizeof(xprt->addr), O_NONBLOCK);
dprintk("RPC: %p connect status %d connected %d sock state %d\n",
Expand Down Expand Up @@ -1177,6 +1179,50 @@ static void xs_connect(struct rpc_task *task)
}
}

/**
* xs_udp_print_stats - display UDP socket-specifc stats
* @xprt: rpc_xprt struct containing statistics
* @seq: output file
*
*/
static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
{
seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n",
xprt->port,
xprt->stat.bind_count,
xprt->stat.sends,
xprt->stat.recvs,
xprt->stat.bad_xids,
xprt->stat.req_u,
xprt->stat.bklog_u);
}

/**
* xs_tcp_print_stats - display TCP socket-specifc stats
* @xprt: rpc_xprt struct containing statistics
* @seq: output file
*
*/
static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
{
long idle_time = 0;

if (xprt_connected(xprt))
idle_time = (long)(jiffies - xprt->last_used) / HZ;

seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n",
xprt->port,
xprt->stat.bind_count,
xprt->stat.connect_count,
xprt->stat.connect_time,
idle_time,
xprt->stat.sends,
xprt->stat.recvs,
xprt->stat.bad_xids,
xprt->stat.req_u,
xprt->stat.bklog_u);
}

static struct rpc_xprt_ops xs_udp_ops = {
.set_buffer_size = xs_udp_set_buffer_size,
.reserve_xprt = xprt_reserve_xprt_cong,
Expand All @@ -1191,6 +1237,7 @@ static struct rpc_xprt_ops xs_udp_ops = {
.release_request = xprt_release_rqst_cong,
.close = xs_close,
.destroy = xs_destroy,
.print_stats = xs_udp_print_stats,
};

static struct rpc_xprt_ops xs_tcp_ops = {
Expand All @@ -1204,6 +1251,7 @@ static struct rpc_xprt_ops xs_tcp_ops = {
.set_retrans_timeout = xprt_set_retrans_timeout_def,
.close = xs_close,
.destroy = xs_destroy,
.print_stats = xs_tcp_print_stats,
};

/**
Expand Down

0 comments on commit 262ca07

Please sign in to comment.