Kernel Sysfs Param Storage function - Get calling parameter

Y

Yoinx

Guest
So, I hate to ask because I'm sure this is really simple...

I have this function that is storing a sysfs value. To save space, I have 4 different parameters sharing the function as it's basically the same function for each. I'd like to check which parameter is calling the function so that I can perform some checks depending on the parameter (ie, that each is in a logical order compared to it's neighboring values). How would I get the name of parameter that called it?

https://gist.github.com/yoinx/6a3ff00945f3ec1db230

embedded to avoid the link:
Code:
/* Frequency limit storage */
static int set_freq_limit(const char *val, const struct kernel_param *kp)
{
	int ret = 0;
	int i, cnt;
	int valid = 0;
	struct cpufreq_policy *policy;
	static struct cpufreq_frequency_table *tbl = NULL;
	
	ret = kstrtouint(val, 10, &i);
	if (ret)
		return -EINVAL;

	policy = cpufreq_cpu_get(0);
	tbl = cpufreq_frequency_get_table(0);
	for (cnt = 0; (tbl[cnt].frequency != CPUFREQ_TABLE_END); cnt++) {
		if (cnt > 0)
			if (tbl[cnt].frequency == i)
				valid = 1;
	}
	if (!valid)
		return -EINVAL;
	
	ret = param_set_int(val, kp);

	return ret;
}

static struct kernel_param_ops freq_limit_ops = {
	.set = set_freq_limit,
	.get = param_get_int,
};

module_param_cb(freq_hell, &freq_limit_ops, &FREQ_HELL, 0644);
module_param_cb(freq_very_hot, &freq_limit_ops, &FREQ_VERY_HOT, 0644);
module_param_cb(freq_hot, &freq_limit_ops, &FREQ_HOT, 0644);
module_param_cb(freq_warm, &freq_limit_ops, &FREQ_WARM, 0644);
I could go even more sloppy and just duplicate this function repeatedly... But I'd rather not.

I thought kp would hold the kernel parameter... but it's a structure, not a variable... So I'm not positive what value in the structure would hold the name.

Thanks for the help.

Edit:

Would it be kp->name?
 
Last edited:
Y

Yoinx

Guest
Ok, so not sure why it wouldn't work for me the other day... Which is what lead me to this post.

It was indeed kp->name, like I expected it to be. When I was trying to test it in a printk, it was causing a kernel panic though. Whatever, it worked now.

It prints out as module.param, just in case this helps anyone in the future.

*Edit*

Here's how I ended up doing this. Again, in case it helps anyone in the future.

Code:
/* Frequency limit storage */
static int set_freq_limit(const char *val, const struct kernel_param *kp)
{
	int ret = 0;
	int i, cnt;
	int valid = 0;
	struct cpufreq_policy *policy;
	static struct cpufreq_frequency_table *tbl = NULL;
	
	ret = kstrtouint(val, 10, &i);
	if (ret)
		return -EINVAL;

	policy = cpufreq_cpu_get(0);
	tbl = cpufreq_frequency_get_table(0);
	for (cnt = 0; (tbl[cnt].frequency != CPUFREQ_TABLE_END); cnt++) {
		if (cnt > 0)
			if (tbl[cnt].frequency == i)
				valid = 1;
	}
	if (!valid)
		return -EINVAL;
	
	/* Perform some sanity checks on the values that we're storing 
	 * to make sure that they're scaling linearly 					*/
	if (strcmp( kp->name, "msm_thermal.freq_warm") == 0 && i <= FREQ_HOT) 
		return -EINVAL;
	if ( strcmp( kp->name, "msm_thermal.freq_hot") == 0 &&  ( i >= FREQ_WARM || i <= FREQ_VERY_HOT ))
		return -EINVAL;	
	if ( strcmp( kp->name, "msm_thermal.freq_very_hot") == 0 && ( i >= FREQ_HOT || i <= FREQ_HELL ))
		return -EINVAL;		
	if ( strcmp( kp->name, "msm_thermal.freq_hell") == 0 && i >= FREQ_VERY_HOT ) 
		return -EINVAL;		
	/* End Sanity Checks */
	
	ret = param_set_int(val, kp);

	return ret;
}

static struct kernel_param_ops freq_limit_ops = {
	.set = set_freq_limit,
	.get = param_get_int,
};

module_param_cb(freq_hell, &freq_limit_ops, &FREQ_HELL, 0644);
module_param_cb(freq_very_hot, &freq_limit_ops, &FREQ_VERY_HOT, 0644);
module_param_cb(freq_hot, &freq_limit_ops, &FREQ_HOT, 0644);
module_param_cb(freq_warm, &freq_limit_ops, &FREQ_WARM, 0644);
 
Last edited: