From 64dfbf629dedf0f78a7eb3409816b934716d2d06 Mon Sep 17 00:00:00 2001 From: Sebastian Keller Date: Tue, 1 Mar 2022 15:06:10 +0100 Subject: [PATCH] info: Fix RAM calculation with empty slots on some hardware On some hardware the value in MEMORY_ARRAY_NUM_DEVICES does not correspond to the number of MEMORY_DEVICEs reported via udev properties. This for example can happen on hardware that only has two physical slots, while the chipset theoretically supports four. Then the value reported as "Number of Memory Devices", (the MEMORY_ARRAY_NUM_DEVICES property) can reflect the number of physical slots available. This would cause the loop to only look at two MEMORY_DEVICEs when there actually are four. This commit changes the loop to iterate over MEMORY_DEVICE properties based on systemd assigning consecutive numbers to the devices and either setting a size property or a "present" property with a value of 0 instead of relying on MEMORY_ARRAY_NUM_DEVICES. Fixes: https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/1686 --- panels/info-overview/cc-info-overview-panel.c | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/panels/info-overview/cc-info-overview-panel.c b/panels/info-overview/cc-info-overview-panel.c index 274a3c6446..652327b62f 100644 --- a/panels/info-overview/cc-info-overview-panel.c +++ b/panels/info-overview/cc-info-overview-panel.c @@ -742,19 +742,33 @@ get_ram_size_dmi (void) g_autoptr(GUdevDevice) dmi = NULL; const gchar * const subsystems[] = {"dmi", NULL }; guint64 ram_total = 0; - guint64 num_ram; guint i; + gboolean entry_exists = TRUE; client = g_udev_client_new (subsystems); dmi = g_udev_client_query_by_sysfs_path (client, "/sys/devices/virtual/dmi/id"); if (!dmi) return 0; - num_ram = g_udev_device_get_property_as_uint64 (dmi, "MEMORY_ARRAY_NUM_DEVICES"); - for (i = 0; i < num_ram ; i++) { - g_autofree char *prop = NULL; - prop = g_strdup_printf ("MEMORY_DEVICE_%d_SIZE", i); - ram_total += g_udev_device_get_property_as_uint64 (dmi, prop); + /* systemd uses consecutive numbers for the memory devices and either assigns + * a size property if a module is present or a "present" property with a value + * of 0 if the slot is empty. + * https://github.com/systemd/systemd/blob/main/src/udev/dmi_memory_id/dmi_memory_id.c + */ + for (i = 0; entry_exists; i++) { + g_autofree char *present_prop = NULL; + g_autofree char *size_prop = NULL; + guint64 size; + + size_prop = g_strdup_printf ("MEMORY_DEVICE_%d_SIZE", i); + size = g_udev_device_get_property_as_uint64 (dmi, size_prop); + ram_total += size; + + if (size == 0) + { + present_prop = g_strdup_printf ("MEMORY_DEVICE_%d_PRESENT", i); + entry_exists = g_udev_device_has_property (dmi, present_prop); + } } return ram_total; } -- GitLab