Let's make use of the newly introduced part_get_info_cached() API and the part_get_info_cached_free() when scanning all partitions of a disk. With this, a lot of unnecessary computation is saved, leading to a faster boot time when partitions are scanned, especially with storage medias with potentially multiple large hardware partitions like UFS, NVMe or eMMC.
Since the default part scan code will always scan up to 128 partitions for a block, and devices with an UFS chip with up to 8 LUNs are very common in the field, this means a complete GPT parsing and validation will be done up to 1024 times instead of 8 on such devices. On the SM8650 QRD platform with a KIOXIA THGJFJT1E45BATPC configured with 8 LUNs, the scsi scan takes 0.2s with both CPU caches enabled, but when disabling both CPU caches it goes up to 4s to do the full scan of all 8 LUN partitions. With this change the scan takes only 0.18s with both CPU caches enabled running 1.1x times faster, and with both CPU caches disabled the full scan takes only 1.27s running 3x faster. While 20ms could look negligeable, it's still a 20ms gain in the boot flow and a non negligeable reduction in calculation and memory allocation since for each scan it would allocate and free the gpt_pte table up to 1024 times, now it would only do 8 allocations, reducing memory fragmentation. Signed-off-by: Neil Armstrong <neil.armstr...@linaro.org> --- drivers/block/blk-uclass.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/block/blk-uclass.c b/drivers/block/blk-uclass.c index f3ac8db9464311acbc96f3358e0ef143471ca59d..313fbe6a480e5bced5230c6ea03a3815cf4087b9 100644 --- a/drivers/block/blk-uclass.c +++ b/drivers/block/blk-uclass.c @@ -820,15 +820,17 @@ static int part_create_block_devices(struct udevice *blk_dev) /* Add devices for each partition */ for (count = 0, part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { - if (part_get_info(desc, part, &info)) + if (part_get_info_cached(desc, part, &info)) continue; snprintf(devname, sizeof(devname), "%s:%d", blk_dev->name, part); ret = device_bind_driver(blk_dev, "blk_partition", strdup(devname), &dev); - if (ret) + if (ret) { + part_get_info_cached_free(desc); return ret; + } part_data = dev_get_uclass_plat(dev); part_data->partnum = part; @@ -847,6 +849,7 @@ static int part_create_block_devices(struct udevice *blk_dev) debug("%s: %d partitions found in %s\n", __func__, count, blk_dev->name); + part_get_info_cached_free(desc); return 0; } -- 2.34.1