how to achieve optimal alignment for emmc partition?

6,020

Solution 1

Try to align to eMMC erasure block size. It usually equals 0.5, 1, 2, 4, 8 MiB depending on eMMC datasheet. If you find block size alignment too much memory wasting, then stick to the page size, generally found in the range of 4..16 KiB.

Try to make partition sizes and borders a multiple of erasure block size, so when file system writes to the first or last FS block, memory card doesn't have to erase and rewrite beginning/end of next/previous partition.

Don't rely on parted's features to align, just take a calculator, pen and a sheet of paper, and count up a correct borders in sectors or bytes.

Personally, I prefer aligning to 8 MiB border, because it isn't waste too much memory, and any partition starts and ends on erasure block border regardless of specific erasure block size, so I don't need to search for memory card documentation.

Optimal alignment reduces write amplification factor, so your memory could last longer.

Solution 2

The answer depends on the disk. parted displayed the error message

not aligned: 2048s % 65535s != 0s

when I tried to partition a Kingston SA400M8120G. However,a Samsung 980 PRO 250GB could be partitioned arbitrarily without warnings. A hint comes from the dmesg log when plugging in the Kingston drive (via a USB → NVMe adapter):

[81602.009178] scsi 6:0:0:0: Direct-Access     ASMT     2115             0    PQ: 0 ANSI: 6
[81602.010206] sd 6:0:0:0: Attached scsi generic sg1 type 0
[81602.021292] sd 6:0:0:0: [sda] 234441648 512-byte logical blocks: (120 GB/112 GiB)
[81602.021390] sd 6:0:0:0: [sda] Write Protect is off
[81602.021395] sd 6:0:0:0: [sda] Mode Sense: 43 00 00 00
[81602.021619] sd 6:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[81602.021903] sd 6:0:0:0: [sda] Optimal transfer size 33553920 bytes
[81602.061285] sd 6:0:0:0: [sda] Attached SCSI disk

The most important information is the Optimal transfer size 33553920 bytes. I.e., for “optimal alignment” the partitions shall begin at integer multiples of 33553920 (= 65535 ⋅ 512) bytes.

Based on How to align partitions for best performance using parted I resolved the alignment problem by querying the sys filesystem. The disk to partition was /dev/sda, the system is a current (2020-12-22) Archlinux, kernel 5.9.14-arch1-1, parted is revision 3.3:

DISK="sda"
OPTIMAL_IO_SIZE=$(cat /sys/block/${DISK}/queue/optimal_io_size)
ALIGNMENT_OFFSET=$(cat /sys/block/${DISK}/alignment_offset)
PHYSICAL_BLOCK_SIZE=$(cat /sys/block/${DISK}/queue/physical_block_size)

With these variables I could calculate the start sectors of the partitions. Knowing the values of OPTIMAL_IO_SIZE and PHYSICAL_BLOCK_SIZE I adjusted the magic numbers to 11 and 128:

START_EFI=$(((OPTIMAL_IO_SIZE+ALIGNMENT_OFFSET)/PHYSICAL_BLOCK_SIZE))
START_SWAP=$((START_EFI+11*OPTIMAL_IO_SIZE/PHYSICAL_BLOCK_SIZE))
START_ROOT=$((START_SWAP+128*OPTIMAL_IO_SIZE/PHYSICAL_BLOCK_SIZE))

With this knowledge, invoking parted is straightforward:

parted -s -a optimal /dev/${DISK} mklabel gpt \
 mkpart "Efi"  fat32      ${START_EFI}s  $((START_SWAP-1))s \
 mkpart "Swap" linux-swap ${START_SWAP}s $((START_ROOT-1))s \
 mkpart "root" ext4       ${START_ROOT}s  100% \
 set 1 esp on \
 print

Verify that the alignment is correct:

parted /dev/sda align-check optimal 1 \
 align-check optimal 2 \
 align-check optimal 3

The output reads:

1 aligned
2 aligned
3 aligned

As already stated, the answer above is for a “Kingston SA400M8120G”. I must admit, I have not found any other device (SATA drive, SDCard, NVMe drive, USB stick) which reports an “Optimal transfer size” different from 0. From that I would conclude that the latter drives do not require a special alignment. And parted does not report alignment warnings for them.

Share:
6,020

Related videos on Youtube

ART
Author by

ART

Updated on September 18, 2022

