diff options
author | Mete Durlu <meted@linux.ibm.com> | 2024-08-12 13:39:38 +0200 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2024-08-29 22:56:35 +0200 |
commit | 441cc6f5b66e814405766ddec4af5071d22e98da (patch) | |
tree | b5ad68300fe0b11eed06e9e3b6dbed08637e2c6f /arch/s390 | |
parent | b9271a533433dd4049723d4668418709e1927e12 (diff) |
s390/hiperdispatch: Add hiperdispatch debug attributes
Add two attributes for debug purposes. They can be found under;
/sys/devices/system/cpu/hiperdispatch/
* hd_stime_threshold : allows user to adjust steal time threshold
* hd_delay_factor : allows user to adjust delay factor of hiperdispatch
work (after topology updates, delayed work is
always delayed extra by this factor)
hd_stime_threshold can have values between 0-100 as it represents a
percentage value.
hd_delay_factor can have values greater than 1. It is multiplied with
the default delay to achieve a longer interval, pushing back the next
hiperdispatch adjustment after a topology update.
Ex:
if delay interval is 250ms and the delay factor is 4;
delayed interval is now 1000ms(1sec). After each capacity adjustment
or topology change, work has a delayed interval of 1 sec for one
interval.
Acked-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Mete Durlu <meted@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/kernel/hiperdispatch.c | 84 |
1 files changed, 82 insertions, 2 deletions
diff --git a/arch/s390/kernel/hiperdispatch.c b/arch/s390/kernel/hiperdispatch.c index 8ff4adab7402..d38710f39d81 100644 --- a/arch/s390/kernel/hiperdispatch.c +++ b/arch/s390/kernel/hiperdispatch.c @@ -46,7 +46,9 @@ */ #include <linux/cpumask.h> +#include <linux/device.h> #include <linux/kernel_stat.h> +#include <linux/kstrtox.h> #include <linux/ktime.h> #include <linux/sysctl.h> #include <linux/workqueue.h> @@ -71,6 +73,8 @@ static int hd_online_cores; /* Current online CORE count */ static unsigned long hd_previous_steal; /* Previous iteration's CPU steal timer total */ +static unsigned int hd_steal_threshold = HD_STEAL_THRESHOLD; +static unsigned int hd_delay_factor = HD_DELAY_FACTOR; static int hd_enabled; static void hd_capacity_work_fn(struct work_struct *work); @@ -151,7 +155,7 @@ int hd_enable_hiperdispatch(void) return 0; if (hd_online_cores <= hd_entitled_cores) return 0; - mod_delayed_work(system_wq, &hd_capacity_work, HD_DELAY_INTERVAL * HD_DELAY_FACTOR); + mod_delayed_work(system_wq, &hd_capacity_work, HD_DELAY_INTERVAL * hd_delay_factor); hd_update_capacities(); return 1; } @@ -214,7 +218,7 @@ static void hd_capacity_work_fn(struct work_struct *work) return; } steal_percentage = hd_steal_avg(hd_calculate_steal_percentage()); - if (steal_percentage < HD_STEAL_THRESHOLD) + if (steal_percentage < hd_steal_threshold) new_cores = hd_online_cores; else new_cores = hd_entitled_cores; @@ -260,6 +264,81 @@ static struct ctl_table hiperdispatch_ctl_table[] = { }, }; +static ssize_t hd_steal_threshold_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%u\n", hd_steal_threshold); +} + +static ssize_t hd_steal_threshold_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + unsigned int val; + int rc; + + rc = kstrtouint(buf, 0, &val); + if (rc) + return rc; + if (val > 100) + return -ERANGE; + hd_steal_threshold = val; + return count; +} + +static DEVICE_ATTR_RW(hd_steal_threshold); + +static ssize_t hd_delay_factor_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sysfs_emit(buf, "%u\n", hd_delay_factor); +} + +static ssize_t hd_delay_factor_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + unsigned int val; + int rc; + + rc = kstrtouint(buf, 0, &val); + if (rc) + return rc; + if (!val) + return -ERANGE; + hd_delay_factor = val; + return count; +} + +static DEVICE_ATTR_RW(hd_delay_factor); + +static struct attribute *hd_attrs[] = { + &dev_attr_hd_steal_threshold.attr, + &dev_attr_hd_delay_factor.attr, + NULL, +}; + +static const struct attribute_group hd_attr_group = { + .name = "hiperdispatch", + .attrs = hd_attrs, +}; + +static void __init hd_create_attributes(void) +{ + struct device *dev; + + dev = bus_get_dev_root(&cpu_subsys); + if (!dev) + return; + if (sysfs_create_group(&dev->kobj, &hd_attr_group)) + pr_warn("Unable to create hiperdispatch attribute group\n"); + put_device(dev); +} + static int __init hd_init(void) { if (IS_ENABLED(CONFIG_HIPERDISPATCH_ON)) { @@ -268,6 +347,7 @@ static int __init hd_init(void) } if (!register_sysctl("s390", hiperdispatch_ctl_table)) pr_warn("Failed to register s390.hiperdispatch sysctl attribute\n"); + hd_create_attributes(); return 0; } late_initcall(hd_init); |