LinuxForum.Fans
Тема

RamDisk, make_request, udelay

Автор: Timbuktu 5 сообщений 6241 просмотров
#256386

Всем привет,

я хочу написать небольшой драйвер, похожий на brd, RapidDisk or sbull (LDD3). Он должен будет симулировать поведение реального устройства. Так к примеру, мне нужно как можно точнее симулировать задержки при IO операциях (20 микросекунд). Я использую для этого функцию udelay, так-как usleep_range слишком уж неточная. Симулироемое устройство поддерживает паралельную обработку операций (так если устройство состоит из двух логических блоков, то паралельно могут обрабатываться две операции). Queue & schedulers не используються - вместо этого напрямую используеться make_request.

И вот какой у меня вопрос:
udelay по документации - "busy waiting" и поэтому может быть использован в atomic context. А совместим ли udelay с параллелизмом?
Вот к примеру мой псевдокод:

text

void make_request(struct request_queue *q, struct bio *bio)
{
    getnstimeofday(start);     
    spinlock_t lock = <<найти лок, который относиться к нужному блоку, основываясь на bio>>;
    spin_lock(lock);
    //simulate IO ....   
    getnstimeofday(end);
    udelay(needed - (end - start));
    spin_unlock(lock);
}

Я собераюсь вместо одного лока использывать несколько – каждый для отдельного блока устройства, чтобы добиться параллелизма. Без udelay, как мне кажеться, всё будет ок. Но вот может ли две, три или больше функций udelay выполняться паралельно? От чего зависить количество таких паралельных задержек?

Заранее большое спасибо!

#256394

udelay будет занимать и кушать процессор... паралельность тут будет только если для каждого экземпляра найдётся свободное ядро.
а на сколько неточной usleep_range оказывается?

#256399

к примеру udelay(25) в 99% случаях дает задержку именно в 25 микросекунд.
а usleep_range(20,25) дает расбросс от 36 до !!!!!1500!!!! микросекунд. (25 на моей машинке я не видел не разу).

то есть на сколько я понял, если у меня на сервере 16 ядер, то на паралельное выполнение udelay (при условии разных локов), я всё-таки могу расчитовать?

Есть у меня еще два вопроса:
- когда данные скопированные в буффер (в функции make_request, к примеру, с помошью memcpy), становяться доступны приложению (которое и инициирует IO): сразу после memcpy или после вызова функции bio_endio(bio, status).

- если мне доступно на сервере порядка 50 Гб оперативки - могу ли я в своем симуляторе резместить с помощью функии alloc_page этиже 50 Гигабайт? vmalloc & kmalloc на сколько я понимаю не годяться для таких размеров.

Спасибо

#256410
"Timbuktu" написал:
а usleep_range(20,25) дает расбросс от 36 до !!!!!1500!!!! микросекунд. (25 на моей машинке я не видел не разу).

м... ну максимальное значение ожидаемое из-за всяких решедулов... может было бы получше если поставить CONFIG_HZ_ поменьше...

"Timbuktu" написал:
то есть на сколько я понял, если у меня на сервере 16 ядер, то на паралельное выполнение udelay (при условии разных локов), я всё-таки могу расчитовать?

да, udelay простой как 5 копеек:

text

// псевдокод
%eax = seconds_to_cycles(n); 
while(%eax)
    %eax--;
"Timbuktu" написал:
- когда данные скопированные в буффер (в функции make_request, к примеру, с помошью memcpy), становяться доступны приложению (которое и инициирует IO): сразу после memcpy или после вызова функции bio_endio(bio, status).

после возврата из систеного вызова. уж точно не после memcpy. так что после bio или позже.
врать не буду - трассировщик в зубы и вперёд проверять...

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

#256447
Fat-Zer написал:
про память тоже не скажу, но для ядра больно жирно столько выделять... независимо от принципиальной возможности.

понимаю, что жирновато. Но подругому вроде никак: нужно симулировать устройсво, так что-бы для системы не было никакой разници, а следовательно без драйвера никак. А само устройство имеет внутреннею память в 32 гига. На сайте RapidDisk rapiddisk.org, автор пишет что можно выделять память под RamDisk и в терабайтах, и вроде он так же все делает как и в стандартном brd. Так что надеюсь получиться.

А вот с паралельностью конечно немножко лажа - но всё равно хоть одна функция позволяет добиться такой как надо точности (P.S. попробывал сначала написать симулятор на Java, там вообще - каждый раз время задержи разное - и то измеримое не в микросекундах, а в МИЛИсекундах).

Большое спасибо за помощь!

Войдите или зарегистрируйтесь, чтобы ответить.