|
PCIe Driver |
|
|
|
Aug 13 2015, 21:15
|
Знающий
   
Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088

|
"Нативными" методами работы с драйверами устройств являются open,read,write,close. fopen,fread,fwrite,fclose - это уже функции библитеки libc, они удобны для работы с файлами, как с потоками данных (stream), поэтому читают из устройства (как бы файла) сразу большими блоками и буферизируют внутри себя данные. Это позволяет добиться существенного выиграша в скорости при работе с файловой системой, даже если верхний уровень читает по 16 байт, в "глубине души" чтение идёт блоками, удобными устройству и буферизируется, а когда юзер снова попросит следующие 16 байт, уже ничего читать не нужно, можно скопировать из буфера уже прочитанное...
--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
|
|
|
|
|
Dec 15 2015, 19:32
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Приветствую. В функции инициализации модуля pcievx7_init хочу добраться до struct pci_dev *pdev, вроде как должно помочь container_of, но получаются разные значения для pdev и my_pdev. Может кто подскажет, что тут неправильно? Значения pdev->driver и &pcievx7_pci_driver одинаковы. Код static int pcievx7_probe(struct pci_dev *pdev , const struct pci_device_id *id) { ... PINFO("pdev = %p\n", pdev); PINFO("pdev->driver = %p\n", pdev->driver); // выводит в syslog адрес pcievx7_pci_driver = DRIVER_ADDRESS ... }
static struct pci_driver pcievx7_pci_driver = { .name = DRIVER_NAME, .probe = pcievx7_probe, .remove = pcievx7_remove, .id_table = pcievx7_pci_driver_ids };
static int __init pcievx7_init(void) { struct pci_dev *my_pdev; ... pci_register_driver(&pcievx7_pci_driver); PINFO("&pcievx7_pci_driver = %p\n", &pcievx7_pci_driver); // выводит в syslog адрес pcievx7_pci_driver = DRIVER_ADDRESS my_pdev = container_of(&pcievx7_pci_driver, struct pci_dev, driver); PINFO("my_pdev = %p\n", my_pdev); ... }
|
|
|
|
|
Dec 16 2015, 07:38
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(Tarbal @ Dec 16 2015, 05:08)  Я бы поле имени pdev->driver->name напечатал в консоль для обоих. Может помочь понять. Перед печатью проверьте если pdev->driver не равен нулю иначе система рухнет. Если правильно Вас понял, то сделал это: Код static int pcievx7_probe(struct pci_dev *pdev , const struct pci_device_id *id) { PINFO("%s\n", pdev->driver->name); // выводит в syslog имя драйвера "pcievx7" }
static struct pci_driver pcievx7_pci_driver = { .name = DRIVER_NAME, .probe = pcievx7_probe, .remove = pcievx7_remove, .id_table = pcievx7_pci_driver_ids };
static int __init pcievx7_init(void) { pci_register_driver(&pcievx7_pci_driver); PINFO("%s\n", (&pcievx7_pci_driver)->name); // выводит в syslog имя драйвера "pcievx7" } Имя драйвера в обоих случаях одинаково. Вопрос остался. Попробовал сделать так: Код static int pcievx7_probe(struct pci_dev *pdev , const struct pci_device_id *id) { struct pci_dev *test_pdev;
test_pdev = container_of(pdev->driver, struct pci_dev, driver);
PINFO("%p\n", test_pdev); PINFO("%p\n", pdev); } Получаю разные значения для test_pdev и pdev. Объясните, что тут неправильно? Спасибо.
|
|
|
|
|
Jul 16 2016, 18:21
|

фанат Linux'а
    
Группа: Свой
Сообщений: 1 353
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008

|
Цитата(dm.pogrebnoy @ Jul 16 2016, 21:00)  В последних ядрах есть CMA (Contiguous Memory Allocator), в принципе можно выделить и подряд много, сам пробовал, получалось. Я может что-то не понимаю, но меня искренне удивляет что работа устройства будет отдана воле случая, выделится а может нет - зачем такое делать? Допустим в системе 16 гигабайт ОЗУ. CMA может выделить буфер 5 гигабайт? Я знаю что так делать не хорошо, но что если будет некоторое устройство, которому именно что требуется это, и пользователь будет предупрежден что именно столько надо для работы устройства. Я сторонник исключительно 100% надежно работающих подходов.
--------------------
|
|
|
|
|
Jul 16 2016, 19:15
|

Знающий
   
Группа: Свой
Сообщений: 747
Регистрация: 11-04-07
Пользователь №: 26 933

|
Цитата(AVR @ Jul 16 2016, 21:21)  Я может что-то не понимаю, но меня искренне удивляет что работа устройства будет отдана воле случая, выделится а может нет - зачем такое делать?
Допустим в системе 16 гигабайт ОЗУ. CMA может выделить буфер 5 гигабайт? Я знаю что так делать не хорошо, но что если будет некоторое устройство, которому именно что требуется это, и пользователь будет предупрежден что именно столько надо для работы устройства.
Я сторонник исключительно 100% надежно работающих подходов. Я так понимаю, если в системе только один драйвер использует подобный алгоритм выделения памяти, то вообще никаких проблем не будет, если несколько, то надо следить за суммарным размером области. В целом да, специфично, но зато можно без SGDMA обойтись. Да и производительность чуть-чуть будет повыше.
--------------------
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|