Что такое использование blk_queue_segment_boundary()

Книга ldd говорит для функции blk_queue_segment_boundary() следующим образом:

Некоторые устройства не могут обрабатывать запросы, которые пересекают границы памяти определенного размера; если ваше устройство является одним из таких, используйте эту функцию, чтобы сообщить ядру об этой границе. Например, если ваше устройство имеет проблемы с запросами, которые пересекают границу 4 МБ, передайте маску 0x3fffff. Маска по умолчанию - 0xffffffff.

Я не совсем понимаю, что здесь означает граница, например, у меня есть виртуальное блочное устройство, которое действительно состоит из файлов 4 МБ, поэтому я хочу, чтобы запрос не превышал границы 4 МБ,

unsigned long sector = blk_rq_pos(req);
unsigned long offset = sector << 9;
unsigned long nbytes = blk_rq_bytes(req);

int file_offset = offset % (1 << 22);

Я хочу, чтобы (file_offset + nbytes) не превышало 4M, но иногда оно превышает 4M, поэтому есть ли какое-то недопонимание в blk_queue_segment_boundary()?

1 ответ

Решение

Некоторые контроллеры (в частности IDE) не могут обрабатывать запросы DMA, которые пересекают области памяти на 4 МБ. Думайте об этом как сегмент: индексная адресация, где индекс не может быть больше, чем установленная граница.

Также есть blk_queue_max_segment_size, Оба используются для построения правильных запросов к устройству - запросы переупорядочиваются и объединяются.

Есть и другие варианты использования. Например, из xen-blkfront.c:

/* Each segment in a request is up to an aligned page in size. */
blk_queue_segment_boundary(rq, PAGE_SIZE - 1);
blk_queue_max_segment_size(rq, PAGE_SIZE);

Запросы ограничены PAGE_SIZE для лучшей производительности.

Другие вопросы по тегам