|
|
  |
Можно ли замапить память юзер спейс для pcie устройства?, вопрос так скажем от новичка. |
|
|
|
Nov 13 2015, 18:46
|

Местный
  
Группа: Свой
Сообщений: 375
Регистрация: 9-10-09
Из: Свердловский регион
Пользователь №: 52 845

|
Вот есть у меня линукс-драйвер для pcie устройства (отладочная плата альтеры). Он еще весьма сырой. В интернете видел, что бары девайса мапятся в юзер спейс программу с помощью mmap. Своими руками такое еще не реализовал  . И в итоге можно в юзер спейс программе писать или читать по выделенным функцией mmap адресам. Это транслируется в запросы записи или чтения на шину pcie. И в итоге эти запросы попадают в плис и уходят в память, которая подключена к барам у pcie ядра в плис. Это выглядит как прямое отображение памяти баров девайса в эзер спейс программу. А вопрос такой. А можно ли с помощью mmap или чего другого отобразить юзер спейс массив (память) для прямого доступа со стороны девайса? Например, чтобы девайс засылал запрос на запись данных по pcie и данные попадали в массив, созданный в юзер спейс программе. Но чтоб без прерываний. PS: LDD читал, читаю и читать буду, но пока каша в голове.
|
|
|
|
|
Nov 14 2015, 15:08
|
Профессионал
    
Группа: Свой
Сообщений: 1 129
Регистрация: 19-07-08
Из: Санкт-Петербург
Пользователь №: 39 079

|
Цитата(novartis @ Nov 13 2015, 21:46)  А вопрос такой. А можно ли с помощью mmap или чего другого отобразить юзер спейс массив (память) для прямого доступа со стороны девайса? Например, чтобы девайс засылал запрос на запись данных по pcie и данные попадали в массив, созданный в юзер спейс программе. Но чтоб без прерываний. Почему бы не выделять память в драйвере, а в userspace только делать mmap этой памяти и работать с ней? Чем обусловлена необходимоть выделять память именно в userspace? Если это, всё-таки, необходимо на 100%, то это тоже реально. Но нужно помнить, что непрерывная память в userspace не будет непрерывной физически и, следовательно, непрерывной для устройства. Поэтому придется работать только с 1-ой страницей непрерывной памяти. Пример можно посмотреть у меня в статье. Основная для Вас информация дана в разделе Реализация userspace программы: http://habrahabr.ru/company/metrotek/blog/248145/
--------------------
|
|
|
|
|
Dec 9 2015, 10:33
|

Местный
  
Группа: Свой
Сообщений: 375
Регистрация: 9-10-09
Из: Свердловский регион
Пользователь №: 52 845

|
С помощью userspace кода, указанного по ссылке выше, получилось сделать задуманное. Сейчас плис пишет прямо в буфер юзер спейс программы. Все довольно шустренько работает. Но вот зародился такой вопрос. Плиска пишет пакет данных, размером чуть меньше страницы (~4000 байт). В конце записи плиска приписывает флаг по определённому адресу, указывающему, что запись закончена. Проц все время в while читает этот флаг. Как только проц определил, что флаг взвелся, он приступает к работе с данными. Но это не оптимально. Можно было бы начинать работать с данными по мере их поступления. Придумали следующий вариант. Плиска все равно в шину отправляет данные пакетиками по 128байт. Из них последние 8байт отводим под флаг. Проц мониторит флаг первого пакетака - если флаг взвелся, проц может проанализировать 120 байт переданных ему данных, и переходит к считыванию флага следующего пакетика. И т.д. А может быть есть другие средства/механизмы удостовериться в том, что данные обновились? Какие-нибудь волшебные ассемблерные вставки? Помимо этого озадачивает следующее. Данные плиска пишет прямо в физ. память. А проц читает не саму память, а кеш первого уровня, в котором отображается блок памяти, размером с кеш линию (обычно 64байт). Так мне объяснил коллега. Каким образом узнать (гарантировать), что в кеше процессора актуальные данные, что из Плиски вот только что не прилетели новые данные?
|
|
|
|
|
Dec 9 2015, 16:36
|

Местный
  
Группа: Свой
Сообщений: 375
Регистрация: 9-10-09
Из: Свердловский регион
Пользователь №: 52 845

|
Цитата Есть старинный стандартный способ -- прерывание. Плиска должна вызывать прерывание по окончанию пакета. Лучше конечно если это сделает DMA. Контролер DMA ведь знает заранее длину пакета. По окончанию пакета надо вызывать прерывание. Прерывание - уже пробовали. Организовали такой тест: в плиску пишут в определенный регистр, она выставляет прерывание, ядро его обрабатывает, снимает прерывание, дальше процесс повторяется. Этот тест показывал цифры 10-15мкс между прерываниями. Ну это никуда не годится. Ладно если объемы большие - десятки-сотни мегабайт. А мне надо не больше 4000 байт перекинуть, но часто. Для pcie x8 Gen2 4000 байт перекинуть - 2мкс, а потом еще 10 мкс ждать когда там ядро в обработчик зайдет. Вот des333 в своей статье расписал способ и исходники приложил. И с ними всё работает шустро, потому хотелось бы двигаться в этом направление. invalidate - погуглю, посмотрю, что это вообще, спасибо.
|
|
|
|
|
Dec 9 2015, 17:25
|
Профессионал
    
Группа: Свой
Сообщений: 1 351
Регистрация: 21-05-10
Пользователь №: 57 439

|
Цитата(novartis @ Dec 9 2015, 20:36)  Прерывание - уже пробовали. Организовали такой тест: в плиску пишут в определенный регистр, она выставляет прерывание, ядро его обрабатывает, снимает прерывание, дальше процесс повторяется. Этот тест показывал цифры 10-15мкс между прерываниями. Ну это никуда не годится. Ладно если объемы большие - десятки-сотни мегабайт. А мне надо не больше 4000 байт перекинуть, но часто. Для pcie x8 Gen2 4000 байт перекинуть - 2мкс, а потом еще 10 мкс ждать когда там ядро в обработчик зайдет. Вот des333 в своей статье расписал способ и исходники приложил. И с ними всё работает шустро, потому хотелось бы двигаться в этом направление.
invalidate - погуглю, посмотрю, что это вообще, спасибо. Ну на таких скоростях вам пофиг ждать в цикле или по прерыванию. Все равно никто ничего делать не сможет -- весь процессор будет занят вашей задачей. По прерыванию подход-отход будет долгий. А нет возможности удлинить пакеты? Дайте DMA длину, скажем, 100 пакетов. Если не получится, то сделайте отдельный тред и на многоядерном процессоре гоняйте. одно ядро будет выполнять задачу и пусть себе ждет в цикле.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|