CPUClock: Allow setting of governors.

This commit is contained in:
Stephen 'Okra' Houston 2017-07-12 15:42:56 -05:00
parent d4bc101866
commit ada1fdb71a
7 changed files with 160 additions and 79 deletions

View File

@ -24,7 +24,6 @@ src_modules_sysinfo_module_la_SOURCES = src/modules/sysinfo/mod.c \
src/modules/sysinfo/thermal/thermal_fallback.c \
src/modules/sysinfo/cpuclock/cpuclock.h \
src/modules/sysinfo/cpuclock/cpuclock.c \
src/modules/sysinfo/cpuclock/cpuclock_sysfs.c \
src/modules/sysinfo/cpuclock/cpuclock_config.c \
src/modules/sysinfo/cpumonitor/cpumonitor.h \
src/modules/sysinfo/cpumonitor/cpumonitor.c \
@ -84,7 +83,23 @@ endif
endif
endif
src_modules_sysinfo_sysfsfreqdir = $(sysinfopkgdir)
src_modules_sysinfo_sysfsfreq_PROGRAMS = src/modules/sysinfo/cpuclock/cpuclock_sysfs
src_modules_sysinfo_sysfsfreq_SOURCES = src/modules/sysinfo/cpuclock/cpuclock_sysfs.c
src_modules_sysinfo_sysfsfreq_CPPFLAGS = $(MOD_CPPFLAGS) @e_cflags@ @SUID_CFLAGS@
src_modules_sysinfo_sysfsfreq_LDFLAGS = @SUID_LDFLAGS@
sysfsfreq_setuid_root_mode = a=rx,u+xs
sysfsfreq_setuid_root_user = root
sysfsfreq-install-data-hook:
@chown $(sysfsfreq_setuid_root_user) $(DESTDIR)$(src_modules_sysinfo_sysfsfreqdir)/cpuclock_sysfs$(EXEEXT) || true
@chmod $(sysfsfreq_setuid_root_mode) $(DESTDIR)$(src_modules_sysinfo_sysfsfreqdir)/cpuclock_sysfs$(EXEEXT) || true
INSTALL_DATA_HOOKS += sysfsfreq-install-data-hook
PHONIES += sysinfo install-sysinfo
sysinfo: $(sysinfopkg_LTLIBRARIES) $(sysinfo_DATA)
install-sysinfo: install-sysinfoDATA install-sysinfopkgLTLIBRARIES
sysinfo: $(sysinfopkg_LTLIBRARIES) $(sysinfo_DATA) $(src_modules_sysinfo_sysfsfreq_PROGRAMS)
install-sysinfo: install-sysinfoDATA install-sysinfopkgLTLIBRARIES install-src_modules_sysinfo_sysfsfreqPROGRAMS
endif

View File

