
We should only perform additional iteration steps when needed to initialize the parent of a device. Other binding errors (such as a missing driver) should not lead to additional iteration steps.
Unnecessary iteration steps can cause issues when memory is tightly constrained (such as in the TPL/SPL) since device_bind_by_name() unconditionally allocates memory for a struct udevice. On the SanCloud BBE this led to boot failure caused by memory exhaustion in the SPL when booting from SPI flash.
Signed-off-by: Paul Barker paul.barker@sancloud.com --- drivers/core/lists.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/drivers/core/lists.c b/drivers/core/lists.c index c49695b24f00..82d479564121 100644 --- a/drivers/core/lists.c +++ b/drivers/core/lists.c @@ -51,13 +51,13 @@ struct uclass_driver *lists_uclass_lookup(enum uclass_id id) return NULL; }
-static int bind_drivers_pass(struct udevice *parent, bool pre_reloc_only) +static bool bind_drivers_pass(struct udevice *parent, bool pre_reloc_only, + int *result) { struct driver_info *info = ll_entry_start(struct driver_info, driver_info); const int n_ents = ll_entry_count(struct driver_info, driver_info); bool missing_parent = false; - int result = 0; int idx;
/* @@ -98,12 +98,12 @@ static int bind_drivers_pass(struct udevice *parent, bool pre_reloc_only) drt->dev = dev; } else if (ret != -EPERM) { dm_warn("No match for driver '%s'\n", entry->name); - if (!result || ret != -ENOENT) - result = ret; + if (!*result || ret != -ENOENT) + *result = ret; } }
- return result ? result : missing_parent ? -EAGAIN : 0; + return missing_parent; }
int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only) @@ -117,13 +117,8 @@ int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only) * always succeed on the first pass. */ for (pass = 0; pass < 10; pass++) { - int ret; - - ret = bind_drivers_pass(parent, pre_reloc_only); - if (!ret) + if (!bind_drivers_pass(parent, pre_reloc_only, &result)) break; - if (ret != -EAGAIN && !result) - result = ret; }
return result;