Jump to content

    

Можно ли замапить память юзер спейс для pcie устройства?

Вот есть у меня линукс-драйвер для pcie устройства (отладочная плата альтеры). Он еще весьма сырой.

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

И в итоге можно в юзер спейс программе писать или читать по выделенным функцией mmap адресам. Это транслируется в запросы записи или чтения на шину pcie. И в итоге эти запросы попадают в плис и уходят в память, которая подключена к барам у pcie ядра в плис.

Это выглядит как прямое отображение памяти баров девайса в эзер спейс программу.

 

А вопрос такой. А можно ли с помощью mmap или чего другого отобразить юзер спейс массив (память) для прямого доступа со стороны девайса?

Например, чтобы девайс засылал запрос на запись данных по pcie и данные попадали в массив, созданный в юзер спейс программе. Но чтоб без прерываний.

 

PS: LDD читал, читаю и читать буду, но пока каша в голове.

 

Share this post


Link to post
Share on other sites
А вопрос такой. А можно ли с помощью mmap или чего другого отобразить юзер спейс массив (память) для прямого доступа со стороны девайса?

Например, чтобы девайс засылал запрос на запись данных по pcie и данные попадали в массив, созданный в юзер спейс программе. Но чтоб без прерываний.

 

Почему бы не выделять память в драйвере, а в userspace только делать mmap этой памяти и работать с ней?

Чем обусловлена необходимоть выделять память именно в userspace?

 

Если это, всё-таки, необходимо на 100%, то это тоже реально.

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

Поэтому придется работать только с 1-ой страницей непрерывной памяти.

 

Пример можно посмотреть у меня в статье.

Основная для Вас информация дана в разделе Реализация userspace программы:

http://habrahabr.ru/company/metrotek/blog/248145/

Share this post


Link to post
Share on other sites

Спасибо за ответ и за ссылку на статью! Теперь есть материал для изучения и экспериментов.

 

Share this post


Link to post
Share on other sites

С помощью userspace кода, указанного по ссылке выше, получилось сделать задуманное. Сейчас плис пишет прямо в буфер юзер спейс программы. Все довольно шустренько работает. Но вот зародился такой вопрос.

Плиска пишет пакет данных, размером чуть меньше страницы (~4000 байт). В конце записи плиска приписывает флаг по определённому адресу, указывающему, что запись закончена. Проц все время в while читает этот флаг. Как только проц определил, что флаг взвелся, он приступает к работе с данными. Но это не оптимально. Можно было бы начинать работать с данными по мере их поступления.

Придумали следующий вариант. Плиска все равно в шину отправляет данные пакетиками по 128байт. Из них последние 8байт отводим под флаг. Проц мониторит флаг первого пакетака - если флаг взвелся, проц может проанализировать 120 байт переданных ему данных, и переходит к считыванию флага следующего пакетика. И т.д.

 

А может быть есть другие средства/механизмы удостовериться в том, что данные обновились? Какие-нибудь волшебные ассемблерные вставки? :rolleyes:

 

Помимо этого озадачивает следующее. Данные плиска пишет прямо в физ. память. А проц читает не саму память, а кеш первого уровня, в котором отображается блок памяти, размером с кеш линию (обычно 64байт). Так мне объяснил коллега.

Каким образом узнать (гарантировать), что в кеше процессора актуальные данные, что из Плиски вот только что не прилетели новые данные?

Share this post


Link to post
Share on other sites

Есть старинный стандартный способ -- прерывание. Плиска должна вызывать прерывание по окончанию пакета. Лучше конечно если это сделает DMA. Контролер DMA ведь знает заранее длину пакета. По окончанию пакета надо вызывать прерывание.

 

Надо invalidate обновленную память, что стимулирует обновление кэша, но я не делал этого на практике. Поищите примеры в исходниках ядра.

Share this post


Link to post
Share on other sites
Есть старинный стандартный способ -- прерывание. Плиска должна вызывать прерывание по окончанию пакета. Лучше конечно если это сделает DMA. Контролер DMA ведь знает заранее длину пакета. По окончанию пакета надо вызывать прерывание.

Прерывание - уже пробовали. Организовали такой тест: в плиску пишут в определенный регистр, она выставляет прерывание, ядро его обрабатывает, снимает прерывание, дальше процесс повторяется. Этот тест показывал цифры 10-15мкс между прерываниями. Ну это никуда не годится. Ладно если объемы большие - десятки-сотни мегабайт. А мне надо не больше 4000 байт перекинуть, но часто. Для pcie x8 Gen2 4000 байт перекинуть - 2мкс, а потом еще 10 мкс ждать когда там ядро в обработчик зайдет. Вот des333 в своей статье расписал способ и исходники приложил. И с ними всё работает шустро, потому хотелось бы двигаться в этом направление.

 

invalidate - погуглю, посмотрю, что это вообще, спасибо.

Share this post


Link to post
Share on other sites
Прерывание - уже пробовали. Организовали такой тест: в плиску пишут в определенный регистр, она выставляет прерывание, ядро его обрабатывает, снимает прерывание, дальше процесс повторяется. Этот тест показывал цифры 10-15мкс между прерываниями. Ну это никуда не годится. Ладно если объемы большие - десятки-сотни мегабайт. А мне надо не больше 4000 байт перекинуть, но часто. Для pcie x8 Gen2 4000 байт перекинуть - 2мкс, а потом еще 10 мкс ждать когда там ядро в обработчик зайдет. Вот des333 в своей статье расписал способ и исходники приложил. И с ними всё работает шустро, потому хотелось бы двигаться в этом направление.

 

invalidate - погуглю, посмотрю, что это вообще, спасибо.

 

Ну на таких скоростях вам пофиг ждать в цикле или по прерыванию. Все равно никто ничего делать не сможет -- весь процессор будет занят вашей задачей. По прерыванию подход-отход будет долгий. А нет возможности удлинить пакеты? Дайте DMA длину, скажем, 100 пакетов.

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

Share this post


Link to post
Share on other sites

Опять вопрос появился.

Вот в интернетах пишут Direct Cache Access.

Прямой доступ к кешу. И пишут, что это ускоряет доставку данных от pcie девайса к процессору. Даже картинки приводят функциональные. А больше ничего найти не могу. Какие то примеры на Си, какие функции использовать, какие include подключать?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this