[RHEL7,COMMIT] fs/fuse kio: share stucked requests count for prometheus stats

Submitted by Vasily Averin on March 5, 2021, 4:22 p.m.

Details

Message ID 202103051622.125GMUNl019624@vz7build.vvs.sw.ru
State New
Series "fs/fuse kio: share stucked requests count for prometheus stats"
Headers show

Commit Message

Vasily Averin March 5, 2021, 4:22 p.m.
The commit is pushed to "branch-rh7-3.10.0-1160.15.2.vz7.173.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-1160.15.2.vz7.173.6
------>
commit 44c508d3fbf0a704fba8eac263b56ed8795b31f0
Author: Ildar Ismagilov <ildar.ismagilov@virtuozzo.com>
Date:   Fri Mar 5 19:22:30 2021 +0300

    fs/fuse kio: share stucked requests count for prometheus stats
    
    Pass the following counters to prometheus through sysfs:
     - stucked_reqs_cnt_8s (total amount of requests that run for longer than 8s)
     - stucked_reqs_cnt_30s (total amount of requests that run for longer than 30s)
     - stucked_reqs_cnt_120s (total amount of requests that run for longer than 120s)
    
    The counters have been added to the end of the kfuse_metrics structure.
    
    https://pmc.acronis.com/browse/VSTOR-41021
    
    Signed-off-by: Ildar Ismagilov <ildar.ismagilov@virtuozzo.com>
    Acked-by:  Alexey Kuznetsov <kuznet@acronis.com>
    
    Signed-off-by: Ildar Ismagilov <ildar.ismagilov@virtuozzo.com>
---
 fs/fuse/kio/pcs/fuse_ktrace.h          |  1 +
 fs/fuse/kio/pcs/fuse_prometheus_prot.h |  4 ++++
 fs/fuse/kio/pcs/pcs_fuse_kdirect.c     | 26 ++++++++++++++++++++++++++
 3 files changed, 31 insertions(+)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/kio/pcs/fuse_ktrace.h b/fs/fuse/kio/pcs/fuse_ktrace.h
index 45a4064..50861b3 100644
--- a/fs/fuse/kio/pcs/fuse_ktrace.h
+++ b/fs/fuse/kio/pcs/fuse_ktrace.h
@@ -15,6 +15,7 @@ 
 struct fuse_ktrace
 {
 	atomic_t				refcnt;
+	struct fuse_conn			*fc;
 	struct rchan				*rchan;
 	struct dentry				*dir;
 	unsigned long __percpu			*ovfl;
diff --git a/fs/fuse/kio/pcs/fuse_prometheus_prot.h b/fs/fuse/kio/pcs/fuse_prometheus_prot.h
index 2959b1e..90aedd6 100644
--- a/fs/fuse/kio/pcs/fuse_prometheus_prot.h
+++ b/fs/fuse/kio/pcs/fuse_prometheus_prot.h
@@ -40,6 +40,10 @@  struct kfuse_metrics {
 
 	/* Counters were added in 3.5 release */
 	struct kfuse_counter	cnts[KFUSE_OP_MAX];
+
+	u64 stucked_reqs_cnt_8s;
+	u64 stucked_reqs_cnt_30s;
+	u64 stucked_reqs_cnt_120s;
 };
 
 #endif /* __FUSE_PROMETHEUS_PROT__ */
diff --git a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
index 1cdcb15..2069e3d 100644
--- a/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
+++ b/fs/fuse/kio/pcs/pcs_fuse_kdirect.c
@@ -1261,6 +1261,8 @@  static void fuse_trace_free(struct fuse_ktrace *tr)
 		free_percpu(tr->prometheus_metrics);
 	free_percpu(tr->buf);
 	debugfs_remove(tr->dir);
+	if (tr->fc)
+		fuse_conn_put(tr->fc);
 	kfree(tr);
 }
 
@@ -1384,6 +1386,24 @@  static int prometheus_file_release(struct inode *inode, struct file *filp)
 	return 0;
 }
 
+static void prometheus_req_iter(struct fuse_file *ff, struct fuse_req *req,
+				void *ctx)
+{
+	struct kfuse_metrics *stats = ctx;
+	struct pcs_fuse_req *r = pcs_req_from_fuse(req);
+	struct pcs_int_request *ireq = &r->exec.ireq;
+	s64 duration;
+
+	duration = ktime_to_ms(ktime_sub(ktime_get(), ireq->ts));
+
+	if (duration >= 8 * MSEC_PER_SEC)
+		stats->stucked_reqs_cnt_8s++;
+	if (duration >= 30 * MSEC_PER_SEC)
+		stats->stucked_reqs_cnt_30s++;
+	if (duration >= 120 * MSEC_PER_SEC)
+		stats->stucked_reqs_cnt_120s++;
+}
+
 /* NOTE: old versions of userspace could read only histograms */
 static ssize_t prometheus_file_read(struct file *filp,
 				    char __user *buffer,
@@ -1429,6 +1449,10 @@  static ssize_t prometheus_file_read(struct file *filp,
 		}
 	}
 
+	spin_lock(&tr->fc->lock);
+	pcs_kio_req_list(tr->fc, prometheus_req_iter, stats);
+	spin_unlock(&tr->fc->lock);
+
 	if (copy_to_user(buffer, (char *)stats + *ppos, count))
 		count = -EFAULT;
 	else
@@ -1461,6 +1485,8 @@  static int fuse_ktrace_setup(struct fuse_conn * fc)
 	if (!tr)
 		return -ENOMEM;
 
+	tr->fc = fuse_conn_get(fc);
+
 	ret = -ENOMEM;
 	tr->ovfl = alloc_percpu(unsigned long);
 	if (!tr->ovfl)