Linux SSD partition alignment – problems with external USB-to-SATA controllers – II

In my last article
Linux SSD partition alignment – problems with external USB-to-SATA controllers – I
I wrote about different partition alignments parted and YaST’s Partitioner (Opensuse) applied when one and the same SSD (a Samsung 850 Pro) was attached

  • to external USB-to-SATA controllers and the USB bus of a Linux system (1 MiB-alignment: start sectors as multiples of 2048 logical 512 byte blocks)
  • or directly to an internal SATA-III-controller of a Linux system (alignment to multiples of 65535 logical 512 byte blocks).

We saw that different controllers led to the detection of different disk topology parameters (I/O limits) by the Linux system via the libblkid library. For one and the same SSD different values were reported by different controllers e.g. for the following parameters (I/O Limits data) :

physical_block_size,    minimum_io_size,    optimal_io_size

We saw in addition that even different Linux disk tools may report different values; e.g. fdisk showed a different value [512 byte] for the “optimal_io_size” for the SSD on the SATA bus than e.g. lsblk and parted [0].

Guided by a Red Hat article https://people.redhat.com/msnitzer/docs/io-limits.txt we came to the conclusion that at least parted and YaST’s Partitioner use heuristic rules for its alignment decisions. The rules take into account the values for disk “I/O Limits” parameters. They are consistent with a default of “optimal” for the alignment parameter of parted and provide a decision when “the value for “optimal_io_size” is found to be zero. By applying these rules we could explain why we got different partition offsets and alignments for one and the same disk when it was attached to different controllers.

But this insight left us in an uncomfortable situation:

  1. Should we cling to the chosen settings when we use the SSD on external controllers, only? Can we partition SSDs on an external USB-to-SATA controller and move them later directly to a SATA-bus without adjusting partition borders? We saw that “parted” would complain about misalignment when SSD partitions were prepared on a different controller.
  2. As many people discuss the importance of partition alignment for SSD performance – will we see a noticeable drop in performance when we read/write to “misaligned” partitions?
  3. We saw that at least a JMicron controller indicated a bundling of 8 logical 512 byte blocks into a 4096 byte (fake?) “physical block”. Another question might therefore be what happens after an installation and something is written by Grub to the first sector of a disk with GPT layout – and maybe assuming some wrong disk topology? This is not so far fetched as one may think; see the third link at the bottom for a disaster with an MBR.

I cannot answer all these questions in general. But in this article I will at least look a bit into performance issues and answer the last question for my test situation.

Continue reading

Linux SSD partition alignment – problems with external USB-to-SATA controllers – I

When you try to find a solution for one problem suddenly another problem appears – and you find yourself confronted with something you never worried about before. For my article series on full laptop encryption with Opensuse Leap 15 I wanted to prepare a new SSD on my Linux desktop. This SSD should later on become the main disk of the laptop. I used an external disk box with an USB-to-SATA-controller from JMicron to attach the disk to the USB-3 bus of my desktop system. And stumbled across a really strange partitioning scheme YaST’s “partitioner” set up on my SSD during installation.

For a SSD you normally expect Linux to choose a so called “1 MiB-alignment“. Among other things this alignment leads to a minimum offset of the first partition of 2048 logical sectors/blocks with 512 byte. The math is 2048 * 512 = 1024 * 1024 = 1 (MiB) = 256 * 4096. This sector start address is well suited for so called AF disks with native 4k support, but also for disks with conventional 512 byte physical blocks. Note that 1024 * 1024 can be divided by both 512 and 4096 without remainder.

From previous experience with SSDs attached to SATA-III controllers on a Linux system I would have said: Any partition on a SSD shows a logical start block number which is a multiple of 2048 on a Linux system. And I would have bet that this were true for the size of a partition number expressed in block numbers, too. I had never questioned this before … In addition there are many articles on the Internet that tell users not to worry about alignment because all Linux tools today handle alignment correctly.

