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

Reply via email to