Disable use_atomic_flag by default
This commit is contained in:
+16
-9
@@ -682,7 +682,10 @@ with replicated pools and reach the best possible write performance.
|
|||||||
|
|
||||||
Default value is auto-detected during OSD initialization from
|
Default value is auto-detected during OSD initialization from
|
||||||
`/sys/block/xx/queue/atomic_write_max_bytes` or assumed to be 4096 bytes
|
`/sys/block/xx/queue/atomic_write_max_bytes` or assumed to be 4096 bytes
|
||||||
because all known disks support 4 KB atomic writes.
|
because all known disks support 4 KB atomic writes. Auto-detection is only used for
|
||||||
|
NVMe disks because SAS disks require the explicit WRITE ATOMIC command which requires
|
||||||
|
RWF_ATOMIC (see below [#use_atomic_flag]) but that flag works incorrectly in current
|
||||||
|
Linux versions.
|
||||||
|
|
||||||
You can also check if your NVMe drives support atomic writes by running
|
You can also check if your NVMe drives support atomic writes by running
|
||||||
the command `nvme id-ctrl /dev/nvme0n1 | grep awupf`. If the reported value,
|
the command `nvme id-ctrl /dev/nvme0n1 | grep awupf`. If the reported value,
|
||||||
@@ -697,12 +700,16 @@ reducing Write Amplification and improving write performance up to 2 times.
|
|||||||
|
|
||||||
- Type: boolean
|
- Type: boolean
|
||||||
|
|
||||||
This option controls whether the Vitastor OSD uses RWF_ATOMIC write flag with atomic
|
This option controls whether Vitastor OSDs use RWF_ATOMIC write flag with atomic writes.
|
||||||
writes. This flag is only supported on Linux kernel since 6.11. Atomic writes are
|
This flag is supported since Linux 6.11 and adds some safety to atomic writes - the kernel
|
||||||
generally only safe to use with this flag because it tells the kernel to never fragment
|
guarantees to not fragment write requests with it and also to check them against the actual
|
||||||
write requests and also to check the write against the actual atomic write capabilities
|
device atomic write capabilities.
|
||||||
of the device.
|
|
||||||
|
|
||||||
This option is enabled by default when atomic_write_size is set to a value larger than 4 KB.
|
However, the option is disabled by default because the flag is currently UNUSABLE - Linux
|
||||||
You can disable it if you're sure that your disks support atomic writes and you want to
|
incorrectly requires writes with that flag to be of power-of-2 length and length-aligned.
|
||||||
bypass the Linux atomic write checks.
|
I.e., for example, 12 KB writes and not-8-KB aligned 8 KB writes are forbidden by the kernel,
|
||||||
|
even though the NVMe specification allows them.
|
||||||
|
|
||||||
|
For NVMe disks with `scheduler=none` writes aren't fragmented anyway so it's not a big deal.
|
||||||
|
However, you can rebuild your kernel with [this patch](../../patches/linux-fix-atomic-write-checks.diff)
|
||||||
|
and turn this option on. It will make your atomic writes a bit safer.
|
||||||
|
|||||||
+15
-7
@@ -717,6 +717,9 @@ pg_minsize OSD во время переключений, что может по
|
|||||||
Значение по умолчанию авто-определяется во время инициализации OSD из
|
Значение по умолчанию авто-определяется во время инициализации OSD из
|
||||||
`/sys/block/xx/queue/atomic_write_max_bytes` либо принимается равным 4096,
|
`/sys/block/xx/queue/atomic_write_max_bytes` либо принимается равным 4096,
|
||||||
так как все известные диски поддерживают атомарную запись 4 КБ блоков.
|
так как все известные диски поддерживают атомарную запись 4 КБ блоков.
|
||||||
|
Автоопределение применяется только для NVMe-дисков, так как SAS диски требуют
|
||||||
|
использования отдельной команды WRITE ATOMIC, а для неё нужен флаг RWF_ATOMIC
|
||||||
|
(см. ниже [#use_atomic_flag]), а он в текущих версиях Linux работает некорректно.
|
||||||
|
|
||||||
Вы также можете проверить, поддерживают ли ваши NVMe-диски атомарную запись,
|
Вы также можете проверить, поддерживают ли ваши NVMe-диски атомарную запись,
|
||||||
с помощью команды `nvme id-ctrl /dev/nvme0n1 | grep awupf`. Если значение awupf
|
с помощью команды `nvme id-ctrl /dev/nvme0n1 | grep awupf`. Если значение awupf
|
||||||
@@ -735,11 +738,16 @@ pg_minsize OSD во время переключений, что может по
|
|||||||
- Тип: булево (да/нет)
|
- Тип: булево (да/нет)
|
||||||
|
|
||||||
Данная опция контролирует использование Vitastor OSD флага RWF_ATOMIC при атомарной записи
|
Данная опция контролирует использование Vitastor OSD флага RWF_ATOMIC при атомарной записи
|
||||||
блоков. Этот флаг поддерживается только в ядрах Linux начиная с 6.11. Атомарная запись
|
блоков. Этот флаг поддерживается, начиная с версии ядра Linux 6.11 и добавляет немного корректности
|
||||||
является безопасной только при использовании этого флага, так как он сообщает ядру о том,
|
атомарным записям - ядро гарантирует отсутствие фрагментации запросов записи с этим флагом и
|
||||||
что запрос записи нельзя фрагментировать и о том, что запрос нужно проверить на соответствие
|
проверяет их на соответствие реальным возможностям устройства.
|
||||||
реальным возможностям атомарной записи устройства.
|
|
||||||
|
|
||||||
Опция включается по умолчанию, когда atomic_write_size устанавливается в значение больше 4 КБ.
|
Однако, данная опция по умолчанию отключена, так как флаг в текущих версиях Linux работает
|
||||||
Вы можете явно отключить её, если уверены, что ваши диски поддерживают атомарную запись и
|
абсолютно НЕКОРРЕКТНО - при нём Linux требует, чтобы запросы записи имели длину, равную
|
||||||
хотите обойти проверки уровня ядра.
|
степени двойки и были выровнены на эту длину. То есть, например, 12 КБ запросы записи, а также
|
||||||
|
8 КБ запросы записи по не-кратному 8 КБ смещению запрещаются ядром, хотя спецификация NVMe их
|
||||||
|
разрешает.
|
||||||
|
|
||||||
|
Для NVMe-дисков с `scheduler=none` запросы записи и так не фрагментируются, так что это не так
|
||||||
|
уж и важно, однако вы можете пересобрать своё ядро с [этим патчем](../../patches/linux-fix-atomic-write-checks.diff)
|
||||||
|
и включить данную опцию. Это сделает вашу атомарную запись капельку безопаснее.
|
||||||
|
|||||||
+31
-16
@@ -813,7 +813,10 @@
|
|||||||
|
|
||||||
Default value is auto-detected during OSD initialization from
|
Default value is auto-detected during OSD initialization from
|
||||||
`/sys/block/xx/queue/atomic_write_max_bytes` or assumed to be 4096 bytes
|
`/sys/block/xx/queue/atomic_write_max_bytes` or assumed to be 4096 bytes
|
||||||
because all known disks support 4 KB atomic writes.
|
because all known disks support 4 KB atomic writes. Auto-detection is only used for
|
||||||
|
NVMe disks because SAS disks require the explicit WRITE ATOMIC command which requires
|
||||||
|
RWF_ATOMIC (see below [#use_atomic_flag]) but that flag works incorrectly in current
|
||||||
|
Linux versions.
|
||||||
|
|
||||||
You can also check if your NVMe drives support atomic writes by running
|
You can also check if your NVMe drives support atomic writes by running
|
||||||
the command `nvme id-ctrl /dev/nvme0n1 | grep awupf`. If the reported value,
|
the command `nvme id-ctrl /dev/nvme0n1 | grep awupf`. If the reported value,
|
||||||
@@ -834,6 +837,9 @@
|
|||||||
Значение по умолчанию авто-определяется во время инициализации OSD из
|
Значение по умолчанию авто-определяется во время инициализации OSD из
|
||||||
`/sys/block/xx/queue/atomic_write_max_bytes` либо принимается равным 4096,
|
`/sys/block/xx/queue/atomic_write_max_bytes` либо принимается равным 4096,
|
||||||
так как все известные диски поддерживают атомарную запись 4 КБ блоков.
|
так как все известные диски поддерживают атомарную запись 4 КБ блоков.
|
||||||
|
Автоопределение применяется только для NVMe-дисков, так как SAS диски требуют
|
||||||
|
использования отдельной команды WRITE ATOMIC, а для неё нужен флаг RWF_ATOMIC
|
||||||
|
(см. ниже [#use_atomic_flag]), а он в текущих версиях Linux работает некорректно.
|
||||||
|
|
||||||
Вы также можете проверить, поддерживают ли ваши NVMe-диски атомарную запись,
|
Вы также можете проверить, поддерживают ли ваши NVMe-диски атомарную запись,
|
||||||
с помощью команды `nvme id-ctrl /dev/nvme0n1 | grep awupf`. Если значение awupf
|
с помощью команды `nvme id-ctrl /dev/nvme0n1 | grep awupf`. Если значение awupf
|
||||||
@@ -849,22 +855,31 @@
|
|||||||
- name: use_atomic_flag
|
- name: use_atomic_flag
|
||||||
type: bool
|
type: bool
|
||||||
info: |
|
info: |
|
||||||
This option controls whether the Vitastor OSD uses RWF_ATOMIC write flag with atomic
|
This option controls whether Vitastor OSDs use RWF_ATOMIC write flag with atomic writes.
|
||||||
writes. This flag is only supported on Linux kernel since 6.11. Atomic writes are
|
This flag is supported since Linux 6.11 and adds some safety to atomic writes - the kernel
|
||||||
generally only safe to use with this flag because it tells the kernel to never fragment
|
guarantees to not fragment write requests with it and also to check them against the actual
|
||||||
write requests and also to check the write against the actual atomic write capabilities
|
device atomic write capabilities.
|
||||||
of the device.
|
|
||||||
|
|
||||||
This option is enabled by default when atomic_write_size is set to a value larger than 4 KB.
|
However, the option is disabled by default because the flag is currently UNUSABLE - Linux
|
||||||
You can disable it if you're sure that your disks support atomic writes and you want to
|
incorrectly requires writes with that flag to be of power-of-2 length and length-aligned.
|
||||||
bypass the Linux atomic write checks.
|
I.e., for example, 12 KB writes and not-8-KB aligned 8 KB writes are forbidden by the kernel,
|
||||||
|
even though the NVMe specification allows them.
|
||||||
|
|
||||||
|
For NVMe disks with `scheduler=none` writes aren't fragmented anyway so it's not a big deal.
|
||||||
|
However, you can rebuild your kernel with [this patch](../../patches/linux-fix-atomic-write-checks.diff)
|
||||||
|
and turn this option on. It will make your atomic writes a bit safer.
|
||||||
info_ru: |
|
info_ru: |
|
||||||
Данная опция контролирует использование Vitastor OSD флага RWF_ATOMIC при атомарной записи
|
Данная опция контролирует использование Vitastor OSD флага RWF_ATOMIC при атомарной записи
|
||||||
блоков. Этот флаг поддерживается только в ядрах Linux начиная с 6.11. Атомарная запись
|
блоков. Этот флаг поддерживается, начиная с версии ядра Linux 6.11 и добавляет немного корректности
|
||||||
является безопасной только при использовании этого флага, так как он сообщает ядру о том,
|
атомарным записям - ядро гарантирует отсутствие фрагментации запросов записи с этим флагом и
|
||||||
что запрос записи нельзя фрагментировать и о том, что запрос нужно проверить на соответствие
|
проверяет их на соответствие реальным возможностям устройства.
|
||||||
реальным возможностям атомарной записи устройства.
|
|
||||||
|
|
||||||
Опция включается по умолчанию, когда atomic_write_size устанавливается в значение больше 4 КБ.
|
Однако, данная опция по умолчанию отключена, так как флаг в текущих версиях Linux работает
|
||||||
Вы можете явно отключить её, если уверены, что ваши диски поддерживают атомарную запись и
|
абсолютно НЕКОРРЕКТНО - при нём Linux требует, чтобы запросы записи имели длину, равную
|
||||||
хотите обойти проверки уровня ядра.
|
степени двойки и были выровнены на эту длину. То есть, например, 12 КБ запросы записи, а также
|
||||||
|
8 КБ запросы записи по не-кратному 8 КБ смещению запрещаются ядром, хотя спецификация NVMe их
|
||||||
|
разрешает.
|
||||||
|
|
||||||
|
Для NVMe-дисков с `scheduler=none` запросы записи и так не фрагментируются, так что это не так
|
||||||
|
уж и важно, однако вы можете пересобрать своё ядро с [этим патчем](../../patches/linux-fix-atomic-write-checks.diff)
|
||||||
|
и включить данную опцию. Это сделает вашу атомарную запись капельку безопаснее.
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
From 98d3f68a40130c438854f61db6025f9e9b099cb6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Vitaliy Filippov <vitalifster@gmail.com>
|
||||||
|
Date: Sat, 20 Dec 2025 14:44:35 +0300
|
||||||
|
Subject: [PATCH] Do not require atomic writes to be power of 2 sized and
|
||||||
|
aligned on length boundary
|
||||||
|
|
||||||
|
It contradicts NVMe specification where alignment is only required when atomic
|
||||||
|
write boundary (NABSPF/NABO) is set and highly limits usage of NVMe atomic writes
|
||||||
|
|
||||||
|
Signed-off-by: Vitaliy Filippov <vitalifster@gmail.com>
|
||||||
|
---
|
||||||
|
fs/read_write.c | 8 --------
|
||||||
|
1 file changed, 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/fs/read_write.c b/fs/read_write.c
|
||||||
|
index 833bae068770..5467d710108d 100644
|
||||||
|
--- a/fs/read_write.c
|
||||||
|
+++ b/fs/read_write.c
|
||||||
|
@@ -1802,17 +1802,9 @@ int generic_file_rw_checks(struct file *file_in, struct file *file_out)
|
||||||
|
|
||||||
|
int generic_atomic_write_valid(struct kiocb *iocb, struct iov_iter *iter)
|
||||||
|
{
|
||||||
|
- size_t len = iov_iter_count(iter);
|
||||||
|
-
|
||||||
|
if (!iter_is_ubuf(iter))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- if (!is_power_of_2(len))
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
- if (!IS_ALIGNED(iocb->ki_pos, len))
|
||||||
|
- return -EINVAL;
|
||||||
|
-
|
||||||
|
if (!(iocb->ki_flags & IOCB_DIRECT))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.51.0
|
||||||
|
|
||||||
@@ -88,6 +88,7 @@ struct disk_tool_t
|
|||||||
uint32_t new_meta_format = 0;
|
uint32_t new_meta_format = 0;
|
||||||
int new_journal_fd = -1, new_meta_fd = -1;
|
int new_journal_fd = -1, new_meta_fd = -1;
|
||||||
resizer_data_moving_t *moving_blocks = NULL;
|
resizer_data_moving_t *moving_blocks = NULL;
|
||||||
|
bool atomic_warned = false;
|
||||||
|
|
||||||
bool started = false;
|
bool started = false;
|
||||||
void *small_write_data = NULL;
|
void *small_write_data = NULL;
|
||||||
|
|||||||
@@ -91,21 +91,24 @@ int disk_tool_t::prepare_one(std::map<std::string, std::string> options, int is_
|
|||||||
if (options.find("atomic_write_size") == options.end())
|
if (options.find("atomic_write_size") == options.end())
|
||||||
{
|
{
|
||||||
auto data_dev = realpath_str(options["data_device"], false);
|
auto data_dev = realpath_str(options["data_device"], false);
|
||||||
uint64_t atomic_write_size = get_atomic_write_size(data_dev);
|
if (data_dev.substr(0, 9) == "/dev/nvme")
|
||||||
if (atomic_write_size > 4096)
|
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Data device %s supports atomic writes up to %ju bytes, enabling. Enjoy faster writes!\n",
|
uint64_t atomic_write_size = get_atomic_write_size(data_dev);
|
||||||
data_dev.c_str(), atomic_write_size);
|
if (atomic_write_size > 4096)
|
||||||
options["atomic_write_size"] = std::to_string(atomic_write_size);
|
{
|
||||||
options["use_atomic_flag"] = "1";
|
// FIXME: Enable use_atomic_flag when the kernel does checks correctly
|
||||||
|
fprintf(stderr, "Data device %s supports atomic writes up to %ju bytes, enabling. Enjoy faster writes!\n",
|
||||||
|
data_dev.c_str(), atomic_write_size);
|
||||||
|
options["atomic_write_size"] = std::to_string(atomic_write_size);
|
||||||
|
if (!atomic_warned)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "WARNING: RWF_ATOMIC can't be used because Linux checks atomic writes incorrectly.\n"
|
||||||
|
" Please don't change scheduler from default 'none' and check use_atomic_flag documentation for more details.\n");
|
||||||
|
atomic_warned = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (options.find("use_atomic_flag") == options.end() &&
|
|
||||||
parse_size(options["atomic_write_size"]) > 4096)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Atomic writes larger than 4 KB are enabled manually, enabling use_atomic_flag too.\n");
|
|
||||||
options["use_atomic_flag"] = "1";
|
|
||||||
}
|
|
||||||
for (auto dev: std::vector<std::string>{"data", "meta", "journal"})
|
for (auto dev: std::vector<std::string>{"data", "meta", "journal"})
|
||||||
{
|
{
|
||||||
if (options[dev+"_device"] != "" && options["disable_"+dev+"_fsync"] == "auto")
|
if (options[dev+"_device"] != "" && options["disable_"+dev+"_fsync"] == "auto")
|
||||||
|
|||||||
Reference in New Issue
Block a user