From 667180cbc8f4f823445e0c7b7beb72d6d7d26cdc Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 24 Feb 2021 11:26:10 -0800 Subject: [PATCH] sysprofd: add API to set perf_event_paranoid This will allow us to get more information on demand when running the profiler without endless tweaking by end users. --- src/org.gnome.Sysprof3.Service.xml | 12 ++++++++ src/sysprofd/ipc-service-impl.c | 47 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/org.gnome.Sysprof3.Service.xml b/src/org.gnome.Sysprof3.Service.xml index de325a99..0f282649 100644 --- a/src/org.gnome.Sysprof3.Service.xml +++ b/src/org.gnome.Sysprof3.Service.xml @@ -106,5 +106,17 @@ + + + + + + diff --git a/src/sysprofd/ipc-service-impl.c b/src/sysprofd/ipc-service-impl.c index 88ab4b36..da9bf473 100644 --- a/src/sysprofd/ipc-service-impl.c +++ b/src/sysprofd/ipc-service-impl.c @@ -375,6 +375,52 @@ finish: return TRUE; } +static gboolean +ipc_service_impl_handle_set_paranoid (IpcService *service, + GDBusMethodInvocation *invocation, + int paranoid) +{ + g_autoptr(GError) error = NULL; + g_autofree gchar *str = NULL; + int previous = G_MAXINT; + + g_assert (IPC_IS_SERVICE (service)); + g_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); + + paranoid = CLAMP (paranoid, -1, 2); + + if (!g_file_get_contents ("/proc/sys/kernel/perf_event_paranoid", &str, NULL, &error)) + { + g_warning ("Failed to discover previous perf_event_paranoid setting: %s", error->message); + goto finish; + } + + previous = g_ascii_strtoll (str, NULL, 10); + + if (previous != paranoid) + { + char paranoid_str[8]; + gssize len = g_snprintf (paranoid_str, sizeof paranoid_str, "%d", paranoid); + + if (!file_set_contents_no_backup ("/proc/sys/kernel/perf_event_paranoid", paranoid_str, len, &error)) + g_warning ("Failed to set perf_event_paranoid: %s", error->message); + } + +finish: + if (error != NULL) + g_dbus_method_invocation_return_error (g_steal_pointer (&invocation), + G_DBUS_ERROR, + G_DBUS_ERROR_FAILED, + "Failed to set perf_event_paranoid: %s", + error->message); + else + ipc_service_complete_set_paranoid (service, + g_steal_pointer (&invocation), + previous); + + return TRUE; +} + static void init_service_iface (IpcServiceIface *iface) { @@ -384,6 +430,7 @@ init_service_iface (IpcServiceIface *iface) iface->handle_perf_event_open = ipc_service_impl_handle_perf_event_open; iface->handle_get_process_info = ipc_service_impl_handle_get_process_info; iface->handle_set_governor = ipc_service_impl_handle_set_governor; + iface->handle_set_paranoid = ipc_service_impl_handle_set_paranoid; } G_DEFINE_TYPE_WITH_CODE (IpcServiceImpl, ipc_service_impl, IPC_TYPE_SERVICE_SKELETON,