lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date:	Mon, 16 Nov 2009 16:50:13 +0100
From:	Takashi Iwai <tiwai@...e.de>
To:	Rusty Russell <rusty@...tcorp.com.au>
Cc:	linux-kernel@...r.kernel.org
Subject: Re: [PATCH 2/8] param: use ops in struct kernel_param, rather than get and set fns directly

At Fri, 30 Oct 2009 21:43:39 +1030,
Rusty Russell wrote:
> 
> On Fri, 30 Oct 2009 08:48:12 pm Takashi Iwai wrote:
> > At Fri, 23 Oct 2009 00:51:28 +1030,
> > Rusty Russell wrote:
> > > 
> > > This is more kernel-ish, saves some space, and also allows us to
> > > expand the ops without breaking all the callers who are happy for the
> > > new members to be NULL.
> > > 
> > > The few places which defined their own param types are changed to the
> > > new scheme.
> > > 
> > > Since we're touching them anyway, we change get and set to take a
> > > const struct kernel_param (which they were, and will be again).
> > > 
> > > To reduce churn, module_param_call creates the ops struct so the callers
> > > don't have to change (and casts the functions to reduce warnings).
> > > The modern version which takes an ops struct is called module_param_cb.
> > 
> > This is nice, as it also reduces the size of struct kernel_param, so
> > each parameter uses less footprint (who cares, though?) :)
> > 
> > But, just wondering whether we still need to export get/set
> > functions.  They can be called from ops now, so if any, it can be
> > defined even as an inlinefunction or a macro.
> 
> My thought too, so I tried that, but many are still used like so:
> 
> 	module_param_call(foo, set_foo, param_get_uint, NULL, 0644);
> 
> They can all be replaced in time with something like:
> 	static int param_get_foo(char *buffer, const struct kernel_param *kp)
> 	{
> 		return param_ops_uint.get(buffer, kp);
> 	}
> 
> But it'll take a transition period.

[Removed Cc's since it's no sub-device specific issue]

Regarding the removal of exports:

I found that static inline functions can be used also as pointers.
So, expanding them in moduleparam.h seems working actually as is.

A test patch is below.  I just did a short build-test, though.


thanks,

Takashi

===
From: Takashi Iwai <tiwai@...e.de>
Subject: param: use static inline functions for param_{get|set}_*()

Instead of exporting each param_{get|set}_*() function, expand it as
a static inline function to call the ops.{get|set}.  Since static inline
functions can be used as function pointers, the currently existing codes
work as they are.

Signed-off-by: Takashi Iwai <tiwai@...e.de>

