Как дисковые контроллеры обрабатывают одновременную запись в один и тот же сектор при отсутствии барьеров записи?

Когда я открываю файл с помощью O_DIRECT|O_ASYNC и выполняю две одновременные записи в один и тот же сектор диска без промежуточной fsync или fdatasync, дает ли дисковая подсистема linux или аппаратные контроллеры диска какие-либо гарантии того, что окончательные данные в этом секторе диска будут сохранены? быть вторым писать?

Хотя верно то, что O_DIRECT обходит буферный кеш ОС, данные в конечном итоге попадают в очередь ввода-вывода низкого уровня (очередь планировщика диска, очередь драйвера диска, кеш/очереди аппаратного контроллера и т. д.). Я проследил весь стек ввода-вывода до алгоритма лифта.
Например, если следующая последовательность запросов попадает в очередь дискового планировщика

write sector 1 from buffer 1  
write sector 2 from buffer 2  
write sector 1 from buffer 3 [Its not buffer 1!!]  

код лифта выполнит «обратное слияние» для объединения секторов 1, 2 из буферов 1, 2 соответственно. А затем выдайте дисковые два дисковых ввода-вывода. Но я не уверен, что окончательные данные в секторе диска 1 взяты из буфера 1 или буфера 3 (поскольку я не знаю о семантике переупорядочения записи драйверов/контроллеров).

Сценарий 2:

write sector 1 from buffer 1  
write sector 500 from buffer 2
write sector 1 from buffer 3

Как будет обрабатываться этот сценарий? Более простой вопрос заключается в том, что при записи в режиме O_DIRECT с AIO может ли эта последовательность запросов оказаться в очереди планировщика диска при отсутствии явных барьеров записи? в тот же сектор приведет к тому, что последняя запись будет окончательной записью" ?
или это упорядочение недетерминированное [оставлено на милость контроллера диска/его кешей, которые переупорядочивают записи в пределах барьеров для оптимизации времени поиска]


person Tautology    schedule 30.11.2010    source источник


Ответы (2)


Барьеры уходят. Если вам требуется упорядочить перекрывающиеся записи, вы должны дождаться завершения первой, прежде чем запускать вторую. (Барьеры исчезают.)

В общем случае я считаю, что нет никакой гарантии. Конечный результат не является детерминированным с точки зрения приложения и зависит от времени, состояния хоста и устройства хранения и т. д.

Очередь запросов будет объединять запросы предсказуемым образом, но аппаратное обеспечение не требуется для обеспечения согласованных результатов для операций записи, которые одновременно находятся в очереди накопителя.

В зависимости от того, насколько быстрым является устройство хранения и насколько медленным является процессор хоста, вы не всегда можете гарантировать, что слияние произойдет в очереди запросов до того, как команды будут отправлены на устройство хранения.

К сожалению, мне не ясно, как приложения, использующие O_DIRECT (в отличие от файловых систем, непосредственно создающих биос), должны ждать завершения.

person Eric Seppanen    schedule 30.11.2010
comment
Что касается биоса, ядро ​​​​собирает и блокирует буферы, если они являются страницами буферного кэша (не принадлежащими приложению). Кроме того, я считаю, что IOMMU попросит процессор (семантически) установить для страницы значение NO ACCESS, пока это не будет сделано с помощью DMA. Иначе для нормальных mmaped пишет гонок целая куча. - person Tautology; 01.12.2010
comment
В любом случае для записи без mmaped это буферная копия в пространство ядра (буферы dma), AFAIK - person Tautology; 01.12.2010

Хорошо, запросы на запись попадают в очередь линейного лифта. На данный момент не имеет значения, пришли ли они из разных потоков. Такое же расположение может быть результатом того, что один поток выполняет три последовательных записи. Доверили бы вы свои файлы операционной системе или контроллеру, который каким-то произвольным образом переупорядочивает последовательную запись в один и тот же сектор? Я бы не стал, но могу ошибаться, конечно :)

person Nikolai Fetissov    schedule 30.11.2010
comment
На самом деле, аппаратное обеспечение не гарантирует упорядочение времени между операциями записи в один и тот же сектор, находящимися в очереди. Я нашел это довольно удивительным, но по крайней мере 3 хакера ядра на LSF 2010 согласились, что это так. Если файловая система заботится об этом, предполагается, что она ожидает завершения (хотя раньше она могла использовать барьеры). Предположительно, то же самое верно и для приложений, использующих O_DIRECT. Конечно, очередь запросов ядра, вероятно, объединит перекрывающиеся запросы до того, как они попадут в аппаратное обеспечение, поэтому такое поведение может быть трудно увидеть. - person Eric Seppanen; 01.12.2010