From b5382b84b60be4ea376aa0218c665c9ff5537e31 Mon Sep 17 00:00:00 2001 From: Santosh Mardi Date: Fri, 25 Oct 2019 15:34:47 +0530 Subject: [PATCH 1/2] devfreq: update sample_ms tunnable store function The sample_ms should never be larger than the devfreq polling interval. If userspace tries to configure this invalid configuration, return an error. Devfreq polling interval should be always greater then the sample_ms add check in the governor interval event to update the polling interval accordingly. Change-Id: I2d07c95668a7fc8e3b2f16e49448ad2e3da8785c Signed-off-by: Santosh Mardi [avajid@codeaurora.org: Replaced snprintf with scnprintf] Signed-off-by: Amir Vajid --- drivers/devfreq/governor_bw_hwmon.c | 47 ++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/drivers/devfreq/governor_bw_hwmon.c b/drivers/devfreq/governor_bw_hwmon.c index 5ee56f108fa2..e2c5ed06ce76 100644 --- a/drivers/devfreq/governor_bw_hwmon.c +++ b/drivers/devfreq/governor_bw_hwmon.c @@ -153,6 +153,9 @@ out: \ #define MIN_MS 10U #define MAX_MS 500U +#define SAMPLE_MIN_MS 1U +#define SAMPLE_MAX_MS 50U + /* Returns MBps of read/writes for the sampling window. */ static unsigned long bytes_to_mbps(unsigned long long bytes, unsigned int us) { @@ -739,11 +742,43 @@ static ssize_t throttle_adj_show(struct device *dev, else val = node->hw->get_throttle_adj(node->hw); - return snprintf(buf, PAGE_SIZE, "%u\n", val); + return scnprintf(buf, PAGE_SIZE, "%u\n", val); } static DEVICE_ATTR_RW(throttle_adj); +static ssize_t sample_ms_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct devfreq *df = to_devfreq(dev); + struct hwmon_node *hw = df->data; + int ret; + unsigned int val; + + ret = kstrtoint(buf, 10, &val); + if (ret) + return ret; + + val = max(val, SAMPLE_MIN_MS); + val = min(val, SAMPLE_MAX_MS); + if (val > df->profile->polling_ms) + return -EINVAL; + + hw->sample_ms = val; + return count; +} + +static ssize_t sample_ms_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct devfreq *df = to_devfreq(dev); + struct hwmon_node *node = df->data; + + return scnprintf(buf, PAGE_SIZE, "%u\n", node->sample_ms); +} + +static DEVICE_ATTR_RW(sample_ms); + show_attr(guard_band_mbps); store_attr(guard_band_mbps, 0U, 2000U); static DEVICE_ATTR_RW(guard_band_mbps); @@ -756,9 +791,6 @@ static DEVICE_ATTR_RW(io_percent); show_attr(bw_step); store_attr(bw_step, 50U, 1000U); static DEVICE_ATTR_RW(bw_step); -show_attr(sample_ms); -store_attr(sample_ms, 1U, 50U); -static DEVICE_ATTR_RW(sample_ms); show_attr(up_scale); store_attr(up_scale, 0U, 500U); static DEVICE_ATTR_RW(up_scale); @@ -841,7 +873,13 @@ static int devfreq_bw_hwmon_ev_handler(struct devfreq *df, "Disabled dev BW HW monitor governor\n"); break; case DEVFREQ_GOV_INTERVAL: + node = df->data; sample_ms = *(unsigned int *)data; + if (sample_ms < node->sample_ms) { + ret = -EINVAL; + goto out; + } + sample_ms = max(MIN_MS, sample_ms); sample_ms = min(MAX_MS, sample_ms); /* @@ -850,7 +888,6 @@ static int devfreq_bw_hwmon_ev_handler(struct devfreq *df, * stop/start the delayed workqueue while the interval update * is happening. */ - node = df->data; hw = node->hw; hw->suspend_hwmon(hw); devfreq_interval_update(df, &sample_ms); From 1ec246bf081d32f9eb753cf4f0f76a12db5daa27 Mon Sep 17 00:00:00 2001 From: Santosh Mardi Date: Mon, 21 Oct 2019 11:02:58 +0530 Subject: [PATCH 2/2] devfreq: update sampling window timer limit Current SW limit is not matching the HW limit, update limit to align with the available HW limit. Change-Id: I6e221136142785a98e3cd378915b2139904f1551 Signed-off-by: Santosh Mardi --- drivers/devfreq/bimc-bwmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/devfreq/bimc-bwmon.c b/drivers/devfreq/bimc-bwmon.c index 286d313c18ed..668477348ae9 100644 --- a/drivers/devfreq/bimc-bwmon.c +++ b/drivers/devfreq/bimc-bwmon.c @@ -186,7 +186,7 @@ void mon_clear(struct bwmon *m, bool clear_all, enum mon_reg_type type) mb(); } -#define SAMPLE_WIN_LIM 0xFFFFF +#define SAMPLE_WIN_LIM 0xFFFFFF static __always_inline void mon_set_hw_sampling_window(struct bwmon *m, unsigned int sample_ms, enum mon_reg_type type)