|
@@ -116,7 +116,15 @@ EXPORT_SYMBOL_GPL(svc_seq_show);
|
|
|
*/
|
|
|
struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt)
|
|
|
{
|
|
|
- return kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL);
|
|
|
+ struct rpc_iostats *stats;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ stats = kcalloc(clnt->cl_maxproc, sizeof(*stats), GFP_KERNEL);
|
|
|
+ if (stats) {
|
|
|
+ for (i = 0; i < clnt->cl_maxproc; i++)
|
|
|
+ spin_lock_init(&stats[i].om_lock);
|
|
|
+ }
|
|
|
+ return stats;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(rpc_alloc_iostats);
|
|
|
|
|
@@ -135,20 +143,21 @@ EXPORT_SYMBOL_GPL(rpc_free_iostats);
|
|
|
* rpc_count_iostats - tally up per-task stats
|
|
|
* @task: completed rpc_task
|
|
|
* @stats: array of stat structures
|
|
|
- *
|
|
|
- * Relies on the caller for serialization.
|
|
|
*/
|
|
|
void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats)
|
|
|
{
|
|
|
struct rpc_rqst *req = task->tk_rqstp;
|
|
|
struct rpc_iostats *op_metrics;
|
|
|
- ktime_t delta;
|
|
|
+ ktime_t delta, now;
|
|
|
|
|
|
if (!stats || !req)
|
|
|
return;
|
|
|
|
|
|
+ now = ktime_get();
|
|
|
op_metrics = &stats[task->tk_msg.rpc_proc->p_statidx];
|
|
|
|
|
|
+ spin_lock(&op_metrics->om_lock);
|
|
|
+
|
|
|
op_metrics->om_ops++;
|
|
|
op_metrics->om_ntrans += req->rq_ntrans;
|
|
|
op_metrics->om_timeouts += task->tk_timeouts;
|
|
@@ -161,8 +170,10 @@ void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats)
|
|
|
|
|
|
op_metrics->om_rtt = ktime_add(op_metrics->om_rtt, req->rq_rtt);
|
|
|
|
|
|
- delta = ktime_sub(ktime_get(), task->tk_start);
|
|
|
+ delta = ktime_sub(now, task->tk_start);
|
|
|
op_metrics->om_execute = ktime_add(op_metrics->om_execute, delta);
|
|
|
+
|
|
|
+ spin_unlock(&op_metrics->om_lock);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(rpc_count_iostats);
|
|
|
|