LINUX.ORG.RU

Ядро неверно определяет TRIM granularity (erase unit size)

 , ,


0

3

Доброе утро, господа.

Дано:

  • SATA SSD, одна штука (эффект наблюдается как минимум на OCZ Vertex 4 и LSS-16L6G, но, думаю, модель не имеет значения);
  • любое ядро Linux вплоть до 4.0-rcчтототам.

Наблюдаем:

$ lsblk -D /dev/disk/by-id/ata-LITEONIT_LSS-16L6G_S0C41154Z1ZSCA185984
NAME   DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sdb           0      512B       2G         0
├─sdb1        0      512B       2G         0
├─sdb2        0      512B       2G         0
└─sdb3        0      512B       2G         0

# hdparm -I /dev/disk/by-id/ata-LITEONIT_LSS-16L6G_S0C41154Z1ZSCA185984 | grep TRIM
	   *	Data Set Management TRIM supported (limit 8 blocks)
	   *	Deterministic read ZEROs after TRIM

Первая утилита забирает данные из /sys/block/sdX/queue (куда они помещаются драйвером дискового контроллера в ядре), вторая (AFAIK) — опрашивает контроллер напрямую.

Что не так:

Значения DISC-GRAN (размер erase unit'а) и DISC-ZERO должны быть равны 4K и 1 соответственно. Получается, что ядро не в состоянии узнать эти данные, хотя они на самом деле доступны (через другой интерфейс, видимо).

Вопрос:

Багу не нашёл, зарепортил. У кого-нибудь ещё такое наблюдается? Есть ли здесь специалисты по всему по ведру и разнообразным ATA, которые могут сказать, чем hdparm отличается от ядерного драйвера (и хотя бы примерно указать, куда копать)? Писать код руками умею, если что.

★★★★★

Последнее исправление: intelfx (всего исправлений: 5)

$ lsblk -D /dev/disk/by-id/ata-Samsung_SSD_840_PRO_Series_
NAME   DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda           0      512B       2G         1
├─sda1        0      512B       2G         1
├─sda2        0      512B       2G         1
└─sda3        0      512B       2G         1


# hdparm -I /dev/disk/by-id/ata-Samsung_SSD_840_PRO_Series_ | grep TRIM
           *    Data Set Management TRIM supported (limit 8 blocks)
           *    Deterministic read ZEROs after TRIM
surefire ★★★
()

В чем проблема? TRIM не работает?

А если работает, то пофиг на эти неувязки. IMHO это прблемы контроллера как отметить свободные области.

vel ★★★★★
()
Ответ на: комментарий от vel

Это можно назвать «TRIM не работает», да.

К примеру, у нас в reiser4 есть такая хрень, как precise discard. Это когда при деаллокации блоков драйвер ФС не пытается тупо оттримить деаллоцированный отрезок, а смотрит по бокам до границ erase unit'а и округляет до ближайших границ. А без информации о размере erase unit'а этот механизм не работает.

intelfx ★★★★★
() автор топика
Ответ на: комментарий от vel

Поясню, зачем это вообще нужно.

Допустим, у нас реальная гранулярность TRIM'а — 8 секторов. Это означает, что контроллер будет отбрасывать все те запросы, которые не покрывают хотя бы один (должным образом выровненный) блок из 8 секторов. Теперь представим, что мы подряд удаляем восемь мелких файлов, каждый из которых занимает по одному сектору. Допустим также, что они идут строго друг за другом и в сумме образуют как раз один такой восьмисекторный блок.

Так вот, любая другая ФС сгенерит восемь последовательных запросов на TRIM, каждый размером в один сектор. В результате ни один из этих запросов не возымеет никакого действия, и мы получим восемь секторов мусора, для уборки которого потребуется сделать fstrim. В случае же reiser4 последняя операция удаления (вне зависимости от их взаимного порядка) породит один TRIM-запрос в восемь секторов, который дойдёт до железа и сработает.

Думаю, теперь понятно, почему корректная информация о гранулярности важна.

Более того, даже в случае любой другой ФС отсутствие этой информации активно вредит. Дело в том, что вплоть до последней ревизии SATA каждый TRIM-запрос должен посылаться при пустой очереди. При этом ядро отфильтровывает те запросы, которые заведомо не сработают (== не покрывают ни один erase unit), чтобы не устраивать в очереди барьеры почём зря. Соответственно, если у ядра нет корректной информации о гранулярности TRIM, этот механизм также не работает (ядро по умолчанию считает каждый запрос корректным).

Так что это реальный баг, который действительно ухудшает производительность.

intelfx ★★★★★
() автор топика
Ответ на: комментарий от intelfx

IMHO «fstrim наше все.» & «discard - ненужно/вредно»

Ты проверял, или теоретизируешь? Сначала нужно убедиться, что оно действительно не работает.

1) Контроллеры в ssd слишком умные. Часть из них делает трим не по запросу, а когда это возможно по их меркам.

2) думаю, что если бы эта проблема была реальной, то ее бы давно подняли раньше.

3) mke2fs на ssd делает TRIM.

4) проблемы reiserfs* не интересуют.

vel ★★★★★
()
Ответ на: комментарий от vel

Ты проверял, или теоретизируешь? Сначала нужно убедиться, что оно действительно не работает.

Смотря что.

  • Неработоспособность TRIM на диапазонах < 8 секторов таки да, проверял (hdparm --read-sector, надеюсь, считается).
  • Выигрыш в производительности от указания корректного granularity ввиду меньшего забития очередей — не проверял (не на чем — не знаю, как форсировать granularity).

Контроллеры в ssd слишком умные. Часть из них делает трим не по запросу, а когда это возможно по их меркам.

Это не важно. Даже если там «бит отложенного трима» или что-то более умное. Если указана гранулярность в 8 секторов — значит, там один «бит отложенного трима» на 8 секторов.

думаю, что если бы эта проблема была реальной, то ее бы давно подняли раньше.

Не аргумент.

mke2fs на ssd делает TRIM.

И что? Мы вообще-то говорим о TRIM/discard в процессе работы ФС, а не об очистке раздела при создании.

проблемы reiserfs* не интересуют.

Ты точно читал мои ответы? Перечитай ещё раз. Я утверждаю, что у reiser4 есть преимущество перед всеми существующими ФС, но оно требует корректных данных гранулярности.

intelfx ★★★★★
() автор топика
Ответ на: комментарий от intelfx

Неработоспособность TRIM на диапазонах < 8 секторов таки да, проверял (hdparm --read-sector, надеюсь, считается).

Печально, придется переходить на интелы. Похоже проблема появилась с приходом новых ssd

hdparm -I /dev/disk/by-id/ata-INTEL_SSDSC2CW120A3_CVCV3034071A120BGN | grep TRIM
           *    Data Set Management TRIM supported (limit 1 block)
           *    Deterministic read data after TRIM
hdparm -I /dev/disk/by-id/ata-OCZ-VERTEX3_OCZ-X5UX3EIKB5310OQ8 | grep TRIM
           *    Data Set Management TRIM supported (limit 1 block)
           *    Deterministic read data after TRIM
hdparm  -I /dev/disk/by-id/ata-Samsung_SSD_840_PRO_Series_S1ANNSADB52865F  | grep -i trim
           *    Data Set Management TRIM supported (limit 8 blocks)
           *    Deterministic read ZEROs after TRIM
hdparm -I /dev/disk/by-id/ata-OCZ-VERTEX4_OCZ-JF3915MUFZL107M6 | grep TRIM
           *    Data Set Management TRIM supported (limit 16 blocks)

Я никогда не пробовал писать в bugzilla.kernel.org. Через mailing-lists на vger.kernel.org в прошлом году пропихивал патчик.

В linux-ide@vger.kernel.org нужно идти. Там как раз недавно обсуждали проблемы с trim у samsung 850pro

vel ★★★★★
()
Ответ на: комментарий от vel

А вот вопрос — у интелов реально TRIM с гранулярностью в один сектор, или просто они даже через этот (hdparm'овский) интерфейс отвечают хрень?

В linux-ide@vger.kernel.org нужно идти.

Точно IDE? А то я в «Serial ATA» баг запостил...

intelfx ★★★★★
() автор топика
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

Неработоспособность TRIM на диапазонах < 8 секторов таки да, проверял (hdparm --read-sector, надеюсь, считается).

Кстати как им проверять, если discard_zeroes_data != 1?

vasily_pupkin ★★★★★
()
Ответ на: комментарий от vasily_pupkin

Ну вот у меня == 1, а если ноль, то хз =)

intelfx ★★★★★
() автор топика
Ответ на: комментарий от vasily_pupkin

Исходя из моих экспериментов, там (на askubuntu) сказано некорректно и это именно что гранулярность. Формулировка «limit», конечно, странная, но де факто на двух указанных в ОП моделях TRIM не срабатывает, пока размер экстента меньше этого limit'а.

intelfx ★★★★★
() автор топика
Последнее исправление: intelfx (всего исправлений: 2)
Ответ на: комментарий от vasily_pupkin

Посмотрел в код hdparm и стандарт ACS-3 — и действительно, 105-е слово результата ATA IDENTIFY не имеет никакого отношения к гранулярности. Выходит, зарепорченный баг можно закрывать как invalid.

Но совпадение очень интересное: на двух разных SSD с двумя разными значениями этого самого limit (8 и 16) наблюдаемая гранулярность TRIM'а совпадает со значением limit.

intelfx ★★★★★
() автор топика
Последнее исправление: intelfx (всего исправлений: 1)
Ответ на: комментарий от intelfx

В linux-ide@vger.kernel.org нужно идти.

Точно IDE? А то я в «Serial ATA» баг запостил...

Ну, я погрепал в MAINTAINERS drivers/ata

SERIAL ATA (SATA) SUBSYSTEM
M:      Tejun Heo <tj@kernel.org>
L:      linux-ide@vger.kernel.org
T:      git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
S:      Supported
F:      drivers/ata/
F:      include/linux/ata.h
F:      include/linux/libata.h

Но совпадение очень интересное: на двух разных SSD с двумя разными значениями этого самого limit (8 и 16) наблюдаемая гранулярность TRIM'а совпадает со значением limit.

Я думаю, что задав этот вопрос в linux-ide@vger.kernel.org можно будет получить разъяснения.

vel ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.