Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 00d72d6b authored by Santosh Mardi's avatar Santosh Mardi
Browse files

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: default avatarSantosh Mardi <gsantosh@codeaurora.org>
parent 56fc321f
Loading
Loading
Loading
Loading
+41 −2
Original line number Diff line number Diff line
@@ -171,6 +171,9 @@ static DEVICE_ATTR(__attr, 0644, show_list_##__attr, store_list_##__attr)
#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)
{
@@ -759,11 +762,42 @@ static ssize_t show_throttle_adj(struct device *dev,
static DEVICE_ATTR(throttle_adj, 0644, show_throttle_adj,
						store_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 snprintf(buf, PAGE_SIZE, "%u\n", node->sample_ms);
}

static DEVICE_ATTR_RW(sample_ms);

gov_attr(guard_band_mbps, 0U, 2000U);
gov_attr(decay_rate, 0U, 100U);
gov_attr(io_percent, 1U, 100U);
gov_attr(bw_step, 50U, 1000U);
gov_attr(sample_ms, 1U, 50U);
gov_attr(up_scale, 0U, 500U);
gov_attr(up_thres, 1U, 100U);
gov_attr(down_thres, 0U, 90U);
@@ -830,7 +864,13 @@ static int devfreq_bw_hwmon_ev_handler(struct devfreq *df,
		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);
		/*
@@ -839,7 +879,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);