---
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 893549c..00baae9 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -283,50 +283,53 @@ static inline void destroy_params(const struct kernel_param *params,
 #define __param_check(name, p, type) \
 	static inline type *__check_##name(void) { return(p); }
 
+/* Define param_get_xxx() and param_set_xxx() for compatibility.
+ * They are defined as inline functions so that they can be used also
+ * as function pointers.
+ */
+#define DEFINE_PARAM_GET_SET(name) \
+	static inline int param_set_##name(const char *val, \
+					   const struct kernel_param *kp) \
+	{ return param_ops_##name.set(val, kp); } \
+	static inline int param_get_##name(char *buffer, \
+					   const struct kernel_param *kp) \
+	{ return param_ops_##name.get(buffer, kp); }
+
 extern struct kernel_param_ops param_ops_byte;
-extern int param_set_byte(const char *val, const struct kernel_param *kp);
-extern int param_get_byte(char *buffer, const struct kernel_param *kp);
+DEFINE_PARAM_GET_SET(byte);
 #define param_check_byte(name, p) __param_check(name, p, unsigned char)
 
 extern struct kernel_param_ops param_ops_short;
-extern int param_set_short(const char *val, const struct kernel_param *kp);
-extern int param_get_short(char *buffer, const struct kernel_param *kp);
+DEFINE_PARAM_GET_SET(short);
 #define param_check_short(name, p) __param_check(name, p, short)
 
 extern struct kernel_param_ops param_ops_ushort;
-extern int param_set_ushort(const char *val, const struct kernel_param *kp);
-extern int param_get_ushort(char *buffer, const struct kernel_param *kp);
+DEFINE_PARAM_GET_SET(ushort);
 #define param_check_ushort(name, p) __param_check(name, p, unsigned short)
 
 extern struct kernel_param_ops param_ops_int;
-extern int param_set_int(const char *val, const struct kernel_param *kp);
-extern int param_get_int(char *buffer, const struct kernel_param *kp);
+DEFINE_PARAM_GET_SET(int);
 #define param_check_int(name, p) __param_check(name, p, int)
 
 extern struct kernel_param_ops param_ops_uint;
-extern int param_set_uint(const char *val, const struct kernel_param *kp);
-extern int param_get_uint(char *buffer, const struct kernel_param *kp);
+DEFINE_PARAM_GET_SET(uint);
 #define param_check_uint(name, p) __param_check(name, p, unsigned int)
 
 extern struct kernel_param_ops param_ops_long;
-extern int param_set_long(const char *val, const struct kernel_param *kp);
-extern int param_get_long(char *buffer, const struct kernel_param *kp);
+DEFINE_PARAM_GET_SET(long);
 #define param_check_long(name, p) __param_check(name, p, long)
 
 extern struct kernel_param_ops param_ops_ulong;
-extern int param_set_ulong(const char *val, const struct kernel_param *kp);
-extern int param_get_ulong(char *buffer, const struct kernel_param *kp);
+DEFINE_PARAM_GET_SET(ulong);
 #define param_check_ulong(name, p) __param_check(name, p, unsigned long)
 
 extern struct kernel_param_ops param_ops_charp;
-extern int param_set_charp(const char *val, const struct kernel_param *kp);
-extern int param_get_charp(char *buffer, const struct kernel_param *kp);
+DEFINE_PARAM_GET_SET(charp);
 #define param_check_charp(name, p) __param_check(name, p, char *)
 
 /* For historical reasons "bool" parameters can be (unsigned) "int". */
 extern struct kernel_param_ops param_ops_bool;
-extern int param_set_bool(const char *val, const struct kernel_param *kp);
-extern int param_get_bool(char *buffer, const struct kernel_param *kp);
+DEFINE_PARAM_GET_SET(bool);
 #define param_check_bool(name, p)					\
 	static inline void __check_##name(void)				\
 	{								\
@@ -336,8 +339,7 @@ extern int param_get_bool(char *buffer, const struct kernel_param *kp);
 	}
 
 extern struct kernel_param_ops param_ops_invbool;
-extern int param_set_invbool(const char *val, const struct kernel_param *kp);
-extern int param_get_invbool(char *buffer, const struct kernel_param *kp);
+DEFINE_PARAM_GET_SET(invbool);
 #define param_check_invbool(name, p) __param_check(name, p, bool)
 
 /**
@@ -380,8 +382,15 @@ extern int param_get_invbool(char *buffer, const struct kernel_param *kp);
 extern struct kernel_param_ops param_array_ops;
 
 extern struct kernel_param_ops param_ops_string;
-extern int param_set_copystring(const char *val, const struct kernel_param *);
-extern int param_get_string(char *buffer, const struct kernel_param *kp);
+static inline int param_set_copystring(const char *val,
+				       const struct kernel_param *kp)
+{
+	return param_ops_string.set(val, kp);
+}
+static inline int param_get_string(char *buffer, const struct kernel_param *kp)
+{
+	return param_ops_string.get(buffer, kp);
+}
 
 /* for exporting parameters in /sys/parameters */
 
diff --git a/kernel/params.c b/kernel/params.c
index 9ed6fcd..12513f1 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -219,7 +219,7 @@ int parse_args(const char *name,
 
 /* Lazy bastard, eh? */
 #define STANDARD_PARAM_DEF(name, type, format, tmptype, strtolfn)      	\
-	int param_set_##name(const char *val, const struct kernel_param *kp) \
+	static int _param_set_##name(const char *val, const struct kernel_param *kp) \
 	{								\
 		tmptype l;						\
 		int ret;						\
@@ -231,16 +231,14 @@ int parse_args(const char *name,
 		*((type *)kp->arg) = l;					\
 		return 0;						\
 	}								\
-	int param_get_##name(char *buffer, const struct kernel_param *kp) \
+	static int _param_get_##name(char *buffer, const struct kernel_param *kp) \
 	{								\
 		return sprintf(buffer, format, *((type *)kp->arg));	\
 	}								\
 	struct kernel_param_ops param_ops_##name = {			\
-		.set = param_set_##name,				\
-		.get = param_get_##name,				\
+		.set = _param_set_##name,				\
+		.get = _param_get_##name,				\
 	};								\
-	EXPORT_SYMBOL(param_set_##name);				\
-	EXPORT_SYMBOL(param_get_##name);				\
 	EXPORT_SYMBOL(param_ops_##name)
 
 
@@ -252,7 +250,7 @@ STANDARD_PARAM_DEF(uint, unsigned int, "%u", unsigned long, strict_strtoul);
 STANDARD_PARAM_DEF(long, long, "%li", long, strict_strtol);
 STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", unsigned long, strict_strtoul);
 
-int param_set_charp(const char *val, const struct kernel_param *kp)
+static int _param_set_charp(const char *val, const struct kernel_param *kp)
 {
 	if (!val) {
 		printk(KERN_ERR "%s: string parameter expected\n",
@@ -280,13 +278,11 @@ int param_set_charp(const char *val, const struct kernel_param *kp)
 
 	return 0;
 }
-EXPORT_SYMBOL(param_set_charp);
 
-int param_get_charp(char *buffer, const struct kernel_param *kp)
+static int _param_get_charp(char *buffer, const struct kernel_param *kp)
 {
 	return sprintf(buffer, "%s", *((char **)kp->arg));
 }
-EXPORT_SYMBOL(param_get_charp);
 
 static void param_free_charp(void *arg)
 {
@@ -294,14 +290,14 @@ static void param_free_charp(void *arg)
 }
 
 struct kernel_param_ops param_ops_charp = {
-	.set = param_set_charp,
-	.get = param_get_charp,
+	.set = _param_set_charp,
+	.get = _param_get_charp,
 	.free = param_free_charp,
 };
 EXPORT_SYMBOL(param_ops_charp);
 
 /* Actually could be a bool or an int, for historical reasons. */
-int param_set_bool(const char *val, const struct kernel_param *kp)
+static int _param_set_bool(const char *val, const struct kernel_param *kp)
 {
 	bool v;
 
@@ -326,9 +322,8 @@ int param_set_bool(const char *val, const struct kernel_param *kp)
 		*(int *)kp->arg = v;
 	return 0;
 }
-EXPORT_SYMBOL(param_set_bool);
 
-int param_get_bool(char *buffer, const struct kernel_param *kp)
+static int _param_get_bool(char *buffer, const struct kernel_param *kp)
 {
 	bool val;
 	if (kp->flags & KPARAM_ISBOOL)
@@ -339,16 +334,15 @@ int param_get_bool(char *buffer, const struct kernel_param *kp)
 	/* Y and N chosen as being relatively non-coder friendly */
 	return sprintf(buffer, "%c", val ? 'Y' : 'N');
 }
-EXPORT_SYMBOL(param_get_bool);
 
 struct kernel_param_ops param_ops_bool = {
-	.set = param_set_bool,
-	.get = param_get_bool,
+	.set = _param_set_bool,
+	.get = _param_get_bool,
 };
 EXPORT_SYMBOL(param_ops_bool);
 
 /* This one must be bool. */
-int param_set_invbool(const char *val, const struct kernel_param *kp)
+static int _param_set_invbool(const char *val, const struct kernel_param *kp)
 {
 	int ret;
 	bool boolval;
@@ -356,22 +350,20 @@ int param_set_invbool(const char *val, const struct kernel_param *kp)
 
 	dummy.arg = &boolval;
 	dummy.flags = KPARAM_ISBOOL;
-	ret = param_set_bool(val, &dummy);
+	ret = _param_set_bool(val, &dummy);
 	if (ret == 0)
 		*(bool *)kp->arg = !boolval;
 	return ret;
 }
-EXPORT_SYMBOL(param_set_invbool);
 
-int param_get_invbool(char *buffer, const struct kernel_param *kp)
+static int _param_get_invbool(char *buffer, const struct kernel_param *kp)
 {
 	return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y');
 }
-EXPORT_SYMBOL(param_get_invbool);
 
 struct kernel_param_ops param_ops_invbool = {
-	.set = param_set_invbool,
-	.get = param_get_invbool,
+	.set = _param_set_invbool,
+	.get = _param_get_invbool,
 };
 EXPORT_SYMBOL(param_ops_invbool);
 
@@ -480,7 +472,7 @@ struct kernel_param_ops param_array_ops = {
 };
 EXPORT_SYMBOL(param_array_ops);
 
-int param_set_copystring(const char *val, const struct kernel_param *kp)
+static int _param_set_string(const char *val, const struct kernel_param *kp)
 {
 	const struct kparam_string *kps = kp->str;
 
@@ -496,18 +488,16 @@ int param_set_copystring(const char *val, const struct kernel_param *kp)
 	strcpy(kps->string, val);
 	return 0;
 }
-EXPORT_SYMBOL(param_set_copystring);
 
-int param_get_string(char *buffer, const struct kernel_param *kp)
+static int _param_get_string(char *buffer, const struct kernel_param *kp)
 {
 	const struct kparam_string *kps = kp->str;
 	return strlcpy(buffer, kps->string, kps->maxlen);
 }
-EXPORT_SYMBOL(param_get_string);
 
 struct kernel_param_ops param_ops_string = {
-	.set = param_set_copystring,
-	.get = param_get_string,
+	.set = _param_set_string,
+	.get = _param_get_string,
 };
 EXPORT_SYMBOL(param_ops_string);
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