Comments

  • ART
    ART almost 2 years

    We have bbb based custom board containing eMMC.
    And we have created partitions as follows,

    parted --script -a minimal /dev/mmcblk0 \
      mklabel gpt \
      mkpart primary 131072B 262143B \
      mkpart primary 262144B 393215B \
      mkpart primary 393216B 524287B \
      mkpart primary 524288B 1572863B \
      mkpart primary 1572864B 2621439B \ 
      mkpart primary 2621440B 3145727B \
      mkpart primary 3145728B 3276799B \ 
      mkpart primary 3276800B 8519679B \
      mkpart primary 8519680B 13762559B \
      mkpart primary 13762560B 19005439B \
      mkpart primary 19005440B 19267583B \
      mkpart primary 19267584B 19529727B \
      mkpart primary 19529728B 19791871B \
      mkpart primary 20MiB 31MiB \
      mkpart primary ext4 32MiB 232MiB \
      mkpart primary ext4 232MiB 432MiB \
      mkpart primary ext4 432MiB 532MiB \
      mkpart primary ext4 532MiB 592MiB \
      mkpart primary ext4 592MiB 792MiB \
      mkpart primary ext4 792MiB 827MiB \
      mkpart primary ext4 827MiB 3650MiB \
    

    With above command we are able to partition eMMC but alignment is set to minimal. We wanted to check how can we achieve optimal alignment ? Is there any advantage in achieving optimal alignment ? I referred this link but solutions like parted -a opt /dev/sdb mkpart primary 0% 100% can not be used as we need following structure.

    # parted --list
    Model: MMC MMC04G (sd/mmc)
    Disk /dev/mmcblk0: 3842MB
    Sector size (logical/physical): 512B/512B
    Partition Table: gpt
    Disk Flags:
    
    Number  Start   End     Size    File system  Name        Flags
     1      131kB   262kB   131kB                
     2      262kB   393kB   131kB                
     3      393kB   524kB   131kB                
     4      524kB   1573kB  1049kB               
     5      1573kB  2621kB  1049kB               
     6      2621kB  3146kB  524kB                
     7      3146kB  3277kB  131kB                
     8      3277kB  8520kB  5243kB               
     9      8520kB  13.8MB  5243kB               
    10      13.8MB  19.0MB  5243kB               
    11      19.0MB  19.3MB  262kB                
    12      19.3MB  19.5MB  262kB                
    13      19.5MB  19.8MB  262kB                
    14      21.0MB  32.5MB  11.5MB               
    15      33.6MB  243MB   210MB   ext4         
    16      243MB   453MB   210MB   ext4         
    17      453MB   558MB   105MB   ext4         
    18      558MB   621MB   62.9MB  ext4         
    19      621MB   830MB   210MB   ext4         
    20      830MB   867MB   36.7MB  ext4         
    21      867MB   3827MB  2960MB  ext4         
    

    With current command if we replace minimal with optimal we are seeing following messages from parted,

    Warning: The resulting partition is not properly aligned for best performance.
    Warning: The resulting partition is not properly aligned for best performance.
    Warning: The resulting partition is not properly aligned for best performance.
    Warning: The resulting partition is not properly aligned for best performance.
    Warning: The resulting partition is not properly aligned for best performance.
    Warning: The resulting partition is not properly aligned for best performance.
    Warning: The resulting partition is not properly aligned for best performance.
    Warning: The resulting partition is not properly aligned for best performance.
    Warning: The resulting partition is not properly aligned for best performance.
    Warning: The resulting partition is not properly aligned for best performance.
    Warning: The resulting partition is not properly aligned for best performance.
    Warning: The resulting partition is not properly aligned for best performance.
    

    Any pointers/suggestions/correction for achieving optimal alignment ?

    as suggested in the this link I extracted following values,

    # cat /sys/class/mmc_host/mmc1/mmc1\:0001/block/mmcblk0/queue/optimal_io_size
    0
    # cat /sys/class/mmc_host/mmc1/mmc1\:0001/block/mmcblk0/queue/minimum_io_size
    512
    # cat /sys/class/mmc_host/mmc1/mmc1\:0001/block/mmcblk0/alignment_offset
    0
    # cat /sys/class/mmc_host/mmc1/mmc1\:0001/block/mmcblk0/queue/physical_block_siz
    e
    512
    

    mmc utils give following output,

    # ./mmc extcsd read /dev/mmcblk0
    =============================================
      Extended CSD rev 1.5 (MMC 4.41)
    =============================================
    
    Card Supported Command sets [S_CMD_SET: 0x01]
    HPI Features [HPI_FEATURE: 0x03]: implementation based on CMD12
    Background operations support [BKOPS_SUPPORT: 0x01]
    Background operations status [BKOPS_STATUS: 0x02]
    1st Initialisation Time after programmed sector [INI_TIMEOUT_AP: 0x7a]
    Power class for 52MHz, DDR at 3.6V [PWR_CL_DDR_52_360: 0x00]
    Power class for 52MHz, DDR at 1.95V [PWR_CL_DDR_52_195: 0x00]
    Minimum Performance for 8bit at 52MHz in DDR mode:
     [MIN_PERF_DDR_W_8_52: 0x00]
     [MIN_PERF_DDR_R_8_52: 0x00]
    TRIM Multiplier [TRIM_MULT: 0x06]
    Secure Feature support [SEC_FEATURE_SUPPORT: 0x15]
    Secure Erase Multiplier [SEC_ERASE_MULT: 0x02]
    Secure TRIM Multiplier [SEC_TRIM_MULT: 0x03]
    Boot Information [BOOT_INFO: 0x07]
     Device supports alternative boot method
     Device supports dual data rate during boot
     Device supports high speed timing during boot
    Boot partition size [BOOT_SIZE_MULTI: 0x10]
    Access size [ACC_SIZE: 0x06]
    High-capacity erase unit size [HC_ERASE_GRP_SIZE: 0x08]
     i.e. 4096 KiB
    High-capacity erase timeout [ERASE_TIMEOUT_MULT: 0x01]
    Reliable write sector count [REL_WR_SEC_C: 0x01]
    High-capacity W protect group size [HC_WP_GRP_SIZE: 0x01]
     i.e. 4096 KiB
    Sleep current (VCC) [S_C_VCC: 0x08]
    Sleep current (VCCQ) [S_C_VCCQ: 0x08]
    Sleep/awake timeout [S_A_TIMEOUT: 0x10]
    Sector Count [SEC_COUNT: 0x00728000]
     Device is block-addressed
    Minimum Write Performance for 8bit:
     [MIN_PERF_W_8_52: 0x08]
     [MIN_PERF_R_8_52: 0x08]
     [MIN_PERF_W_8_26_4_52: 0x08]
     [MIN_PERF_R_8_26_4_52: 0x08]
    Minimum Write Performance for 4bit:
     [MIN_PERF_W_4_26: 0x08]
     [MIN_PERF_R_4_26: 0x08]
    Power classes registers:
     [PWR_CL_26_360: 0x00]
     [PWR_CL_52_360: 0x00]
     [PWR_CL_26_195: 0x00]
     [PWR_CL_52_195: 0x00]
    Partition switching timing [PARTITION_SWITCH_TIME: 0x01]
    Out-of-interrupt busy timing [OUT_OF_INTERRUPT_TIME: 0x02]
    Card Type [CARD_TYPE: 0x07]
     HS Dual Data Rate eMMC @52MHz 1.8V or 3VI/O
     HS eMMC @52MHz - at rated device voltage(s)
     HS eMMC @26MHz - at rated device voltage(s)
    CSD structure version [CSD_STRUCTURE: 0x02]
    Command set [CMD_SET: 0x00]
    Command set revision [CMD_SET_REV: 0x00]
    Power class [POWER_CLASS: 0x00]
    High-speed interface timing [HS_TIMING: 0x01]
    Erased memory content [ERASED_MEM_CONT: 0x00]
    Boot configuration bytes [PARTITION_CONFIG: 0x00]
     Not boot enable
     No access to boot partition
    Boot config protection [BOOT_CONFIG_PROT: 0x00]
    Boot bus Conditions [BOOT_BUS_CONDITIONS: 0x00]
    High-density erase group definition [ERASE_GROUP_DEF: 0x01]
    Boot write protection status registers [BOOT_WP_STATUS]: 0x00
    Boot Area Write protection [BOOT_WP]: 0x00
     Power ro locking: possible
     Permanent ro locking: possible
     ro lock status: not locked
    User area write protection register [USER_WP]: 0x00
    FW configuration [FW_CONFIG]: 0x00
    RPMB Size [RPMB_SIZE_MULT]: 0x01
    Write reliability setting register [WR_REL_SET]: 0x00
     user area: existing data is at risk if a power failure occurs during a write operation
     partition 1: existing data is at risk if a power failure occurs during a write operation
     partition 2: existing data is at risk if a power failure occurs during a write operation
     partition 3: existing data is at risk if a power failure occurs during a write operation
     partition 4: existing data is at risk if a power failure occurs during a write operation
    Write reliability parameter register [WR_REL_PARAM]: 0x05
     Device supports writing EXT_CSD_WR_REL_SET
     Device supports the enhanced def. of reliable write
    Enable background operations handshake [BKOPS_EN]: 0x00
    H/W reset function [RST_N_FUNCTION]: 0x00
    HPI management [HPI_MGMT]: 0x01
    Partitioning Support [PARTITIONING_SUPPORT]: 0x03
     Device support partitioning feature
     Device can have enhanced tech.
    Max Enhanced Area Size [MAX_ENH_SIZE_MULT]: 0x0001ca
     i.e. 1875968 KiB
    Partitions attribute [PARTITIONS_ATTRIBUTE]: 0x00
    Partitioning Setting [PARTITION_SETTING_COMPLETED]: 0x00
     Device partition setting NOT complete
    General Purpose Partition Size
     [GP_SIZE_MULT_4]: 0x000000
     [GP_SIZE_MULT_3]: 0x000000
     [GP_SIZE_MULT_2]: 0x000000
     [GP_SIZE_MULT_1]: 0x000000
    Enhanced User Data Area Size [ENH_SIZE_MULT]: 0x000000
     i.e. 0 KiB
    Enhanced User Data Start Address [ENH_START_ADDR]: 0x000000
     i.e. 0 bytes offset
    Bad Block Management mode [SEC_BAD_BLK_MGMNT]: 0x00
    

    EDIT: Achieved optimal alignment as suggested by "Глеб Майоров", Except first 3 partition(which I can't change) other small partitions are changed to minimum of 1MiB size. And except for 3 partitions, all other partitions seems to be aligned. Here is the latest partitioning script I used for eMMC.(Please note: In below script I have changed partition sizes w.r.t above script)

    parted --script -a optimal /dev/mmcblk0 \
      mklabel gpt \
      mkpart primary 128KiB 255KiB \
      mkpart primary 256KiB 383KiB \
      mkpart primary 384KiB 511KiB \
      mkpart primary 1MiB 2MiB \
      mkpart primary 2MiB 3MiB \ 
      mkpart primary 3MiB 4MiB \
      mkpart primary 4MiB 5MiB \ 
      mkpart primary 5MiB 10MiB \
      mkpart primary 10MiB 15MiB \
      mkpart primary 15MiB 20MiB \
      mkpart primary 20MiB 21MiB \
      mkpart primary 21MiB 22MiB \
      mkpart primary 22MiB 23MiB \
      mkpart primary 23MiB 30MiB \
      mkpart primary ext4 30MiB 530MiB \
      mkpart primary ext4 530MiB 1030MiB \
      mkpart primary ext4 1030MiB 1130MiB \
      mkpart primary ext4 1130MiB 1190MiB \
      mkpart primary ext4 1190MiB 1720MiB \
      mkpart primary ext4 1720MiB 1755MiB \
      mkpart primary ext4 1755MiB 100%
    
  • ART
    ART over 8 years
    @"Глеб Майоров" Thank you for reply, I have couple of questions, mmc utils gives option to mmc disable 512B emulation <device>, do you suggest to disable it.(i think that will improve performance) emmc size is 4GB. If you see initial partitions are raw and their sizes are in kb that should not create any problem as far as we keep them in sector boundry right ? GPT takes ~17kb of initial portion of the disk. in that case how can we align partition manually ?
  • Gleb Mayorov
    Gleb Mayorov over 8 years
    @AnkurTank In my opinion memory card's bottleneck is flash memory latency, not sector size emulation, so I don't see any difference between disabling or enabling it. Sector size is virtual value, and flash memory page can be represented as multiple 512 B sectors - 8, 16 or 32. Consider memory page as a kind of "real" sector. So align to sector without taking page size into account could make your partition start from the middle of a flash memory page, making it virtually aligned in terms of parted, which sees 512B logical/physical sectors and partitions aligned to it, but misaligned in real.
  • Gleb Mayorov
    Gleb Mayorov over 8 years
    @ArthurTank Just left some free space between GPT and the beginning of first partition, so it starts, for example, from 1 MiB, or from the beginning second flash erasure block, in case you know it's size.
  • ART
    ART over 8 years
    Thank you for reply. will parted see real page size if we disable 512 B sector emulation? Is there any problem in disabling 512B emulation ? I would have left 1MiB memory at the beginning but SPL(or x-loader) for am335x looks for either of 4 copies of SPL(of size 128k max) from beginning of the flash). I think, should leave 3 pages(assuming 4KB size of physical page). How can we find physical page size of eMMC High-capacity erase unit size [HC_ERASE_GRP_SIZE: 0x08] i.e. 4096 KiB in mmc extcsd read command means 4KB page size ?