From nobody Thu Apr 2 16:58:15 2026 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.9]) (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 427C538B9A3 for ; Tue, 10 Feb 2026 22:13:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.9 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770761624; cv=none; b=Od7ihFB8AVd6Cn8BuKEbyMIAdfAMXEssL2hGePb0c0MVlkNOogl+q8QUje6dCMQLCZIsDhjyOG2vtRBJqjc+ZKqyzdY6C35WRwgcuvkdy35YeZydVyxIHDIfT21FvGoUMJeM+ggHReSzOtJT4uV2ulENrTsoH0IeS46QUPSt6Kw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770761624; c=relaxed/simple; bh=DdamgIBRlreQFym+IV+sNw42fL88iaPB67NI+vDOkMM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=TwpFD5O9IVCkUVjdY4hfFhYvV3mSS4SrG3Lh1JNpU1utrCc2+rHI+OL+ZbKnJxa2SquQQs+6IBh+lKL5Qf7lzqA1g45dw/YRuWwDXek8NRnJfQzikIcVD/Qhkumx3utvJgxSoXGWrxrSZniNkXBZA+T1yxgTVSNg8ECNSwMUiiE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=pass smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=V1IqKXYw; arc=none smtp.client-ip=192.198.163.9 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="V1IqKXYw" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1770761623; x=1802297623; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=DdamgIBRlreQFym+IV+sNw42fL88iaPB67NI+vDOkMM=; b=V1IqKXYwHhRY5C7YiOyfngX/dOXZ4NNIiWEOOW3TxycdigBrxHFYnbsT 3DzaTWG/+ug2ZoMnhhNb1kNSAWQgVhaqYo0SIHSz1aY8a+Hm43IRHB5k/ dbQfsW43dBCz7QQVw3lTRg2E3Imu6GAkJiepCvbfYSH8lXeicZUxcUvgm mhQcszGHh99DKdD1fmCNjUcLzw7qSUnCozp1BOuEKpNI/S8qKnN4NDiNe XQb20118VMqify/ZEkeJ2Np2clD01N+D3peo9eF08PiDMVOVDfXTQBMW2 hZL7GdI9ZI2Kxw6YNdfQlU8kkVSVFrzzGjwr9temIuTOab+O2p9+dn491 A==; X-CSE-ConnectionGUID: v417zybOThewi8t7Sry5uw== X-CSE-MsgGUID: 3JI9lRqWTuyM1woUKV7Now== X-IronPort-AV: E=McAfee;i="6800,10657,11697"; a="82631588" X-IronPort-AV: E=Sophos;i="6.21,283,1763452800"; d="scan'208";a="82631588" Received: from fmviesa004.fm.intel.com ([10.60.135.144]) by fmvoesa103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Feb 2026 14:13:42 -0800 X-CSE-ConnectionGUID: uKw0XR9HQVylq7/DW8VW6w== X-CSE-MsgGUID: r+C0uYY1SR2HVCVoeEQ0EA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.21,283,1763452800"; d="scan'208";a="216374029" Received: from b04f130c83f2.jf.intel.com ([10.165.154.98]) by fmviesa004.fm.intel.com with ESMTP; 10 Feb 2026 14:13:42 -0800 From: Tim Chen To: Peter Zijlstra , Ingo Molnar , K Prateek Nayak , "Gautham R . Shenoy" , Vincent Guittot Cc: Chen Yu , Juri Lelli , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Valentin Schneider , Madadi Vineeth Reddy , Hillf Danton , Shrikanth Hegde , Jianyong Wu , Yangyu Chen , Tingyin Duan , Vern Hao , Vern Hao , Len Brown , Tim Chen , Aubrey Li , Zhao Liu , Chen Yu , Adam Li , Aaron Lu , Tim Chen , Josh Don , Gavin Guo , Qais Yousef , Libo Chen , linux-kernel@vger.kernel.org Subject: [PATCH v3 18/21] sched/cache: Allow the user space to turn on and off cache aware scheduling Date: Tue, 10 Feb 2026 14:18:58 -0800 Message-Id: <57f431298bf6346d37a3046ec771898607ae6ccf.1770760558.git.tim.c.chen@linux.intel.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Chen Yu Provide a debugfs knob to allow the user to turn off and on the cache aware scheduling at runtime. Signed-off-by: Chen Yu Signed-off-by: Tim Chen --- Notes: v2->v3: Split into a new patch for better review, use kstrtobool_from_user() to get the user input. (Peter Zijlstra) kernel/sched/debug.c | 45 ++++++++++++++++++++++++++++ kernel/sched/sched.h | 7 +++-- kernel/sched/topology.c | 65 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 2 deletions(-) diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 41caa22e0680..bae747eddc59 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c @@ -215,6 +215,46 @@ static const struct file_operations sched_scaling_fops= =3D { .release =3D single_release, }; =20 +#ifdef CONFIG_SCHED_CACHE +static ssize_t +sched_cache_enable_write(struct file *filp, const char __user *ubuf, + size_t cnt, loff_t *ppos) +{ + bool val; + int ret; + + ret =3D kstrtobool_from_user(ubuf, cnt, &val); + if (ret) + return ret; + + sysctl_sched_cache_user =3D val; + + sched_cache_active_set_unlocked(); + + return cnt; +} + +static int sched_cache_enable_show(struct seq_file *m, void *v) +{ + seq_printf(m, "%d\n", sysctl_sched_cache_user); + return 0; +} + +static int sched_cache_enable_open(struct inode *inode, + struct file *filp) +{ + return single_open(filp, sched_cache_enable_show, NULL); +} + +static const struct file_operations sched_cache_enable_fops =3D { + .open =3D sched_cache_enable_open, + .write =3D sched_cache_enable_write, + .read =3D seq_read, + .llseek =3D seq_lseek, + .release =3D single_release, +}; +#endif + #ifdef CONFIG_PREEMPT_DYNAMIC =20 static ssize_t sched_dynamic_write(struct file *filp, const char __user *u= buf, @@ -523,6 +563,11 @@ static __init int sched_init_debug(void) debugfs_create_u32("hot_threshold_ms", 0644, numa, &sysctl_numa_balancing= _hot_threshold); #endif /* CONFIG_NUMA_BALANCING */ =20 +#ifdef CONFIG_SCHED_CACHE + debugfs_create_file("llc_enabled", 0644, debugfs_sched, NULL, + &sched_cache_enable_fops); +#endif + debugfs_create_file("debug", 0444, debugfs_sched, NULL, &sched_debug_fops= ); =20 debugfs_fair_server_init(); diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 59ac04625842..adf3428745dd 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -3917,12 +3917,15 @@ static inline void mm_cid_switch_to(struct task_str= uct *prev, struct task_struct =20 #ifdef CONFIG_SCHED_CACHE DECLARE_STATIC_KEY_FALSE(sched_cache_present); -extern int max_llcs; +DECLARE_STATIC_KEY_FALSE(sched_cache_active); +extern int max_llcs, sysctl_sched_cache_user; =20 static inline bool sched_cache_enabled(void) { - return static_branch_unlikely(&sched_cache_present); + return static_branch_unlikely(&sched_cache_active); } + +extern void sched_cache_active_set_unlocked(void); #endif extern void init_sched_mm(struct task_struct *p); =20 diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index 9104fed25351..e86dea1b9e86 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -801,7 +801,16 @@ enum s_alloc { }; =20 #ifdef CONFIG_SCHED_CACHE +/* hardware support for cache aware scheduling */ DEFINE_STATIC_KEY_FALSE(sched_cache_present); +/* + * Indicator of whether cache aware scheduling + * is active, used by the scheduler. + */ +DEFINE_STATIC_KEY_FALSE(sched_cache_active); +/* user wants cache aware scheduling [0 or 1] */ +int sysctl_sched_cache_user =3D 1; + static bool alloc_sd_pref(const struct cpumask *cpu_map, struct s_data *d) { @@ -833,6 +842,60 @@ static bool alloc_sd_pref(const struct cpumask *cpu_ma= p, =20 return false; } + +static void _sched_cache_active_set(bool enable, bool locked) +{ + if (enable) { + if (locked) + static_branch_enable_cpuslocked(&sched_cache_active); + else + static_branch_enable(&sched_cache_active); + } else { + if (locked) + static_branch_disable_cpuslocked(&sched_cache_active); + else + static_branch_disable(&sched_cache_active); + } +} + +/* + * Enable/disable cache aware scheduling according to + * user input and the presence of hardware support. + */ +static void sched_cache_active_set(bool locked) +{ + /* hardware does not support */ + if (!static_branch_likely(&sched_cache_present)) { + _sched_cache_active_set(false, locked); + return; + } + + /* + * user wants it or not ? + * TBD: read before writing the static key. + * It is not in the critical path, leave as-is + * for now. + */ + if (sysctl_sched_cache_user) { + _sched_cache_active_set(true, locked); + if (sched_debug()) + pr_info("%s: enabling cache aware scheduling\n", __func__); + } else { + _sched_cache_active_set(false, locked); + if (sched_debug()) + pr_info("%s: disabling cache aware scheduling\n", __func__); + } +} + +static void sched_cache_active_set_locked(void) +{ + return sched_cache_active_set(true); +} + +void sched_cache_active_set_unlocked(void) +{ + return sched_cache_active_set(false); +} #else static bool alloc_sd_pref(const struct cpumask *cpu_map, struct s_data *d) @@ -2809,6 +2872,8 @@ build_sched_domains(const struct cpumask *cpu_map, st= ruct sched_domain_attr *att static_branch_enable_cpuslocked(&sched_cache_present); else static_branch_disable_cpuslocked(&sched_cache_present); + + sched_cache_active_set_locked(); #endif __free_domain_allocs(&d, alloc_state, cpu_map); =20 --=20 2.32.0