NVMe physical block size

Aus Thomas-Krenn-Wiki
Zur Navigation springen Zur Suche springen

SSDs speichern Daten in Speicherzellen, die in Pages zusammengefasst sind. Mehrere Pages bilden wiederum einen Block. Im Gegensatz zu Festplatten weisen SSDs daher keine physical_block_size aus. Der Linux Kernel berechnet seit Kernel Version 5.3 daher die physical_block_size aufgrund anderer Parameter.

Berechnung der physical_block_size im Linux Kernel

Seit Linux Kernel Version 5.3 wird die physical_block_size von NVMe SSDs im Linux Kernel folgendermaßen berechnet:[1]

  1. Zu Beginn gilt:
    phys_bs = logical_block_size
    512 Byte oder 4.096 Byte - je nachdem, welche Block Größe der Default-Namespace einer SSD hat bzw. mit welcher Block Größe der Namespace formatiert wurde.
  2. Wenn für den betroffenden Namespace der NVMe eine NPGW (Namespace Preferred Write Granularity) definiert ist, wird phys_bs entsprechend auf ein Vielfaches erhöht:
    phys_bs = (1 + NPWG) * logical_block_size
  3. Zusätzlich wird die atomic_bs (atomare Block Größe, die während eines Stromausfalles noch garantiert atomar geschrieben werden kann) ermittelt.
  4. Linux-Dateisysteme gehen davon aus, dass das Schreiben eines einzelnen physischen Blocks (physical_block_size) ein atomarer Vorgang ist. Daher wird zur Absicherung für physical_block_size der kleinere der beiden Werte (phys_bs, atomic_bs) verwendet:
    physical_block_size = min(phys_bs, atomic_bs)

Berechnung im Detail

Die folgenden Informationen erläutern noch im Detail die Berechnung.

atomic_bs

Definitionen:[2]

  • Namespace Features (NSFEAT):
    • Bit 1 (NSABP), wenn auf '1' gesetzt, zeigt an, dass die Felder NAWUN, NAWUPF und NACWU für diesen Namensraum definiert sind und vom Host für diesen Namensraum anstelle der Felder AWUN, AWUPF und ACWU in der Datenstruktur "Identify Controller" verwendet werden sollten. Wird dieser Wert auf '0' zurückgesetzt, unterstützt der Controller die Felder NAWUN, NAWUPF und NACWU für diesen Namensraum nicht. In diesem Fall sollte der Host die Felder AWUN, AWUPF und ACWU verwenden.
  • Namespace Atomic Boundary Offset (NABO)
    Dieses Feld gibt die LBA in diesem Namensraum an, an der die erste atomare Grenze beginnt. Typischerweise verweist NABO auf die LBA Adresse 0.
  • Namespace Atomic Write Unit Power Fail (NAWUPF) (≥ AWUPF)
    Dieses Feld gibt die namensraumspezifische Größe des Schreibvorgangs an, der während eines Stromausfalls oder einer Fehlerbedingung garantiert atomar in den NVM geschrieben wird. Wenn das NSABP-Bit auf '0' gesetzt ist, ist dieses Feld reserviert.
    Ein Wert von 0h bedeutet, dass die Größe für diesen Namensraum dieselbe ist wie die im Feld AWUPF der Datenstruktur Identify Controller angegebene. Alle anderen Werte geben die Größe in Form von logischen Blöcken an, wobei die gleiche Kodierung wie im AWUPF-Feld verwendet wird.
  • Atomic Write Unit Power Fail (AWUPF)
    Dieses Feld gibt die Größe des Schreibvorgangs an, der während eines Stromausfalls oder einer Fehlerbedingung garantiert atomar in den NVM über alle Namespaces mit einem beliebigen unterstützten Namespace-Format geschrieben wird.
    Wenn ein bestimmter Namespace eine größere Größe garantiert als in diesem Feld angegeben, wird diese namespacespezifische Größe im Feld NAWUPF in der Datenstruktur Identify Namespace angegeben.
    Dieses Feld wird in logischen Blöcken angegeben und ist ein 0-basierter Wert. Der AWUPF-Wert muss kleiner als oder gleich dem AWUN-Wert sein.
    Wenn ein Schreibbefehl mit einer Größe kleiner oder gleich dem AWUPF-Wert übermittelt wird, ist dem Host garantiert, dass der Schreibvorgang im NVM in Bezug auf andere Lese- oder Schreibbefehle atomar ist. Wird ein Schreibbefehl übermittelt, der größer als diese Größe ist, gibt es keine Garantie für die Atomarität des Befehls. Wenn die Schreibgröße kleiner oder gleich dem AWUPF-Wert ist und der Schreibbefehl fehlschlägt, geben nachfolgende Lesebefehle für die zugehörigen logischen Blöcke die Daten des vorherigen erfolgreichen Schreibbefehls zurück. Wenn ein Schreibbefehl mit einer Größe größer als der AWUPF-Wert übermittelt wird, gibt es keine Garantie dafür, dass bei nachfolgenden Lesebefehlen für die zugehörigen logischen Blöcke Daten zurückgegeben werden.

Berechnung:

  1. Standarmäßig ist atomic_bs = bs
  2. Wenn NABO den Wert 0 hat und
    1. wenn das NSABP Bit gesetzt ist und NAWUPF > 1 beträgt, gilt: atomic_bs = (1 + NAWUP) * bs,
    2. ansonsten gilt: atomic_bs = (1 + AWUPF) * bs

phys_bs

