Speed up daemon startup by 15%

During my fwupd startup fu_plugin_has_custom_flag gets called 21 times
which causes all HWIDs to be enumerated with 346 calls to the quite
expensive fu_context_lookup_quirk_by_id() function.

Move the flag to a private hashset and enumerate the HWIDs only during
startup. There's nothing plugin specific about them anyway...
This commit is contained in:
Richard Hughes 2021-11-02 20:43:58 +00:00
parent 43924010b0
commit 1a077289bc
8 changed files with 60 additions and 29 deletions

View File

@ -27,6 +27,7 @@ typedef struct {
GHashTable *compile_versions;
GPtrArray *udev_subsystems;
GHashTable *firmware_gtypes;
GHashTable *hwid_flags; /* str: */
FuBatteryState battery_state;
guint battery_level;
guint battery_threshold;
@ -501,6 +502,7 @@ gboolean
fu_context_load_hwinfo(FuContext *self, GError **error)
{
FuContextPrivate *priv = GET_PRIVATE(self);
GPtrArray *guids;
g_autoptr(GError) error_smbios = NULL;
g_autoptr(GError) error_hwids = NULL;
@ -512,10 +514,45 @@ fu_context_load_hwinfo(FuContext *self, GError **error)
if (!fu_hwids_setup(priv->hwids, priv->smbios, &error_hwids))
g_warning("Failed to load HWIDs: %s", error_hwids->message);
/* set the hwid flags */
guids = fu_context_get_hwid_guids(self);
for (guint i = 0; i < guids->len; i++) {
const gchar *guid = g_ptr_array_index(guids, i);
const gchar *value;
/* does prefixed quirk exist */
value = fu_context_lookup_quirk_by_id(self, guid, FU_QUIRKS_FLAGS);
if (value != NULL) {
g_auto(GStrv) values = g_strsplit(value, ",", -1);
for (guint j = 0; values[j] != NULL; j++)
g_hash_table_add(priv->hwid_flags, g_strdup(values[j]));
}
}
/* always */
return TRUE;
}
/**
* fu_context_has_hwid_flag:
* @self: a #FuContext
* @flag: flag, e.g. `use-legacy-bootmgr-desc`
*
* Returns if a HwId custom flag exists, typically added from a DMI quirk.
*
* Returns: %TRUE if the flag exists
*
* Since: 1.7.2
**/
gboolean
fu_context_has_hwid_flag(FuContext *self, const gchar *flag)
{
FuContextPrivate *priv = GET_PRIVATE(self);
g_return_val_if_fail(FU_IS_CONTEXT(self), FALSE);
g_return_val_if_fail(flag != NULL, FALSE);
return g_hash_table_lookup(priv->hwid_flags, flag) != NULL;
}
/**
* fu_context_load_quirks:
* @self: a #FuContext
@ -716,6 +753,7 @@ fu_context_finalize(GObject *object)
if (priv->compile_versions != NULL)
g_hash_table_unref(priv->compile_versions);
g_object_unref(priv->hwids);
g_hash_table_unref(priv->hwid_flags);
g_object_unref(priv->quirks);
g_object_unref(priv->smbios);
g_hash_table_unref(priv->firmware_gtypes);
@ -782,6 +820,7 @@ fu_context_init(FuContext *self)
priv->battery_threshold = FU_BATTERY_VALUE_INVALID;
priv->smbios = fu_smbios_new();
priv->hwids = fu_hwids_new();
priv->hwid_flags = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
priv->udev_subsystems = g_ptr_array_new_with_free_func(g_free);
priv->firmware_gtypes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
priv->quirks = fu_quirks_new();

View File

@ -45,6 +45,8 @@ gboolean
fu_context_has_hwid_guid(FuContext *self, const gchar *guid);
GPtrArray *
fu_context_get_hwid_guids(FuContext *self);
gboolean
fu_context_has_hwid_flag(FuContext *self, const gchar *flag);
const gchar *
fu_context_get_hwid_value(FuContext *self, const gchar *key);
gchar *

View File

@ -611,30 +611,12 @@ gboolean
fu_plugin_has_custom_flag(FuPlugin *self, const gchar *flag)
{
FuPluginPrivate *priv = GET_PRIVATE(self);
GPtrArray *guids;
g_return_val_if_fail(FU_IS_PLUGIN(self), FALSE);
g_return_val_if_fail(flag != NULL, FALSE);
/* never set up, e.g. in tests */
if (priv->ctx == NULL)
return FALSE;
/* search each hwid */
guids = fu_context_get_hwid_guids(priv->ctx);
for (guint i = 0; i < guids->len; i++) {
const gchar *guid = g_ptr_array_index(guids, i);
const gchar *value;
/* does prefixed quirk exist */
value = fu_context_lookup_quirk_by_id(priv->ctx, guid, FU_QUIRKS_FLAGS);
if (value != NULL) {
g_auto(GStrv) values = g_strsplit(value, ",", -1);
if (g_strv_contains((const gchar *const *)values, flag))
return TRUE;
}
}
return FALSE;
return fu_context_has_hwid_flag(priv->ctx, flag);
}
/**

View File

@ -133,4 +133,5 @@ fu_plugin_get_config_value_boolean(FuPlugin *self, const gchar *key);
gboolean
fu_plugin_set_config_value(FuPlugin *self, const gchar *key, const gchar *value, GError **error);
gboolean
fu_plugin_has_custom_flag(FuPlugin *self, const gchar *flag);
fu_plugin_has_custom_flag(FuPlugin *self, const gchar *flag)
G_DEPRECATED_FOR(fu_context_has_hwid_flag);

View File

@ -945,3 +945,9 @@ LIBFWUPDPLUGIN_1.7.1 {
fu_usb_device_new_with_context;
local: *;
} LIBFWUPDPLUGIN_1.7.0;
LIBFWUPDPLUGIN_1.7.2 {
global:
fu_context_has_hwid_flag;
local: *;
} LIBFWUPDPLUGIN_1.7.1;

View File

@ -16,7 +16,7 @@ gboolean
fu_plugin_device_created(FuPlugin *plugin, FuDevice *dev, GError **error)
{
if (fu_device_get_specialized_gtype(dev) == FU_TYPE_ELANTP_I2C_DEVICE &&
!fu_plugin_has_custom_flag(plugin, "elantp-recovery")) {
!fu_context_has_hwid_flag(fu_plugin_get_context(plugin), "elantp-recovery")) {
g_set_error_literal(error, FWUPD_ERROR, FWUPD_ERROR_NOT_SUPPORTED, "not required");
return FALSE;
}

View File

@ -38,7 +38,7 @@ fu_plugin_coldplug(FuPlugin *plugin, GError **error)
devices = fu_backend_get_devices(FU_BACKEND(data->backend));
for (guint i = 0; i < devices->len; i++) {
FuDevice *device = g_ptr_array_index(devices, i);
if (fu_plugin_has_custom_flag(plugin, "reset-required"))
if (fu_context_has_hwid_flag(fu_plugin_get_context(plugin), "reset-required"))
fu_device_add_flag(device, FWUPD_DEVICE_FLAG_NEEDS_REBOOT);
fu_plugin_device_add(plugin, device);
}
@ -343,7 +343,7 @@ fu_plugin_startup(FuPlugin *plugin, GError **error)
gboolean ca_check = fu_plugin_get_config_value_boolean(plugin, "CACheck");
fu_redfish_backend_set_cacheck(data->backend, ca_check);
}
if (fu_plugin_has_custom_flag(plugin, "wildcard-targets"))
if (fu_context_has_hwid_flag(fu_plugin_get_context(plugin), "wildcard-targets"))
fu_redfish_backend_set_wildcard_targets(data->backend, TRUE);
#ifdef HAVE_LINUX_IPMI_H

View File

@ -465,15 +465,15 @@ fu_plugin_uefi_capsule_coldplug_device(FuPlugin *plugin, FuUefiDevice *dev, GErr
return FALSE;
/* if not already set by quirks */
if (fu_plugin_has_custom_flag(plugin, "use-legacy-bootmgr-desc")) {
if (fu_context_has_hwid_flag(ctx, "use-legacy-bootmgr-desc")) {
fu_device_add_private_flag(FU_DEVICE(dev),
FU_UEFI_DEVICE_FLAG_USE_LEGACY_BOOTMGR_DESC);
}
if (fu_plugin_has_custom_flag(plugin, "supports-boot-order-lock")) {
if (fu_context_has_hwid_flag(ctx, "supports-boot-order-lock")) {
fu_device_add_private_flag(FU_DEVICE(dev),
FU_UEFI_DEVICE_FLAG_SUPPORTS_BOOT_ORDER_LOCK);
}
if (fu_plugin_has_custom_flag(plugin, "no-ux-capsule"))
if (fu_context_has_hwid_flag(ctx, "no-ux-capsule"))
fu_device_add_private_flag(FU_DEVICE(dev), FU_UEFI_DEVICE_FLAG_NO_UX_CAPSULE);
/* set fallback name if nothing else is set */
@ -522,6 +522,7 @@ fu_plugin_uefi_capsule_test_secure_boot(FuPlugin *plugin)
gboolean
fu_plugin_startup(FuPlugin *plugin, GError **error)
{
FuContext *ctx = fu_plugin_get_context(plugin);
FuPluginData *data = fu_plugin_get_data(plugin);
guint64 nvram_total;
g_autofree gchar *esp_path = NULL;
@ -534,11 +535,11 @@ fu_plugin_startup(FuPlugin *plugin, GError **error)
return TRUE;
/* for the uploaded report */
if (fu_plugin_has_custom_flag(plugin, "use-legacy-bootmgr-desc"))
if (fu_context_has_hwid_flag(ctx, "use-legacy-bootmgr-desc"))
fu_plugin_add_report_metadata(plugin, "BootMgrDesc", "legacy");
/* some platforms have broken SMBIOS data */
if (fu_plugin_has_custom_flag(plugin, "uefi-force-enable"))
if (fu_context_has_hwid_flag(ctx, "uefi-force-enable"))
return TRUE;
/* use GRUB to load updates */
@ -665,7 +666,7 @@ fu_plugin_uefi_update_state_notify_cb(GObject *object, GParamSpec *pspec, FuPlug
return;
/* only do this on hardware that cannot coalesce multiple capsules */
if (!fu_plugin_has_custom_flag(plugin, "no-coalesce"))
if (!fu_context_has_hwid_flag(fu_plugin_get_context(plugin), "no-coalesce"))
return;
/* mark every other device for this plugin as non-updatable */