From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 83C89394461; Wed, 12 Aug 2026 05:42:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=148.163.158.5 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786513364; cv=none; b=qjSOQySfP9mv/Esuy0snjfoQFRQKQLp/CQAEeaNTFjfpmB4YpIr7rFznfVhNqBkrL5pWeGYUaJY/M/3B9zW1kJscwCW3a4RNE1KoCfbLU5UybILMneNtLUbgNSHxylFdf2E6/lOAzsWDr6SX9z6Vz910sy9iAn03AGNolENg9wQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786513364; c=relaxed/simple; bh=080FW7/pBVPrAEE6G6RZOuv7FM2p2iJePFSbtKUPn8A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=J3yB9gvD5D36eRt04iJXhpM7n7p0JMSJ9GFrhnOT9iLS4w/1eUPMOVk5KyQwbu4sBRpvcpiJr3ixdDP0hm0aNTySJ3IfM3HHBet+8X+yimW4LwAtntWOooFVdf/9QTZETCxeNGGMMdCswhWYH5UhjwqhOJ2aDxumBwlTFIdPPbY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com; spf=pass smtp.mailfrom=linux.ibm.com; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b=agUO8sa4; arc=none smtp.client-ip=148.163.158.5 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.ibm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=ibm.com header.i=@ibm.com header.b="agUO8sa4" Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 67C31lxh2196170; Wed, 12 Aug 2026 05:42:24 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=pp1; bh=+KXiQpoD6/H7hE/gH +GmtA+6Hl66Ta6Hh1ZBHVaDiHY=; b=agUO8sa4MLrQkbsGZR+/g5Px4CuMm9oW6 8L7IZ03vgD7XlUPZtzJKV1Jz5YSFBiwExIou0egA51uF0zGFtjW8OFtKiA49+Q/X NiMM12wMNrJO0s1smIM/ciO7D6NiK7mGCtaoeAvnq2YFDEjd8Gfq7DRy4F2yiseR mNPxO84QfTk5G5AWak0akk10zYKyf7mYdlOB9q47IulkD8M95HOY9C1aLHfygfiv Z03fPfuQFhy9Eqarz4l0VnP9fceD98u6fc7LGYYmpheN4um9v8vc2GyuIx25YA1X Jzl5v+X08FKycuZtkZMgYRvVeTdcIxw7HR46R/n9Md3MAifjRpC2A== Received: from ppma21.wdc07v.mail.ibm.com (5b.69.3da9.ip4.static.sl-reverse.com [169.61.105.91]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 4fwvp308cf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 12 Aug 2026 05:42:23 +0000 (GMT) Received: from pps.filterd (ppma21.wdc07v.mail.ibm.com [127.0.0.1]) by ppma21.wdc07v.mail.ibm.com (8.18.1.7/8.18.1.7) with ESMTP id 67C5fVAw012811; Wed, 12 Aug 2026 05:42:22 GMT Received: from smtprelay03.fra02v.mail.ibm.com ([9.218.2.224]) by ppma21.wdc07v.mail.ibm.com (PPS) with ESMTPS id 4fxfsjvpcw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 12 Aug 2026 05:42:22 +0000 (GMT) Received: from smtpav04.fra02v.mail.ibm.com (smtpav04.fra02v.mail.ibm.com [10.20.54.103]) by smtprelay03.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 67C5gI0s35783144 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 12 Aug 2026 05:42:18 GMT Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id B544D2004B; Wed, 12 Aug 2026 05:42:18 +0000 (GMT) Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3F5BA20043; Wed, 12 Aug 2026 05:42:09 +0000 (GMT) Received: from li-7bb28a4c-2dab-11b2-a85c-887b5c60d769.ibm.com.com (unknown [9.124.217.151]) by smtpav04.fra02v.mail.ibm.com (Postfix) with ESMTP; Wed, 12 Aug 2026 05:42:08 +0000 (GMT) From: Shrikanth Hegde To: linux-kernel@vger.kernel.org, mingo@kernel.org, peterz@infradead.org, juri.lelli@redhat.com, vincent.guittot@linaro.org, yury.norov@gmail.com, kprateek.nayak@amd.com, iii@linux.ibm.com, corbet@lwn.net, meted@linux.ibm.com, ynorov@nvidia.com Cc: sshegde@linux.ibm.com, tglx@kernel.org, gregkh@linuxfoundation.org, pbonzini@redhat.com, seanjc@google.com, vschneid@redhat.com, huschle@linux.ibm.com, rostedt@goodmis.org, dietmar.eggemann@arm.com, maddy@linux.ibm.com, srikar@linux.ibm.com, hdanton@sina.com, chleroy@kernel.org, vineeth@bitbyteword.org, frederic@kernel.org, arighi@nvidia.com, pauld@redhat.com, christian.loehle@arm.com, tj@kernel.org, tommaso.cucinotta@gmail.com, maz@kernel.org, rafael@kernel.org, rdunlap@infradead.org, kernellwp@gmail.com, linux-doc@vger.kernel.org, jgross@suse.com, virtualization@lists.linux.dev Subject: [PATCH v10 10/12] virt/steal_governor: Add control knobs for handling steal values Date: Wed, 12 Aug 2026 11:10:31 +0530 Message-ID: <20260812054033.95658-11-sshegde@linux.ibm.com> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260812054033.95658-1-sshegde@linux.ibm.com> References: <20260812054033.95658-1-sshegde@linux.ibm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-Reinject: loops=2 maxloops=12 X-Authority-Analysis: v=2.4 cv=AMtp2X5w c=1 sm=1 tr=0 ts=6a7c07c0 cx=c_pps a=GFwsV6G8L6GxiO2Y/PsHdQ==:117 a=GFwsV6G8L6GxiO2Y/PsHdQ==:17 a=Sv0fKeRqtYgA:10 a=VkNPw1HP01LnGYTKEx00:22 a=RnoormkPH1_aCDwRdu11:22 a=Y2IxJ9c9Rs8Kov3niI8_:22 a=pGLkceISAAAA:8 a=VnNF1IyMAAAA:8 a=XC_GqrfF-lTPz34eE_0A:9 X-Proofpoint-GUID: tNGAu6tFwgukEvDzRuqNVexWFQZ2_VvA X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwODEyMDA0MSBTYWx0ZWRfX8TLLC0nP62qt Lst0z1yXp5NhsjiKGtd60SIDw4F4ASa7GsvbrFPcziudWEqjIKqhx+rGOnZxS8PiKG+ZA9VA9MB fCwgMTTBnJs0kpRC9fOoFReCEAe9/1bsHJCtAeiaryvZpmuWTfk/Pv0b8MWcCtE/drvz4CKZS4K PcOGOvZWxzTfIFVdAX/Cb4L8fxVA8sSAKMiB8d7JTwgt5gNoEl8Bkz5KAl0hSzCTUThZOql80ST G9OW9TEFWum5gCnEGHP58dDN3Xt+OW1tkknaAECZG0jaKS5Ig8S+L1UMUpV3Fp82MfD+DJ0ieGp 10Zhauw6/7t/SjFZeyz/mG0bJxmr5WDDOrQJaF3yx3mcC1HX7Qh9AmzsS8f3QF4Af3q0qFySpib gGOTKzfo5wVofBcIgkYNYKvl+EF81j4f+ea8VSBFfvQcMHFz1KysRHdggXYASFHN7iKBGqxzI2y 3Uyb16lhl2r7alfQEBg== X-Proofpoint-ORIG-GUID: Z4jRKlYBcGtx6ZVKpenT5zLHNzRLpe6k X-Proofpoint-Spam-Info: AW1haW4tMjYwODEyMDA0MSBTYWx0ZWRfXxfQHv5FbnnVS QBi/Nr2e78HzrZZv1DiqA9lNJyeLCgiJzUZjAS+KsNkf5HNdp7tuMyYudVHATo2LgUbQBZKRGQ1 jdGLBCMhM+whnWHQqbE1FOFnKbgd3Rw= X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-08-12_01,2026-08-10_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 adultscore=0 lowpriorityscore=0 clxscore=1015 priorityscore=1501 impostorscore=0 phishscore=0 spamscore=0 bulkscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2608120041 These are the knobs to control the steal_governor. interval_ms: How often steal governor checks for steal time. (Default: 1000 i.e 1 second) This controls how fast steal governor driver reacts to changes to the contention of physical CPUs. Can be set between 100 to 100000. i.e. 100ms to 100seconds. 100ms is kept as minimum to ensure few meaningful steal values accumulate even with HZ=100. low_threshold: lower threshold value in percentage * 100. (Default: 200, i.e 2% steal is considered as low threshold) This determines what values should be considered as nil/no steal values. When steal governor see steal ratio is below or equal to this value, it will increase the preferred CPUs by 1 core. Having value as zero might cause oscillations high_threshold: higher threshold value in percentage * 100 (Default: 500, i.e 5% steal is considered as high threshold) This determines what values should be considered as high steal values. When steal governor sees steal ratio is higher than this value, it will reduce the preferred CPUs by 1 core. module_param_cb methods are used to do the validation checks. This helps to ensure one configures sane values. Since low and high are dependent, that check is done at module init. Notes: - Parameters values can't be changed at runtime. One has to unload the module and change it. Hence recommended to build it as module. - Default values cannot cater to all configuration such as sparse CPUs, selectively offline CPUs etc. Compute the values based on system under test. Documentation provides an example. Documentation is available at: Documentation/driver-api/steal-governor.rst Suggested-by: Yury Norov Signed-off-by: Shrikanth Hegde --- drivers/virt/steal_governor.c | 73 ++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/drivers/virt/steal_governor.c b/drivers/virt/steal_governor.c index d427282966d2..fda86777d6f0 100644 --- a/drivers/virt/steal_governor.c +++ b/drivers/virt/steal_governor.c @@ -37,7 +37,11 @@ struct steal_governor { struct delayed_work work; }; -static struct steal_governor sg_ctx; +static struct steal_governor sg_ctx = { + .interval_ms = 1000, /* 1 second */ + .high_threshold = 500, /* 5% */ + .low_threshold = 200, /* 2% */ +}; static void restore_preferred_to_active(void) { @@ -48,9 +52,74 @@ static void restore_preferred_to_active(void) set_cpu_preferred(cpu, true); } +static int param_set_interval_ms(const char *val, const struct kernel_param *kp) +{ + unsigned int interval; + int ret; + + ret = kstrtouint(val, 0, &interval); + if (ret) + return ret; + + if (interval < 100 || interval > 100000) { + pr_err("interval_ms must be between 100 and 100000\n"); + return -EINVAL; + } + + return param_set_uint(val, kp); +} + +static const struct kernel_param_ops interval_ms_ops = { + .set = param_set_interval_ms, + .get = param_get_uint, +}; + +module_param_cb(interval_ms, &interval_ms_ops, &sg_ctx.interval_ms, 0444); +MODULE_PARM_DESC(interval_ms, + "Sampling frequency in milliseconds. default: 1000"); + +static int param_set_high_threshold(const char *val, const struct kernel_param *kp) +{ + unsigned int threshold; + int ret; + + ret = kstrtouint(val, 0, &threshold); + if (ret) + return ret; + + if (threshold >= 100 * 100) { + pr_err("high_threshold (%u) can't be more than 99.99%%\n", threshold); + return -EINVAL; + } + + return param_set_uint(val, kp); +} + +static const struct kernel_param_ops high_threshold_ops = { + .set = param_set_high_threshold, + .get = param_get_uint, +}; + +module_param_cb(high_threshold, &high_threshold_ops, &sg_ctx.high_threshold, 0444); +MODULE_PARM_DESC(high_threshold, + "High steal threshold. default: 500 i.e 5%. Must be > low_threshold"); + +module_param_named(low_threshold, sg_ctx.low_threshold, uint, 0444); +MODULE_PARM_DESC(low_threshold, + "Low steal threshold. default: 200 i.e 2%. Must be < high_threshold"); + static int __init steal_governor_init(void) { - pr_info("enabled\n"); + if (sg_ctx.low_threshold >= sg_ctx.high_threshold) { + pr_err("low_threshold (%u) must be less than high_threshold (%u)\n", + sg_ctx.low_threshold, sg_ctx.high_threshold); + return -EINVAL; + } + + sg_ctx.delay = msecs_to_jiffies(sg_ctx.interval_ms); + pr_info("enabled. interval: %ums, high_threshold: %u, low_threshold: %u\n", + sg_ctx.interval_ms, sg_ctx.high_threshold, sg_ctx.low_threshold); + return 0; } -- 2.47.3