Speed up fwupd startup by loading less thunderbolt firmware

We load the Thunderbolt controller firmware to see if the controller is in
native mode, as this changes the GUID. If the controller is asleep the firmware
is not cached by the kernel and it can take more than 4 seconds to read out
504kB of firmware.

We only need the first two 64-byte chunks, so only read what is required.
This speeds up fwupd starting substantially, and also means we don't have to
allocate a giant chunk of heap memory just to inspect one byte.

Fixes: https://github.com/hughsie/fwupd/issues/848
This commit is contained in:
Richard Hughes 2018-11-14 12:20:23 +00:00
parent 840184929b
commit 86b79fb039
3 changed files with 20 additions and 8 deletions

View File

@ -193,19 +193,25 @@ fu_plugin_thunderbolt_udev_get_version (GUdevDevice *udevice)
static gboolean
fu_plugin_thunderbolt_is_native (GUdevDevice *udevice, gboolean *is_native, GError **error)
{
gsize nr_chunks;
g_autoptr(GFile) nvmem = NULL;
g_autoptr(GBytes) controller_fw = NULL;
gchar *content;
gsize length;
g_autoptr(GInputStream) istr = NULL;
nvmem = fu_plugin_thunderbolt_find_nvmem (udevice, TRUE, error);
if (nvmem == NULL)
return FALSE;
if (!g_file_load_contents (nvmem, NULL, &content, &length, NULL, error))
/* read just enough bytes to read the status byte */
nr_chunks = (FU_TBT_OFFSET_NATIVE + FU_TBT_CHUNK_SZ - 1) / FU_TBT_CHUNK_SZ;
istr = G_INPUT_STREAM (g_file_read (nvmem, NULL, error));
if (istr == NULL)
return FALSE;
controller_fw = g_input_stream_read_bytes (istr,
nr_chunks * FU_TBT_CHUNK_SZ,
NULL, error);
if (controller_fw == NULL)
return FALSE;
controller_fw = g_bytes_new_take (content, length);
return fu_thunderbolt_image_controller_is_native (controller_fw,
is_native,

View File

@ -787,8 +787,10 @@ fu_thunderbolt_image_controller_is_native (GBytes *controller_fw,
gsize fw_size;
const guint8 *fw_data = g_bytes_get_data (controller_fw, &fw_size);
const FuThunderboltFwObject controller = { fw_data, fw_size, controller_sections };
const FuThunderboltFwLocation location = { .offset = 0x7B, .len = 1, .description = "Native", .mask = 0x20 };
const FuThunderboltFwLocation location = {
.offset = FU_TBT_OFFSET_NATIVE,
.len = 1,
.description = "Native",
.mask = 0x20 };
return read_bool (&location, &controller, is_native, error);
}

View File

@ -15,6 +15,10 @@ typedef enum {
UNKNOWN_DEVICE,
} FuPluginValidation;
/* byte offsets in firmware image */
#define FU_TBT_OFFSET_NATIVE 0x7B
#define FU_TBT_CHUNK_SZ 0x40
FuPluginValidation fu_thunderbolt_image_validate (GBytes *controller_fw,
GBytes *blob_fw,
GError **error);