mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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. Signed-off-by: Tejun Heo <tj@kernel.org>
This commit is contained in:
		
							parent
							
								
									c03cd7738a
								
							
						
					
					
						commit
						a5e112e642
					
				
					 3 changed files with 51 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -696,6 +696,12 @@ Conventions
 | 
			
		|||
  informational files on the root cgroup which end up showing global
 | 
			
		||||
  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
 | 
			
		||||
  interface file should be named "weight" and have the range [1,
 | 
			
		||||
  10000] with 100 as the default.  The values are chosen to allow
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,6 +131,8 @@ void cgroup_free(struct task_struct *p);
 | 
			
		|||
int cgroup_init_early(void);
 | 
			
		||||
int cgroup_init(void);
 | 
			
		||||
 | 
			
		||||
int cgroup_parse_float(const char *input, unsigned dec_shift, s64 *v);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Iteration helpers and macros.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6387,4 +6387,47 @@ static int __init cgroup_sysfs_init(void)
 | 
			
		|||
	return sysfs_create_group(kernel_kobj, &cgroup_sysfs_attr_group);
 | 
			
		||||
}
 | 
			
		||||
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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue