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

Commit 3703043a authored by Tejun Heo's avatar Tejun Heo Committed by Quentin Perret
Browse files

UPSTREAM: cgroup: add cgroup_parse_float()



cgroup already uses floating point for percent[ile] numbers and there
are several controllers which want to take them as input.  Add a
generic parse helper to handle inputs.

Update the interface convention documentation about the use of
percentage numbers.  While at it, also clarify the default time unit.

Bug: 120440300
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
(cherry picked from commit a5e112e6424adb77d953eac20e6936b952fd6b32)
Signed-off-by: default avatarQais Yousef <qais.yousef@arm.com>
Change-Id: Ic1fcf21d7955eb8edd2e8e91517bca6aef41694f
Signed-off-by: default avatarQuentin Perret <qperret@google.com>
parent cc8657ff
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -694,6 +694,12 @@ Conventions
  informational files on the root cgroup which end up showing global
  informational files on the root cgroup which end up showing global
  information available elsewhere shouldn't exist.
  information available elsewhere shouldn't exist.


- The default time unit is microseconds.  If a different unit is ever
  used, an explicit unit suffix must be present.

- A parts-per quantity should use a percentage decimal with at least
  two digit fractional part - e.g. 13.40.

- If a controller implements weight based resource distribution, its
- If a controller implements weight based resource distribution, its
  interface file should be named "weight" and have the range [1,
  interface file should be named "weight" and have the range [1,
  10000] with 100 as the default.  The values are chosen to allow
  10000] with 100 as the default.  The values are chosen to allow
+2 −0
Original line number Original line Diff line number Diff line
@@ -129,6 +129,8 @@ void cgroup_free(struct task_struct *p);
int cgroup_init_early(void);
int cgroup_init_early(void);
int cgroup_init(void);
int cgroup_init(void);


int cgroup_parse_float(const char *input, unsigned dec_shift, s64 *v);

/*
/*
 * Iteration helpers and macros.
 * Iteration helpers and macros.
 */
 */
+43 −0
Original line number Original line Diff line number Diff line
@@ -6171,4 +6171,47 @@ static int __init cgroup_sysfs_init(void)
	return sysfs_create_group(kernel_kobj, &cgroup_sysfs_attr_group);
	return sysfs_create_group(kernel_kobj, &cgroup_sysfs_attr_group);
}
}
subsys_initcall(cgroup_sysfs_init);
subsys_initcall(cgroup_sysfs_init);

static u64 power_of_ten(int power)
{
	u64 v = 1;
	while (power--)
		v *= 10;
	return v;
}

/**
 * cgroup_parse_float - parse a floating number
 * @input: input string
 * @dec_shift: number of decimal digits to shift
 * @v: output
 *
 * Parse a decimal floating point number in @input and store the result in
 * @v with decimal point right shifted @dec_shift times.  For example, if
 * @input is "12.3456" and @dec_shift is 3, *@v will be set to 12345.
 * Returns 0 on success, -errno otherwise.
 *
 * There's nothing cgroup specific about this function except that it's
 * currently the only user.
 */
int cgroup_parse_float(const char *input, unsigned dec_shift, s64 *v)
{
	s64 whole, frac = 0;
	int fstart = 0, fend = 0, flen;

	if (!sscanf(input, "%lld.%n%lld%n", &whole, &fstart, &frac, &fend))
		return -EINVAL;
	if (frac < 0)
		return -EINVAL;

	flen = fend > fstart ? fend - fstart : 0;
	if (flen < dec_shift)
		frac *= power_of_ten(dec_shift - flen);
	else
		frac = DIV_ROUND_CLOSEST_ULL(frac, power_of_ten(flen - dec_shift));

	*v = whole * power_of_ten(dec_shift) + frac;
	return 0;
}

#endif /* CONFIG_SYSFS */
#endif /* CONFIG_SYSFS */