[PATCH] sched: mc/smt power savings sched policy
S.Çağlar Onur
caglar at pardus.org.tr
Mon Jun 11 13:01:23 PDT 2007
Hi;
Following patch tries to add GetSchedPowerSavings/SetSchedPowerSavings methods
to cpufreq-addon.
This patch is nothing but a "i want to hear your comments one" :), so if this
is acceptable i want to provide another patch in future to introduce CPU
online/offlining with HAL, so kpowersave/gnome-power-manager can provide
these features to users also.
For reference, "power savings sched policy" introduces following
[@http://kernelnewbies.org/Linux_2_6_18]
Process scheduler
In machines with several multi core/smt "packages" (which will become
increasingly common in the future), the power consumption can be improved by
letting some packages idle while others do all the work, instead of spreading
the tasks over all CPUs, so a optional power saving policy has been developed
to make this possible. When this power savings policy is enabled - set to 1
the sysfs entry 'sched_mc_power_savings' or 'sched_smt_power_savings' placed
under /sys/devices/system/cpu/cpuX/ when enabled CONFIG_SCHED_MC /
CONFIG_SCHED_SMT - and under light load conditions, the scheduler will
minimize the physical packages/cpu cores carrying the load and thus
conserving power, but impacting the performance depending on the workload
characteristics (when there's lot of work to do all CPUs will be used, to
completely disable individual CPUs use the already available CPU hot plugging
feature by writing 0 to the "online" file in that sysfs directory). For more
details on the effect of this policy read the "Chip Multi Processing (CMP)
aware Linux Kernel Scheduler" talk from the OLS 2005 (page 201 and onwards)
(commit)
And here it is;
diff --git a/hald/linux/addons/addon-cpufreq.c
b/hald/linux/addons/addon-cpufreq.c
index b10edf9..c7e7c74 100644
--- a/hald/linux/addons/addon-cpufreq.c
+++ b/hald/linux/addons/addon-cpufreq.c
@@ -67,6 +67,12 @@ const char SYSFS_CPU_ONLINE_FILE[] =
const char ONDEMAND_IGNORE_NICE_LOAD_FILE[] =
"/sys/devices/system/cpu/cpu%u/cpufreq/ondemand/ignore_nice_load";
+const char SYSFS_SCHED_MC_POWER_SAVINGS_FILE[] =
+ "/sys/devices/system/cpu/sched_mc_power_savings";
+
+const char SYSFS_SCHED_SMT_POWER_SAVINGS_FILE[] =
+ "/sys/devices/system/cpu/sched_smt_power_savings";
+
static gboolean dbus_raise_error(DBusConnection *connection, DBusMessage
*message,
const char *error_name, char *format, ...);
@@ -816,6 +822,80 @@ static gboolean get_governors(DBusConnection *connection,
DBusMessage *message,
return TRUE;
}
+
+/**
+ * set_sched_power_savings:
+ * @connection: connection to D-Bus
+ * @message: Message
+ * @sched_power_savings: pointer to return the current power savings value
+ * Returns: TRUE/FALSE
+ *
+ * @raises GeneralError
+ *
+ * sets the MC/SMT power savings policy for the scheduler.
+ */
+ static gboolean set_sched_power_savings(DBusConnection *connection,
DBusMessage *message,
+ int *sched_power_savings)
+{
+ int status;
+ int num_cpus;
+
+ num_cpus = sysconf(_SC_NPROCESSORS_CONF);
+ if (num_cpus < 2) {
+ dbus_raise_error(connection, message, CPUFREQ_ERROR_GENERAL,
+ "No MC/SMT capable CPUs found in system");
+ HAL_WARNING(("No MC/SMT CPUs found in system"));
+ return FALSE;
+ }
+ /* FIXME: Detect the topology properly instead of trying */
+ if (!write_line(SYSFS_SCHED_MC_POWER_SAVINGS_FILE, "%u",
sched_power_savings)) {
+ if (!write_line(SYSFS_SCHED_SMT_POWER_SAVINGS_FILE, "%u",
sched_power_savings)) {
+ dbus_raise_error(connection, message, CPUFREQ_ERROR_GENERAL,
+ "Could not set current power savings policy for the scheduler");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ * get_sched_power_savings:
+ * @connection: connection to D-Bus
+ * @message: Message
+ * @sched_power_savings: pointer to return the current power savings value
+ * Returns: TRUE/FALSE
+ *
+ * @raises GeneralError
+ *
+ * gets the MC/SMT power savings policy for the scheduler.
+ */
+ static gboolean get_sched_power_savings(DBusConnection *connection,
DBusMessage *message,
+ int *sched_power_savings)
+{
+ int status;
+ int num_cpus;
+
+ num_cpus = sysconf(_SC_NPROCESSORS_CONF);
+ if (num_cpus < 2) {
+ dbus_raise_error(connection, message, CPUFREQ_ERROR_GENERAL,
+ "No MC/SMT capable CPUs found in system");
+ HAL_WARNING(("No MC/SMT CPUs found in system"));
+ return FALSE;
+ }
+
+ /* FIXME: Detect the topology properly instead of trying */
+ if (!read_line_int(SYSFS_SCHED_MC_POWER_SAVINGS_FILE, &status)) {
+ if (!read_line_int(SYSFS_SCHED_SMT_POWER_SAVINGS_FILE, &status)) {
+ dbus_raise_error(connection, message, CPUFREQ_ERROR_GENERAL,
+ "Could not read current power savings policy for the scheduler");
+ return FALSE;
+ }
+ }
+ *sched_power_savings = (int)status;
+
+ return TRUE;
+}
/********************* main interface end *********************/
/********************* DBus stuff *********************/
@@ -1146,6 +1226,19 @@ static DBusHandlerResult
dbus_filter_function(DBusConnection *connection,
dbus_send_reply(connection, message, DBUS_TYPE_INVALID, NULL);
} else if (dbus_message_is_method_call(message, DBUS_INTERFACE,
+ "SetSchedPowerSavings")) {
+ int arg;
+
+ if (!dbus_get_argument(connection, message, &dbus_error,
+ DBUS_TYPE_INT32, &arg)) {
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ HAL_DEBUG(("Received argument: %d", arg));
+
+ if (set_sched_power_savings(connection, message, arg))
+ dbus_send_reply(connection, message, DBUS_TYPE_INVALID, NULL);
+
+ } else if (dbus_message_is_method_call(message, DBUS_INTERFACE,
"GetCPUFreqGovernor")) {
char governor[MAX_LINE_SIZE + 1];
char *gov = governor;
@@ -1174,7 +1267,14 @@ static DBusHandlerResult
dbus_filter_function(DBusConnection *connection,
if (get_available_governors(connection, message, &governors))
dbus_send_reply_strlist(connection, message, governors);
g_strfreev(governors);
-
+
+ } else if (dbus_message_is_method_call(message, DBUS_INTERFACE,
+ "GetSchedPowerSavings")) {
+ int sched_power_savings = -1;
+
+ if (get_sched_power_savings(connection, message, &sched_power_savings))
+ dbus_send_reply(connection, message, DBUS_TYPE_INT32,
&sched_power_savings);
+
} else {
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
@@ -1250,6 +1350,9 @@ gboolean dbus_init(void)
" <method name=\"SetCPUFreqConsiderNice\">\n"
" <arg name=\"value\" direction=\"in\" type=\"b\"/>\n"
" </method>\n"
+ " <method name=\"SetSchedPowerSavings\">\n"
+ " <arg name=\"value\" direction=\"in\" type=\"i\"/>\n"
+ " </method>\n"
" <method name=\"GetCPUFreqGovernor\">\n"
" <arg name=\"return_code\" direction=\"out\" type=\"s\"/>\n"
" </method>\n"
@@ -1261,6 +1364,9 @@ gboolean dbus_init(void)
" </method>\n"
" <method name=\"GetCPUFreqAvailableGovernors\">\n"
" <arg name=\"return_code\" direction=\"out\" type=\"as\"/>\n"
+ " </method>\n"
+ " <method name=\"GetSchedPowerSavings\">\n"
+ " <arg name=\"return_code\" direction=\"out\" type=\"i\"/>\n"
" </method>\n",
&dbus_error)) {
Cheers
--
S.Çağlar Onur <caglar at pardus.org.tr>
http://cekirdek.pardus.org.tr/~caglar/
Linux is like living in a teepee. No Windows, no Gates and an Apache in house!
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part.
Url : http://lists.freedesktop.org/archives/hal/attachments/20070611/90094da1/attachment.pgp
More information about the hal
mailing list