All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nadia.Derbey@bull.net
To: linux-kernel@vger.kernel.org
Cc: Nadia Derbey <Nadia.Derbey@bull.net>
Subject: [RFC][PATCH 4/6] min and max kobjects
Date: Tue, 16 Jan 2007 07:15:20 +0100	[thread overview]
Message-ID: <20070116063029.862885000@bull.net> (raw)
In-Reply-To: 20070116061516.899460000@bull.net

[-- Attachment #1: tunable_min_max_kobjects.patch --]
[-- Type: text/plain, Size: 15777 bytes --]

[PATCH 04/06]


Introduces the kobjects associated to each tunable min and max value


Signed-off-by: Nadia Derbey <Nadia.Derbey@bull.net>


---
 include/linux/akt.h         |   30 ++++
 include/linux/akt_ops.h     |  311 ++++++++++++++++++++++++++++++++++++++++++++
 kernel/autotune/akt.c       |  120 ++++++++++++++++
 kernel/autotune/akt_sysfs.c |    8 +
 4 files changed, 469 insertions(+)

Index: linux-2.6.20-rc4/include/linux/akt.h
===================================================================
--- linux-2.6.20-rc4.orig/include/linux/akt.h	2007-01-15 15:08:41.000000000 +0100
+++ linux-2.6.20-rc4/include/linux/akt.h	2007-01-15 15:21:47.000000000 +0100
@@ -62,6 +62,13 @@ struct tunable_kobject {
  * auto_tune structure.
  * These values are type dependent and are used as high / low boundaries when
  * tuning up or down.
+ * The show and store routines (thare are type dependent too) are here for
+ * sysfs support (since the min and max can be updated through sysfs).
+ * The abs_value field is used to check that we are not:
+ *   . falling under the very 1st min value when updating the min value
+ *     through sysfs
+ *   . going over the very 1st max value when updating the max value
+ *     through sysfs
  * The type is known when the tunable is defined (see DEFINE_TUNABLE macro).
  */
 struct typed_value {
@@ -74,6 +81,17 @@ struct typed_value {
 		long   val_long;
 		ulong  val_ulong;
 	} value;
+	union {
+		short  val_short;
+		ushort val_ushort;
+		int    val_int;
+		uint   val_uint;
+		size_t val_size_t;
+		long   val_long;
+		ulong  val_ulong;
+	} abs_value;
+	ssize_t (*show)(struct auto_tune *, char *);
+	ssize_t (*store)(struct auto_tune *, const char *, size_t);
 };
 
 
@@ -170,9 +188,15 @@ static inline int is_tunable_registered(
 		.threshold	= (_thresh),				\
 		.min	= {						\
 			.value		= { .val_##type = (_min), },	\
+			.abs_value	= { .val_##type = (_min), },	\
+			.show		= show_tunable_min_##type,	\
+			.store		= store_tunable_min_##type,	\
 		},							\
 		.max	= {						\
 			.value		= { .val_##type = (_max), },	\
+			.abs_value	= { .val_##type = (_max), },	\
+			.show		= show_tunable_max_##type,	\
+			.store		= store_tunable_max_##type,	\
 		},							\
 		.tun_kobj	= { .tun = NULL, },			\
 		.tunable	= (_tun),				\
@@ -186,7 +210,9 @@ static inline int is_tunable_registered(
 #define set_tunable_min_max(s, _min, _max, type)	\
 	do {						\
 		(s).min.value.val_##type = _min;	\
+		(s).min.abs_value.val_##type = _min;	\
 		(s).max.value.val_##type = _max;	\
+		(s).max.abs_value.val_##type = _max;	\
 	} while (0)
 
 
@@ -234,6 +260,10 @@ extern int unregister_tunable(struct aut
 extern int tunable_sysfs_setup(struct auto_tune *);
 extern ssize_t show_tuning_mode(struct auto_tune *, char *);
 extern ssize_t store_tuning_mode(struct auto_tune *, const char *, size_t);
+extern ssize_t show_tunable_min(struct auto_tune *, char *);
+extern ssize_t store_tunable_min(struct auto_tune *, const char *, size_t);
+extern ssize_t show_tunable_max(struct auto_tune *, char *);
+extern ssize_t store_tunable_max(struct auto_tune *, const char *, size_t);
 
 
 #else	/* CONFIG_AKT */
Index: linux-2.6.20-rc4/include/linux/akt_ops.h
===================================================================
--- linux-2.6.20-rc4.orig/include/linux/akt_ops.h	2007-01-15 14:28:16.000000000 +0100
+++ linux-2.6.20-rc4/include/linux/akt_ops.h	2007-01-15 15:22:53.000000000 +0100
@@ -182,5 +182,316 @@ static inline int default_auto_tuning_ul
 }
 
 
+/*
+ * member can be one of min / max
+ */
+#define __show_tunable_member(member, p, type, buf, format, y)	\
+do {								\
+	type _xx = (type) p->member.value.val_##type;		\
+								\
+	y = snprintf(buf, PAGE_SIZE, format "\n", _xx);		\
+} while (0)
+
+/*
+ * Show routines for the min and max tunables values
+ */
+static inline ssize_t show_tunable_min_short(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(min, p, short, buf, "%d", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_min_ushort(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(min, p, ushort, buf, "%u", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_min_int(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(min, p, int, buf, "%d", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_min_uint(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(min, p, uint, buf, "%u", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_min_size_t(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(min, p, ulong, buf, "%lu", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_min_long(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(min, p, long, buf, "%ld", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_min_ulong(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(min, p, ulong, buf, "%lu", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_max_short(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(max, p, short, buf, "%d", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_max_ushort(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(max, p, ushort, buf, "%u", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_max_int(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(max, p, int, buf, "%d", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_max_uint(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(max, p, uint, buf, "%u", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_max_size_t(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(max, p, ulong, buf, "%lu", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_max_long(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(max, p, long, buf, "%ld", _count);
+	return _count;
+}
+
+static inline ssize_t show_tunable_max_ulong(struct auto_tune *p, char *buf)
+{
+	ssize_t _count;
+	__show_tunable_member(max, p, ulong, buf, "%lu", _count);
+	return _count;
+}
+
+
+/*
+ * when setting the min: we don't accept to fall under the absolute min
+ *                       (the very 1st one that has been set)
+ */
+#define __store_tunable_min(p, type, buf, y)				\
+do {									\
+	long _vv;							\
+	char *_rr;							\
+									\
+	_vv = simple_strtol(buf, &_rr, 0);				\
+	if (_rr == buf)							\
+		y = -EINVAL;						\
+	else {								\
+		if (_vv >= p->min.abs_value.val_##type &&		\
+				_vv < p->max.value.val_##type) {	\
+			p->min.value.val_##type = _vv;			\
+			y = _rr - buf;					\
+		} else							\
+			y = -EINVAL;					\
+	}								\
+} while (0)
+
+#define __store_tunable_umin(p, type, buf, y)				\
+do {									\
+	ulong _vv;							\
+	char *_rr;							\
+									\
+	_vv = simple_strtoul(buf, &_rr, 0);				\
+	if (_rr == buf)							\
+		y = -EINVAL;						\
+	else {								\
+		if (_vv >= p->min.abs_value.val_##type &&		\
+				_vv < p->max.value.val_##type) {	\
+			p->min.value.val_##type = _vv;			\
+			y = _rr - buf;					\
+		} else							\
+			y = -EINVAL;					\
+	}								\
+} while (0)
+
+/*
+ * Store routines for the min tunables values
+ */
+static inline ssize_t store_tunable_min_short(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_min(p, short, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_min_ushort(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_umin(p, ushort, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_min_int(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_min(p, int, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_min_uint(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_umin(p, uint, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_min_size_t(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_umin(p, size_t, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_min_long(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_min(p, long, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_min_ulong(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_umin(p, ulong, buf, _count);
+	return _count;
+}
+
+
+/*
+ * when setting the max: we don't accept to go over the absolute max
+ *                       (the very 1st one that has been set)
+ *
+ */
+#define __store_tunable_max(p, type, buf, y)				\
+do {									\
+	long _vv;							\
+	char *_rr;							\
+									\
+	_vv = simple_strtol(buf, &_rr, 0);				\
+	if (_rr == buf)							\
+		y = -EINVAL;						\
+	else {								\
+		if (_vv <= p->max.abs_value.val_##type &&		\
+				_vv > p->min.value.val_##type) {	\
+			p->max.value.val_##type = _vv;			\
+			y = _rr - buf;					\
+		} else							\
+			y = -EINVAL;					\
+	}								\
+} while (0)
+
+#define __store_tunable_umax(p, type, buf, y)				\
+do {									\
+	ulong _vv;							\
+	char *_rr;							\
+									\
+	_vv = simple_strtoul(buf, &_rr, 0);				\
+	if (_rr == buf)							\
+		y = -EINVAL;						\
+	else {								\
+		if (_vv <= p->max.abs_value.val_##type &&		\
+				_vv > p->min.value.val_##type) {	\
+			p->max.value.val_##type = _vv;			\
+			y = _rr - buf;					\
+		} else							\
+			y = -EINVAL;					\
+	}								\
+} while (0)
+
+/*
+ * Store routines for the max tunables values
+ */
+static inline ssize_t store_tunable_max_short(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_umax(p, short, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_max_ushort(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_umax(p, ushort, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_max_int(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_max(p, int, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_max_uint(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_umax(p, uint, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_max_size_t(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_umax(p, size_t, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_max_long(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_max(p, long, buf, _count);
+	return _count;
+}
+
+static inline ssize_t store_tunable_max_ulong(struct auto_tune *p,
+					const char *buf, size_t count)
+{
+	ssize_t _count;
+	__store_tunable_umax(p, ulong, buf, _count);
+	return _count;
+}
 
 #endif /* AKT_OPS_H */
Index: linux-2.6.20-rc4/kernel/autotune/akt.c
===================================================================
--- linux-2.6.20-rc4.orig/kernel/autotune/akt.c	2007-01-15 15:13:31.000000000 +0100
+++ linux-2.6.20-rc4/kernel/autotune/akt.c	2007-01-15 15:25:35.000000000 +0100
@@ -28,6 +28,10 @@
  *              unregister_tunable         (exported)
  *              show_tuning_mode           (exported)
  *              store_tuning_mode          (exported)
+ *              show_tunable_min           (exported)
+ *              store_tunable_min          (exported)
+ *              show_tunable_max           (exported)
+ *              store_tunable_max          (exported)
  */
 
 #include <linux/init.h>
@@ -203,5 +207,121 @@ ssize_t store_tuning_mode(struct auto_tu
 }
 
 
+/*
+ * FUNCTION:    Get operation called by tunable_attr_show (i.e. when the file
+ *              /sys/tunables/<tunable>/min is displayed).
+ *              Outputs the current tunable minimum value
+ *
+ * RETURN VALUE: >0 : output string length (including the '\0')
+ *               <0 : failure
+ */
+ssize_t show_tunable_min(struct auto_tune *tun_addr, char *buf)
+{
+	ssize_t rc;
+
+	if (tun_addr == NULL) {
+		printk(KERN_ERR
+			" show_tunable_min(): tunable address is invalid\n");
+		return -EINVAL;
+	}
+
+	spin_lock(&tun_addr->tunable_lck);
+
+	rc = tun_addr->min.show(tun_addr, buf);
+
+	spin_unlock(&tun_addr->tunable_lck);
+
+	return rc;
+}
+
+
+/*
+ * FUNCTION:    Set operation called by tunable_attr_store (i.e. when a
+ *              string is stored into /sys/tunables/<tunable>/min).
+ *
+ * PARAMETERS:  count: input buffer size (including the '\0')
+ *
+ * RETURN VALUE: >0: number of characters used from the input buffer
+ *               <= 0: failure
+ */
+ssize_t store_tunable_min(struct auto_tune *tun_addr, const char *buf,
+			size_t count)
+{
+	ssize_t rc;
+
+	if (tun_addr == NULL) {
+		printk(KERN_ERR
+			" store_tunable_min(): tunable address is invalid\n");
+		return -EINVAL;
+	}
+
+	spin_lock(&tun_addr->tunable_lck);
+
+	rc = tun_addr->min.store(tun_addr, buf, count);
+
+	spin_unlock(&tun_addr->tunable_lck);
+
+	return rc;
+}
+
+
+/*
+ * FUNCTION:    Get operation called by tunable_attr_show (i.e. when the file
+ *              /sys/tunables/<tunable>/max is displayed).
+ *              Outputs the current tunable maximum value
+ *
+ * RETURN VALUE: >0 : output string length (including the '\0')
+ *               <0 : failure
+ */
+ssize_t show_tunable_max(struct auto_tune *tun_addr, char *buf)
+{
+	ssize_t rc;
+
+	if (tun_addr == NULL) {
+		printk(KERN_ERR
+			" show_tunable_max(): tunable address is invalid\n");
+		return -EINVAL;
+	}
+
+	spin_lock(&tun_addr->tunable_lck);
+
+	rc = tun_addr->max.show(tun_addr, buf);
+
+	spin_unlock(&tun_addr->tunable_lck);
+
+	return rc;
+}
+
+
+/*
+ * FUNCTION:    Set operation called by tunable_attr_store (i.e. when a
+ *              string is stored into /sys/tunables/<tunable>/max).
+ *
+ * PARAMETERS:  count: input buffer size (including the '\0')
+ *
+ * RETURN VALUE: >0: number of characters used from the input buffer
+ *               <= 0: failure
+ */
+ssize_t store_tunable_max(struct auto_tune *tun_addr, const char *buf,
+			size_t count)
+{
+	ssize_t rc;
+
+	if (tun_addr == NULL) {
+		printk(KERN_ERR
+			" store_tunable_max(): tunable address is invalid\n");
+		return -EINVAL;
+	}
+
+	spin_lock(&tun_addr->tunable_lck);
+
+	rc = tun_addr->max.store(tun_addr, buf, count);
+
+	spin_unlock(&tun_addr->tunable_lck);
+
+	return rc;
+}
+
+
 EXPORT_SYMBOL_GPL(register_tunable);
 EXPORT_SYMBOL_GPL(unregister_tunable);
Index: linux-2.6.20-rc4/kernel/autotune/akt_sysfs.c
===================================================================
--- linux-2.6.20-rc4.orig/kernel/autotune/akt_sysfs.c	2007-01-15 15:14:55.000000000 +0100
+++ linux-2.6.20-rc4/kernel/autotune/akt_sysfs.c	2007-01-15 15:26:31.000000000 +0100
@@ -54,8 +54,16 @@ struct tunable_attribute tun_attr_##_nam
 static TUNABLE_ATTR(autotune, S_IWUSR | S_IRUGO, show_tuning_mode,
 		store_tuning_mode);
 
+static TUNABLE_ATTR(min, S_IWUSR | S_IRUGO, show_tunable_min,
+		store_tunable_min);
+
+static TUNABLE_ATTR(max, S_IWUSR | S_IRUGO, show_tunable_max,
+		store_tunable_max);
+
 static struct tunable_attribute *tunable_sysfs_attrs[] = {
 	&tun_attr_autotune,	/* to (de)activate auto tuning */
+	&tun_attr_min,		/* to play with the tunable min value */
+	&tun_attr_max,		/* to play with the tunable max value */
 	NULL,
 };
 

--

  parent reply	other threads:[~2007-01-16  6:28 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-16  6:15 [RFC][PATCH 0/6] Automatice kernel tunables (AKT) Nadia.Derbey
2007-01-16  6:15 ` [RFC][PATCH 1/6] Tunable structure and registration routines Nadia.Derbey
2007-01-25  0:32   ` Randy Dunlap
2007-01-25 16:26     ` Nadia Derbey
2007-01-25 16:34       ` Randy Dunlap
2007-01-25 17:01         ` Nadia Derbey
2007-01-16  6:15 ` [RFC][PATCH 2/6] auto_tuning activation Nadia.Derbey
2007-01-16  6:15 ` [RFC][PATCH 3/6] tunables associated kobjects Nadia.Derbey
2007-01-16  6:15 ` Nadia.Derbey [this message]
2007-01-24 22:41   ` [RFC][PATCH 4/6] min and max kobjects Randy Dunlap
2007-01-25 16:34     ` Nadia Derbey
2007-01-16  6:15 ` [RFC][PATCH 5/6] per namespace tunables Nadia.Derbey
2007-01-24 22:41   ` Randy Dunlap
2007-01-16  6:15 ` [RFC][PATCH 6/6] automatic tuning applied to some kernel components Nadia.Derbey
2007-01-22 19:56   ` Andrew Morton
2007-01-23 14:40     ` Nadia Derbey
2007-02-07 21:18       ` Eric W. Biederman
2007-02-09 12:27         ` Nadia Derbey
2007-02-09 18:35           ` Eric W. Biederman
2007-02-13  9:06             ` Nadia Derbey
2007-02-13 10:10               ` Eric W. Biederman
2007-02-15  7:07                 ` Nadia Derbey
2007-02-15  7:49                   ` Eric W. Biederman
2007-02-15  8:25                     ` Nadia Derbey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070116063029.862885000@bull.net \
    --to=nadia.derbey@bull.net \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.