Definitionen:[2]

  • Namespace Features (NSFEAT):
    Bit 4 (OPTPERF), wenn auf '1' gesetzt, zeigt an, dass die Felder NPWG, NPWA, NPDG, NPDA und NOWS für diesen Namensraum definiert sind und vom Host für die E/A-Optimierung verwendet werden sollten. Ist der Wert '0', so unterstützt die NVMe SSD die Felder NPWG, NPWA, NPDG, NPDA und NOWS für diesen Namensraum nicht.
  • Namespace Preferred Write Granularity (NPWG)
    Dieses Feld gibt die kleinste empfohlene Schreibgranularität in logischen Blöcken für diesen Namespace an. Es handelt sich um einen 0-basierten Wert. Wenn das OPTPERF-Bit auf "0" gesetzt ist, ist dieses Feld reserviert. Die angegebene Größe sollte kleiner oder gleich der maximalen Datenübertragungsgröße (MDTS) sein, die in Einheiten der minimalen Speicherseitengröße angegeben ist. Der Wert dieses Feldes kann sich ändern, wenn der Namespace neu formatiert wird. Die Größe sollte ein Vielfaches von Namespace Preferred Write Alignment (NPWA) sein.

Berechnung:

  1. Standarmäßig ist phys_bs = bs
  2. Wenn OPTPERF den Wert 1 hat gilt: phys_bs = (1 + NPWG) * bs

Beispiel einer NVMe SSD

Das folgende Beispiel zeigt eine Micron 7450 Pro M.2 SSD mit einer logischen Blockgröße von 512 Byte und Firmware E2MU200 (ältere Versionen meldeten größere Werte für NPWG):[3]

root@ubuntu2204:~# nvme list
Node                  SN                   Model                                    Namespace Usage                      Format           FW Rev
--------------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1          22503FB3D7CE         Micron_7450_MTFDKBA960TFR                1           0,00   B / 960,20  GB    512   B +  0 B   E2MU200
root@ubuntu2204:~# cat /sys/devices/pci0000:00/0000:00:1c.0/0000:01:00.0/nvme/nvme0/nvme0n1/queue/physical_block_size
4096
root@ubuntu2204:~# cat /sys/devices/pci0000:00/0000:00:1c.0/0000:01:00.0/nvme/nvme0/nvme0n1/queue/logical_block_size
512
root@ubuntu2204:~# nvme id-ns -H /dev/nvme0n1 |grep -i NAWUPF
  [1:1] : 0x1   Namespace uses NAWUN, NAWUPF, and NACWU
nawupf  : 511
root@ubuntu2204:~# nvme id-ctrl -H /dev/nvme0 |grep -i AWUPF
awupf     : 63
root@ubuntu2204:~# nvme id-ns -H /dev/nvme0n1 |grep -i NPWG
  [4:4] : 0x1   NPWG, NPWA, NPDG, NPDA, and NOWS are Supported
npwg    : 7

Das folgende Beispiel zeigt eine Micron 7450 Max U.2 SSD mit einer logischen Blockgröße von 4.096 Byte und Firmware E2MU200:

root@ubuntu2204:~# nvme list
Node                  SN                   Model                                    Namespace Usage                      Format           FW Rev
--------------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
[...]
/dev/nvme1n1          22323B6AC5C5         Micron_7450_MTFDKCC3T2TFS                1         977,32  MB /   3,20  TB      4 KiB +  0 B   E2MU200
root@ubuntu2204:~# cat /sys/devices/pci0000:5d/0000:5d:01.0/0000:5e:00.0/nvme/nvme1/nvme1n1/queue/physical_block_size
4096
root@ubuntu2204:~# cat /sys/devices/pci0000:5d/0000:5d:01.0/0000:5e:00.0/nvme/nvme1/nvme1n1/queue/logical_block_size
4096
root@ubuntu2204:~# nvme id-ns -H /dev/nvme1n1 |grep -i NAWUPF
  [1:1] : 0x1   Namespace uses NAWUN, NAWUPF, and NACWU
nawupf  : 63
root@ubuntu2204:~# nvme id-ctrl -H /dev/nvme1 |grep -i AWUPF
awupf     : 63
root@ubuntu2204:~# nvme id-ns -H /dev/nvme1n1 |grep -i NPWG
  [4:4] : 0x1   NPWG, NPWA, NPDG, NPDA, and NOWS are Supported
npwg    : 0

Weitere Informationen

Einzelnachweise

  1. nvme: set physical block size and optimal I/O size (git.kernel.org, Bart Van Assche, 28.06.2019)
  2. 2,0 2,1 NVM Command Set Specification (nvmexpress.org, 03.10.2022) Revision 1.0c
  3. ashift=18 needed for NVMe with physical block size 256k (github.com/openzfs/zfs/issues)


Foto Werner Fischer.jpg

Autor: Werner Fischer

Werner Fischer arbeitet im Product Management Team von Thomas-Krenn. Er evaluiert dabei neueste Technologien und teilt sein Wissen in Fachartikeln, bei Konferenzen und im Thomas-Krenn Wiki. Bereits 2005 - ein Jahr nach seinem Abschluss des Studiums zu Computer- und Mediensicherheit an der FH Hagenberg - heuerte er beim bayerischen Server-Hersteller an. Als Öffi-Fan nutzt er gerne Bus & Bahn und genießt seinen morgendlichen Spaziergang ins Büro.


Das könnte Sie auch interessieren

ISCSI Multipathing unter Linux
Linux Storage Stack Diagramm
Windows Passwort löschen - Kennwortsperre umgehen unter Windows 10