mirror of
https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9.git
synced 2026-09-09 00:08:12 +08:00
Merge: Backport upstream solution to isolate EFI Runtime Services to a CPU [RHEL-9.x]
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/8138 JIRA: https://redhat.atlassian.net/browse/RHEL-175657 Most EFI Runtime Services will require the execution of hardware-specific, highly privileged code without interference from the Operating System. That is usually achieved on X86_64 via SMI/SMM and on ARM64 via SMC/EL3. Obviously the implementations of the base idea vary widely and are heavily dependent on the underlying hardware, firmware and BIOS. The patches from Sebastian Andrzej Siewior[1], backported here, make it possible to set the CPUMASK for the workqueue that wraps the access to the efI callbacks. In order to set a CPU or group of CPUs to serve the EFI Runtime requests, one simply writes the desired CPUMASK to /sys/devices/virtual/workqueue/efi_runtime/cpumask The effect of this MR is different for x86_64 and ARM64: - ARM64: an EFI Runtime Service request will generate a SMC (Secure Monitor Call) that will trap into EL3 (Exception Level 3) where the specific request will be handled. On ARM64 the SMC calls are usually isolated to the CPU serving the request, making it possible to use ideas such as Sebastian Siewior's proposal[1] to select a CPU or set of CPUs to serve EFI Runtime requests, making it possible to keep the remaining CPUs free from that noise. - X86_64: EFI Runtime Service requests will trigger SMI (System Management Interrupt) that will force the CPU to switch into SMM (System Management Mode) to execute the specific request. The effect of a SMI in the system is heavily dependent on the actual Hardware, firmware and BIOS implementations. Modern systems provide BIOS presets (with names such as "Telco" or "Low Latency") that along with other settings, isolate SMI effects to a single CPU or to a socket. In our earlier experiences, some of these extra settings unfortunately may induce other sources of latency, so caution and experimentation is advised. In any case, for most systems the effects of an SMI (which may come from EFI Runtime Services execution) are system wide, causing latency spikes on all CPUs. That said, the gains from Sebastian's proposal[1] for X86_64 may vary. [1] https://lore.kernel.org/linux-rt-devel/20260227170103.4042157-1-bigeasy@linutronix.de/ Signed-off-by: Luis Claudio R. Goncalves <lgoncalv@redhat.com> Approved-by: Crystal Wood <crwood@redhat.com> Approved-by: Phil Auld <pauld@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
This commit is contained in:
@@ -419,7 +419,7 @@ static int __init efisubsys_init(void)
|
||||
* ordered workqueue (which creates only one execution context)
|
||||
* should suffice for all our needs.
|
||||
*/
|
||||
efi_rts_wq = alloc_ordered_workqueue("efi_rts_wq", 0);
|
||||
efi_rts_wq = alloc_ordered_workqueue("efi_runtime", WQ_SYSFS);
|
||||
if (!efi_rts_wq) {
|
||||
pr_err("Creating efi_rts_wq failed, EFI runtime services disabled.\n");
|
||||
clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
|
||||
|
||||
+20
-8
@@ -7147,7 +7147,26 @@ static struct attribute *wq_sysfs_attrs[] = {
|
||||
&dev_attr_max_active.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(wq_sysfs);
|
||||
|
||||
static umode_t wq_sysfs_is_visible(struct kobject *kobj, struct attribute *a, int n)
|
||||
{
|
||||
struct device *dev = kobj_to_dev(kobj);
|
||||
struct workqueue_struct *wq = dev_to_wq(dev);
|
||||
|
||||
/*
|
||||
* Adjusting max_active breaks ordering guarantee. Changing it has no
|
||||
* effect on BH worker. Limit max_active to RO in such case.
|
||||
*/
|
||||
if (wq->flags & (WQ_BH | __WQ_ORDERED))
|
||||
return 0444;
|
||||
return a->mode;
|
||||
}
|
||||
|
||||
static const struct attribute_group wq_sysfs_group = {
|
||||
.is_visible = wq_sysfs_is_visible,
|
||||
.attrs = wq_sysfs_attrs,
|
||||
};
|
||||
__ATTRIBUTE_GROUPS(wq_sysfs);
|
||||
|
||||
static void apply_wqattrs_lock(void)
|
||||
{
|
||||
@@ -7468,13 +7487,6 @@ int workqueue_sysfs_register(struct workqueue_struct *wq)
|
||||
struct wq_device *wq_dev;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Adjusting max_active breaks ordering guarantee. Disallow exposing
|
||||
* ordered workqueues.
|
||||
*/
|
||||
if (WARN_ON(wq->flags & __WQ_ORDERED))
|
||||
return -EINVAL;
|
||||
|
||||
wq->wq_dev = wq_dev = kzalloc(sizeof(*wq_dev), GFP_KERNEL);
|
||||
if (!wq_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
Reference in New Issue
Block a user