However, in my test situation I got something very different – and consequently some (!) Linux partitioning tools on the laptop later complained about misalignment. This worried me. Googling lead me to the following unanswered question at
https://superuser.com/questions/1291467/trouble-figuring-out-optimal-alignment-of-multiple-partitions-on-a-931-5-gib-ext,
which describes more or less my problem.

I have tried to figure out what was/is behind these “misalignment” problem – and the result shocked me a bit. It triggers questions about manufacturers of disk controllers and the way Linux handles disk property information. In addition I had a brief look at performance for an aligned and an unaligned partition. The results again puzzled me. I find it difficult to get a consistent picture out of my findings for partition alignment on SSDs at different controllers. Write me a mail if you know better …

Anyway, I hope this article, which digs into areas of Linux which are a bit offside standard usage, finds the interest of some other Linux fans, too ….

I shall use the words “blocks” (OS perspective) and “sectors” (atomic disk unit) on the level of partitioning interchangeably – which is not quite correct semantically. But you find this mix of wording also in disk tools :-).

The problem

I used an external box for my SSD which contained a JMicron USB-to-SATA controller. When my SSD – a Samsung 850 Pro – was attached to my Linux desktop via an external USB interface, the physical sector size was reported to be 4096 bytes by lsblk, by parted and fdisk. This stood a bit in contrast to other reports for this SSD type on the Internet; but SSD technology changes so often; I did not make me suspicious. I added a BIOS boot partition and several other partitions to the disk first with YaST’s Partitioner. The start sector of the first partition was chosen by YaST to be 65535.

mytux:~ # fdisk -l /dev/sdh 
Disk /dev/sdh: 477 GiB, 512110190592 bytes, 1000215216 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O 
size (minimum/optimal): 4096 bytes / 33553920 bytes
Disklabel type: gpt
Disk identifier: ....

Device         Start       End   Sectors  Size Type
/dev/sdh1      65535    131069     65535   32M BIOS boot
/dev/sdh2     131070   1376234   1245165  608M EFI System
/dev/sdh3    1376235  37027274  35651040  17GM Linux swap
...

OK, I had noticed before that some present partitioning tools choose a 32 MiB offset for the first partition these days. However, the number 65535 is NOT a multiple of 2048 and thus gives 31,99951171875 MiB. An offset of 65536 logical blocks would, however, fit exactly to 32 MiB.
Also all other partitions on the external SSD were “aligned” (?) to start sector numbers which were multiples of 65535.
Addendum 05.12.2018: I retested this with the tool parted – without defining a special alignment type, i.e. using defaults. Same result.

65535 is compatible with a physical block size of 512 bytes, but NOT 4096 bytes. Interestingly, 65535 also fits an erase block size of 1536 MiB, which a lot of people assume to be used by Samsung for its SSDs. Wherever these people got this information from … see e.g. https://www.phoronix.com/forums/forum/hardware/general-hardware/1030306-samsung-970-evo-nvme-ssd-benchmarks-on-ubuntu-linux.

But: I checked against partition boundaries on another Linux system with the same type of SSD directly attached to the internal (Intel) SATA controller. There the alignment fitted exactly the theory of boundaries as multiples of 1 MiB (=> multiples of 2048 logical blocks as start sector numbers). I also checked for systems with other internal SSDs. 1 MiB alignment …

Then I built the disk into my laptop and attached it directly to the SATA interface there – and got a plain “1 MiB”-alignment (both for YaST’s Partitioner and parted with defaults).

mylux:~ # fdisk -l /dev/sda 
Disk /dev/sda: 477 GiB, 512110190592 bytes, 1000215216 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: ....

Device         Start       End   Sectors  Size Type
/dev/sda1      2048      67583     65536   32M BIOS boot
...

If one had added more partitions the pattern would have repeated itself: With the SSD on the SATA controller the start sector numbers became multiples of 2048; on the external JMicron USB-to-Sata-controller bus the start sector numbers became multiples of 65535.

Where did this discrepancy come from?

Continue reading