From fb8423bfd90aab4b78b17ad210433151686ae25e Mon Sep 17 00:00:00 2001 From: Bruno Faccini Date: Thu, 5 Jun 2025 16:27:51 +0200 Subject: [PATCH] LU-19091 ptlrpc: protect internal access to obd->obd_svc_stats PM-QoS patch from LU-18446, where OBD svc stats are used to evaluate best time period for low CPUs latency to be kept, has introduced a new and internal way to access obd->obd_svc_stats which now requires other concurrent access protection than simply to remove external tunables in /sys or /debug. Fixes: 54a64ea818 ("LU-18446 ptlrpc: lower CPUs latency during client I/O") Signed-off-by: Bruno Faccini Change-Id: I45a5f65216fa2bf0821776ff3141fa8e2a33f10e Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/59593 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Aurelien Degremont Reviewed-by: Oleg Drokin --- lustre/ptlrpc/niobuf.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/lustre/ptlrpc/niobuf.c b/lustre/ptlrpc/niobuf.c index a321cce..ed8a37f 100644 --- a/lustre/ptlrpc/niobuf.c +++ b/lustre/ptlrpc/niobuf.c @@ -585,19 +585,23 @@ static void kick_cpu_latency(struct ptlrpc_connection *conn, return; #ifdef CONFIG_PROC_FS - if (ptlrpc_pmqos_use_stats_for_duration == true && obd != NULL && - obd->obd_svc_stats != NULL) { - struct lprocfs_counter ret; - - lprocfs_stats_collect(obd->obd_svc_stats, - PTLRPC_REQWAIT_CNTR, &ret); - /* use 125% of average wait time (lc_sum/lc_count) - * instead of lc_max - */ - if (ret.lc_count != 0) - time = (ret.lc_sum / ret.lc_count) * 5 / 4; - CDEBUG(D_INFO, "%s: using a timeout of %llu usecs (%lu jiffies)\n", - obd->obd_name, time, usecs_to_jiffies(time)); + if (ptlrpc_pmqos_use_stats_for_duration == true && obd != NULL) { + /* prevent racing with OBD cleanup (umount !) */ + spin_lock(&obd->obd_dev_lock); + if (!obd->obd_stopping && obd->obd_svc_stats != NULL) { + struct lprocfs_counter ret; + + lprocfs_stats_collect(obd->obd_svc_stats, + PTLRPC_REQWAIT_CNTR, &ret); + /* use 125% of average wait time (lc_sum/lc_count) + * instead of lc_max + */ + if (ret.lc_count != 0) + time = (ret.lc_sum / ret.lc_count) * 5 / 4; + CDEBUG(D_INFO, "%s: using a timeout of %llu usecs (%lu jiffies)\n", + obd->obd_name, time, usecs_to_jiffies(time)); + } + spin_unlock(&obd->obd_dev_lock); } #endif -- 1.8.3.1