@ -62,38 +62,13 @@ _cpuclock_cb_sort(const void *item1, const void *item2)
return 0;
}
static void
_cpuclock_set_thread_governor(void *data, Ecore_Thread *th EINA_UNUSED)
{
const char *governor = data;
if (_cpuclock_sysfs_setall("scaling_governor", governor) == 0)
return;
if (!strcmp(governor, "ondemand"))
_cpuclock_sysfs_set("ondemand/ignore_nice_load", "0");
else if (!strcmp(governor, "conservative"))
_cpuclock_sysfs_set("conservative/ignore_nice_load", "0");
}
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined (__OpenBSD__)
static void
_cpuclock_set_thread_frequency(void *data, Ecore_Thread *th EINA_UNUSED)
{
const char *freq = data;
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined (__OpenBSD__)
int frequency = atoi(freq);
_cpuclock_sysctl_frequency(frequency);
#else
_cpuclock_sysfs_setall("scaling_setspeed", freq);
#endif
}
static void
_cpuclock_set_thread_pstate(void *data, Ecore_Thread *th EINA_UNUSED)
{
Pstate_Config *pc = data;
_cpuclock_sysfs_pstate(pc->min, pc->max, pc->turbo);
}
static void
@ -101,16 +76,7 @@ _cpuclock_set_thread_done(void *data EINA_UNUSED, Ecore_Thread *th EINA_UNUSED)
{
return;
}
static void
_cpuclock_set_thread_pstate_done(void *data, Ecore_Thread *th EINA_UNUSED)
{
Pstate_Config *pc = data;
E_FREE_FUNC(pc, free);
return;
}
#endif
void
_cpuclock_set_governor(const char *governor)
@ -118,24 +84,44 @@ _cpuclock_set_governor(const char *governor)
#if defined __FreeBSD__ || defined __OpenBSD__
return;
#endif
char buf[4096], exe[4096];
struct stat st;
ecore_thread_run(_cpuclock_set_thread_governor, _cpuclock_set_thread_done, NULL, governor);
snprintf(exe, 4096, "%s/%s/cpuclock_sysfs",
e_module_dir_get(sysinfo_config->module), MODULE_ARCH);
printf("%s\n", exe);
if (stat(exe, &st) < 0) return;
snprintf(buf, sizeof(buf),
"%s %s %s", exe, "governor", governor);
printf("%s\n", buf);
system(buf);
}
void
_cpuclock_set_frequency(int frequency)
{
char buf[4096];
const char *freq;
struct stat st;
#ifdef __FreeBSD__
frequency /= 1000;
#endif
snprintf(buf, sizeof(buf), "%i", frequency);
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined (__OpenBSD__)
const char *freq;
freq = eina_stringshare_add(buf);
ecore_thread_run(_cpuclock_set_thread_frequency, _cpuclock_set_thread_done, NULL, freq);
#else
char exe[4096];
snprintf(exe, 4096, "%s/%s/cpuclock_sysfs",
e_module_dir_get(sysinfo_config->module), MODULE_ARCH);
if (stat(exe, &st) < 0) return;
snprintf(buf, sizeof(buf),
"%s %s %i", exe, "frequency", frequency);
system(buf);
#endif
}
void
@ -144,16 +130,15 @@ _cpuclock_set_pstate(int min, int max, int turbo)
#if defined __FreeBSD__ || defined __OpenBSD__
return;
#endif
Pstate_Config *pc;
char buf[4096], exe[4096];
struct stat st;
pc = E_NEW(Pstate_Config, 1);
if (!pc) return;
pc->turbo = turbo;
pc->min = min;
pc->max = max;
ecore_thread_run(_cpuclock_set_thread_pstate, _cpuclock_set_thread_pstate_done, NULL, pc);
snprintf(exe, 4096, "%s/%s/cpuclock_sysfs",
e_module_dir_get(sysinfo_config->module), MODULE_ARCH);
if (stat(exe, &st) < 0) return;
snprintf(buf, sizeof(buf),
"%s %s %i %i %i", exe, "pstate", min, max, turbo);
system(buf);
}
static void
@ -292,17 +277,19 @@ _cpuclock_popup_create(Instance *inst)
{
Evas_Object *popup, *box, *label;
double f = inst->cfg->cpuclock.status->cur_frequency;
char buf[100];
char buf[100], *u;
if (f < 1000000)
{
f += 500;
f /= 1000;
u = _("MHz");
}
else
{
f += 50000;
f /= 1000000;
u = _("GHz");
}
popup = elm_ctxpopup_add(e_comp->elm);
@ -320,7 +307,7 @@ _cpuclock_popup_create(Instance *inst)
label = elm_label_add(box);
elm_object_style_set(label, "marker");
snprintf(buf, 100, "%s: %1.1f", _("Frequency"), f);
snprintf(buf, 100, "%s: %1.1f %s", _("Frequency"), f, u);
elm_object_text_set(label, buf);
elm_box_pack_end(box, label);
evas_object_show(label);
@ -423,19 +410,21 @@ _cpuclock_face_update_current(Instance *inst)
if (inst->cfg->cpuclock.popup)
{
double f = inst->cfg->cpuclock.status->cur_frequency;
char buf[100];
char buf[100], *u;
if (f < 1000000)
{
f += 500;
f /= 1000;
u = _("MHz");
}
else
{
f += 50000;
f /= 1000000;
u = _("GHz");
}
snprintf(buf, 100, "%s: %1.1f", _("Frequency"), f);
snprintf(buf, 100, "%s: %1.1f %s", _("Frequency"), f, u);
elm_object_text_set(inst->cfg->cpuclock.popup_label, buf);
}
}
@ -843,6 +832,7 @@ _cpuclock_cb_frequency_check_notify(void *data,
{
Cpu_Status *status = msg;
Eina_Bool freq_changed = EINA_FALSE;
Eina_Bool init_set = EINA_FALSE;
Thread_Config *thc = data;
Instance *inst = thc->inst;
@ -870,8 +860,13 @@ _cpuclock_cb_frequency_check_notify(void *data,
else if (inst->cfg->cpuclock.status->active == 1)
elm_layout_signal_emit(inst->cfg->cpuclock.o_gadget, "e,state,enabled", "e");
_cpuclock_set_pstate(inst->cfg->cpuclock.pstate_min - 1,
inst->cfg->cpuclock.pstate_max - 1, inst->cfg->cpuclock.status->pstate_turbo);
if (!init_set)
{
_cpuclock_set_pstate(inst->cfg->cpuclock.pstate_min - 1,
inst->cfg->cpuclock.pstate_max - 1,
inst->cfg->cpuclock.status->pstate_turbo);
init_set = EINA_TRUE;
}
}
static void

View File

@ -26,9 +26,6 @@ void _cpuclock_config_updated(Instance *inst);
void _cpuclock_set_governor(const char *governor);
void _cpuclock_set_frequency(int frequency);
void _cpuclock_set_pstate(int min, int max, int turbo);
int _cpuclock_sysfs_setall(const char *control, const char *value);
int _cpuclock_sysfs_set(const char *control, const char *value);
int _cpuclock_sysfs_pstate(int min, int max, int turbo);
#if defined __OpenBSD__ || defined __FreeBSD__
int _cpuclock_sysctl_frequency(int new_perf);
#endif

View File

@ -403,7 +403,7 @@ cpuclock_configure(Instance *inst)
elm_object_text_set(o, _("Maximum Speed"));
else
elm_object_text_set(o, l->data);
evas_object_data_set(o, "governor", (const char *)l->data);
evas_object_data_set(o, "governor", strdup(l->data));
elm_box_pack_end(box, o);
evas_object_smart_callback_add(o, "changed", _governor_changed, cc);
evas_object_show(o);
@ -473,7 +473,7 @@ cpuclock_configure(Instance *inst)
else
elm_object_text_set(o, l->data);
elm_object_disabled_set(o, inst->cfg->cpuclock.auto_powersave);
evas_object_data_set(o, "governor", l->data);
evas_object_data_set(o, "governor", strdup(l->data));
elm_box_pack_end(box, o);
evas_object_smart_callback_add(o, "changed", _powersave_changed, cc);
evas_object_show(o);

View File

@ -1,7 +1,86 @@
#include "cpuclock.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
static int sys_cpu_setall(const char *control, const char *value);
static int sys_cpufreq_set(const char *control, const char *value);
static int sys_cpu_pstate(int min, int max, int turbo);
int
_cpuclock_sysfs_setall(const char *control, const char *value)
main(int argc, char *argv[])
{
if (argc < 3)
{
fprintf(stderr, "Invalid command. Syntax:\n");
fprintf(stderr, "\tcpuclock_sysfs <frequency|governor> <freq-level|governor-name>\n");
fprintf(stderr, "\tcpuclock_sysfs <pstate> <min> <max> <turbo>\n");
return 1;
}
if (seteuid(0))
{
fprintf(stderr, "%s %s\n", argv[0], argv[1]);
fprintf(stderr, "Unable to assume root privileges\n");
return 1;
}
if (!strcmp(argv[1], "frequency"))
{
if (sys_cpu_setall("scaling_setspeed", argv[2]) == 0)
{
fprintf(stderr, "Unable to open frequency interface for writing.\n");
return 1;
}
return 0;
}
else if (!strcmp(argv[1], "governor"))
{
if (sys_cpu_setall("scaling_governor", argv[2]) == 0)
{
fprintf(stderr, "Unable to open governor interface for writing.\n");
return 1;
}
if (!strcmp(argv[2], "ondemand"))
sys_cpufreq_set("ondemand/ignore_nice_load", "0");
else if (!strcmp(argv[2], "conservative"))
sys_cpufreq_set("conservative/ignore_nice_load", "0");
return 0;
}
else if (!strcmp(argv[1], "pstate"))
{
int min, max, turbo;
if (argc < 5)
{
fprintf(stderr, "Invalid number of arguments.\n");
return 1;
}
min = atoi(argv[2]);
max = atoi(argv[3]);
turbo = atoi(argv[4]);
if ((min < 0) || (min > 100) ||
(max < 0) || (max > 100) ||
(turbo < 0) || (turbo > 1))
{
fprintf(stderr, "Invalid pstate values.\n");
return 1;
}
sys_cpu_pstate(min, max, turbo);
return 0;
}
else
{
fprintf(stderr, "Unknown command.\n");
return 1;
}
return -1;
}
static int
sys_cpu_setall(const char *control, const char *value)
{
int num = 0;
char filename[4096];
@ -20,11 +99,11 @@ _cpuclock_sysfs_setall(const char *control, const char *value)
fclose(f);
num++;
}
return 1;
return -1;
}
int
_cpuclock_sysfs_set(const char *control, const char *value)
static int
sys_cpufreq_set(const char *control, const char *value)
{
char filename[4096];
FILE *f;
@ -34,10 +113,10 @@ _cpuclock_sysfs_set(const char *control, const char *value)
if (!f)
{
if (_cpuclock_sysfs_setall(control, value) > 0)
if (sys_cpu_setall(control, value) > 0)
return 1;
else
return 0;
return -1;
}
fprintf(f, "%s\n", value);
@ -46,8 +125,8 @@ _cpuclock_sysfs_set(const char *control, const char *value)
return 1;
}
int
_cpuclock_sysfs_pstate(int min, int max, int turbo)
static int
sys_cpu_pstate(int min, int max, int turbo)
{
FILE *f;
@ -55,18 +134,16 @@ _cpuclock_sysfs_pstate(int min, int max, int turbo)
if (!f) return 0;
fprintf(f, "%i\n", min);
fclose(f);
f = fopen("/sys/devices/system/cpu/intel_pstate/max_perf_pct", "w");
if (!f) return 0;
fprintf(f, "%i\n", max);
fclose(f);
f = fopen("/sys/devices/system/cpu/intel_pstate/no_turbo", "w");
if (!f) return 0;
fprintf(f, "%i\n", turbo ? 0 : 1);
fclose(f);
return 1;
}

View File

@ -5,7 +5,6 @@
static E_Config_DD *conf_edd = NULL;
static E_Config_DD *conf_item_edd = NULL;
Eina_List *sysinfo_instances = NULL;
E_Module *module = NULL;
Config *sysinfo_config = NULL;
EINTERN void
@ -210,7 +209,6 @@ e_modapi_init(E_Module *m)
{
sysinfo_init();
module = m;
sysinfo_config->module = m;
return m;
}

View File

@ -291,6 +291,5 @@ EINTERN void sysinfo_netstatus_remove(void *data, Evas *e EINA_UNUSED, Evas_Obje
extern Config *sysinfo_config;
extern Eina_List *sysinfo_instances;
extern E_Module *module;
#endif