kernel BUG at mm/memory.c при вызове remap_pfn_range()

Вопросы программного кода и архитектуры Linux

Модератор: Olej

just_a_student
Писатель
Сообщения: 20
Зарегистрирован: 11 июл 2013, 20:57
Контактная информация:

kernel BUG at mm/memory.c при вызове remap_pfn_range()

Непрочитанное сообщение just_a_student » 29 окт 2013, 11:07

Здравствуйте!
Пытаюсь заставить работать на новом ядре драйвер и тестовую программу к нему, которые были написаны лет пять назад для этого же железа, но для старого ядра. В те времена все работало отлично.
Компьютер одноплатный. Загрузочная карта памяти содержит linux с ядром 3.10.12 и файлом initrd.img, сделанным так, чтобы постоянная файловая система не монтировалась, а работа велась в initrd, который крутится в оперативной памяти. Ядро было довольно сильно урезано, для экономии памяти.
Драйвер создан для сигнального процессора, который связан с одноплатным компьютером через PCI шину (и компьютер и плата содержащая процессор вставляются в PCI слоты в одной стойке). Драйвер успешно распознает процессор и загружается в систему.
Этот драйвер позволяет загружать данные с хоста (одноплатного компьютера) прямо в память сигнального процессора. Тестовая программа собственно это и делает.
В коде драйвера, в структуре file_operations, определена функция .mmap, которая, насколько я понимаю, производит отображение памяти процессора в пространство пользователя. Функция mmap заключается в вызове функции remap_pfn_range(). Именно на вызове этой функции вылетает следующая ошибка и вся система перестает работать (здесь linkdrv это драйвер, а BoardTest это тестовая программа):

Код: Выделить всё

--------[ cut here ]--------
kernel BUG at mm/memory.c :2377! 
invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC
Modules linked in: linkdrv(0)
CPU: 1 PID: 851 Comm: BoardTest Tainted: G   0 3.10.12 #10
Hardware name:      /F15, BIOS F15r1-Q.11 10/17/2006 
task: f6581950 ti: f5c5c000 task.ti: f5c5c000 
EIP: 0060:[<c10aeac4>] EFLAGS: 00010246 CPU: 1 
EIP is at remap_pfn_range+0x75/0x191
ЕАХ: 00000000 EBX: b72f5000 ECX: b72f5000 EDX: 00000000 
ESI: f6616c08 EDI: 00040000 EBP: f5c5ded8 ESP: f5c5de9c
 DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 
CR0: 80050033 CR2: b760а890 CR3: 35c2f000 CR4: 000007d0 
DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 
DR6: ffff0ff0 DR7: 00000400 
Stack:
 f5c5ded8 с10b2b9с f67d3540 00000200 f65175ac 00000003 
 00000000 b72f5000 00000000 f5c5ded0 f678ce00 f6616c08 
 f8028123 00000000 00000027 f6616c08 b74f5000 f5c5df24 
Call Trace:
 [<c10b2b9c>] ? vma_merge+0x148/0xlc5
 [<f80281Z3>] Mmар+0х4а/0х51 [linkdrv]
 [<c10b3fl6>] mmap_region+0x20d/0x3c8
 [<c10b4330>] do_mmap_pgoff+0x25f/0x2d5
 [<c10a9a3c>] vw_mmap_pgoff+0x54/0x7d
 [<c10b2d96>] SyS_mmap_pgoff+0xllf/0x159
 [<c14a2558>] syscall_call+0x7/0xb 
Code: 04 75 ec 89 7e 4c ff 75 ec 89 f9 8d 55 0c 89 f0 53 e8 88 36
EIP: [<c10aeac4>] remap_pfn_range+0x75/0x191  SS:ESP 0068:f5c5de9c 
---[ end trace b23282ceb98d656f ]---
Я нашел только один аналогичный случай на stackoverflow, но там проблема состояла в отображении большого объема памяти (1Гб и более). Здесь же такой проблемы не стоит. На всякий случай я все равно сделал так как советовали там в ответе (включив в ядре опцию CONFIG_TRANSPARENT_HUGEPAGE), но это разумеется не помогло.
Пробовал так же использовать ядро с defconfig, но результат оставался тем же.

Подскажите пожалуйста, в чем может быть причина этой ошибки и в чем она вообще заключается? Насколько я понимаю, проблема больше в ядре(ведь драйвер раньше работал). Возможно нужно что-то изменить в конфигах? Если так, то что именно?

Заранее спасибо за любую помощь!

Update: нашел еще один аналогичный пример
Но в этом случае решением было, если я все правильно понял, вставить вызов remap_pfn_range() в .mmap, но у меня он и так там находится, поэтому помогло мало :(

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: kernel BUG at mm/memory.c при вызове remap_pfn_range()

Непрочитанное сообщение Olej » 29 окт 2013, 14:37

just_a_student писал(а): Пытаюсь заставить работать на новом ядре драйвер и тестовую программу к нему, которые были написаны лет пять назад для этого же железа, но для старого ядра. В те времена все работало отлично.
Если такое происходит, то работало явно не "отлично" ... работало кое-как ;-)
Вряд ли (не сильно вероятно обычно) что это из-за нового ядра ... вот API меняется и не компилируется - это бывает, а совместимость снизу-вверх обычно поддерживается.
А не поменялась ли у вас архитектура ... за пять лет: 32 бит -> 64, i86 -> ARM и т.д. ?
just_a_student писал(а): Подскажите пожалуйста, в чем может быть причина этой ошибки и в чем она вообще заключается? Насколько я понимаю, проблема больше в ядре(ведь драйвер раньше работал). Возможно нужно что-то изменить в конфигах? Если так, то что именно?
Ошибка у вас с выделением памяти... может параметр размера там портится, или граница выравнивания области какая-то не такая...
Происходит это в модуле ядра, но совершенно не обязательно ошибка именно там - сбой у вас происходит сразу после syscall из тестовой программы - возможно там с параметрами вызова полная лажа...

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: kernel BUG at mm/memory.c при вызове remap_pfn_range()

Непрочитанное сообщение Olej » 29 окт 2013, 14:48

just_a_student писал(а):Пытаюсь заставить работать на новом ядре драйвер и тестовую программу к нему, которые были написаны лет пять назад для этого же железа, но для старого ядра.
Ситуация похожа на то, что драйвер этот писали не вы, а автор его сдрыснул года 4 назад ;-) не оставиив никаких описаний...

По опыту (в таких случаях):
- место это в драйвере написано хреново, "на грани фола" - до поры до времени это ещё работало, а теперь накрылось...
- готовьтесь к тому, что это место драйвера вам придётся переписать полностью, в тот способ как сами понимаете это место в работе устройств...
- а руководство своё сразу подготовьте к мысли, что трудоёмкость такой работы не "29 минут", а, может быть, и месяц безотрывой работы (с тестированием и выверкой)...
- а ещё обратите их внимание на важность того, какой детализации пишется тех. документация + система регрессивных тестов ...
- и на то, что на такую постановку работ нужно планировать время, трудоёмкость ... и, соответственно, стоимость ;-)

P.S. "скупой платит дважды" ... а драйвера переписывает до 5-ти раз :lol:

just_a_student
Писатель
Сообщения: 20
Зарегистрирован: 11 июл 2013, 20:57
Контактная информация:

Re: kernel BUG at mm/memory.c при вызове remap_pfn_range()

Непрочитанное сообщение just_a_student » 29 окт 2013, 14:56

Olej писал(а):А не поменялась ли у вас архитектура ... за пять лет: 32 бит -> 64, i86 -> ARM и т.д. ?
Нет, железка в точности та же.
Olej писал(а): сбой у вас происходит сразу после syscall из тестовой программы - возможно там с параметрами вызова полная лажа...
Тестовую программу я не менял, но мб API изменилось. Вот как этот вызов выглядит:

Код: Выделить всё

buffers.inAddr = ::mmap(NULL, image.inSize, PROT_READ | PROT_WRITE, MAP_SHARED, handle, 0);

just_a_student
Писатель
Сообщения: 20
Зарегистрирован: 11 июл 2013, 20:57
Контактная информация:

Re: kernel BUG at mm/memory.c при вызове remap_pfn_range()

Непрочитанное сообщение just_a_student » 29 окт 2013, 15:07

Olej писал(а):Ситуация похожа на то, что драйвер этот писали не вы, а автор его сдрыснул года 4 назад не оставиив никаких описаний...
Ну почти так :) Я просто студент, и цель научной работы - создание(точнее оптимизация существующего) интерфейса между хостом и сигнальным процессором. А то что я пытаюсь завести сейчас - это тот вариант этого интерфейса, который работает на предприятии. Не могу пока судить насколько он хороший или плохой. Но там везде стоят старые ядра. Я создал загрузочную флешку с новым ядром, но столкнулся с этой проблемой.
Проблемы точно не в конфигурации ядра?

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: kernel BUG at mm/memory.c при вызове remap_pfn_range()

Непрочитанное сообщение Olej » 29 окт 2013, 15:11

just_a_student писал(а):
Olej писал(а): сбой у вас происходит сразу после syscall из тестовой программы - возможно там с параметрами вызова полная лажа...
Тестовую программу я не менял, но мб API изменилось.
1. Обычно API не меняется, если меняется, то разработчики ядра специально меняют ... названия символьных констант в #define и т.д. - чтобы несоответствующие программы/модули не компилировались (чтоб сразу указать на это место).
just_a_student писал(а): Вот как этот вызов выглядит:

Код: Выделить всё

buffers.inAddr = ::mmap(NULL, image.inSize, PROT_READ | PROT_WRITE, MAP_SHARED, handle, 0);
2. Что ж мы гадать будем? ... я же не буду за вас отлаживать вашу программу ... да ещё и не имея самой программы? :-o (как любят говорить врачи: "я не лечу по телефону!" ;-) ).
... ставьте отладку (printk) перед вызовом - контролируйте все параметры, что и как туда попадает и т.д.
... выясняйте сколько у вас доступной памяти в ядре, будет ли выделяться память для отображения в памяти ядра ... или нужно что-то переотображать из верхней памяти? ...
... что там с выравниванием границ отображений?
См. для этого хэдер-файлы (.h) ядра, там очень много в комментариях подсказок...

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: kernel BUG at mm/memory.c при вызове remap_pfn_range()

Непрочитанное сообщение Olej » 29 окт 2013, 15:18

just_a_student писал(а):
Olej писал(а):Ситуация похожа на то, что драйвер этот писали не вы, а автор его сдрыснул года 4 назад не оставиив никаких описаний...
Я просто студент, и цель научной работы - создание(точнее оптимизация существующего) интерфейса между хостом и сигнальным процессором.
"Ну вы, блин, даёте"(с) генерал в "национальной охоте": оптимизировать то, что не работает :-o
Это сильный ход :lol:
just_a_student писал(а): А то что я пытаюсь завести сейчас - это тот вариант этого интерфейса, который работает на предприятии. Не могу пока судить насколько он хороший или плохой. Но там везде стоят старые ядра. Я создал загрузочную флешку с новым ядром, но столкнулся с этой проблемой.
Ну, так возьмите старое ядро, и оптимизируйте ;-)
P.S. Можно попробовать всё это организовать в виртуальной машине, в VirtualBox - тогда вы быстро сможете прогонять всё это на целой линейке разных версий ядер.
just_a_student писал(а): Проблемы точно не в конфигурации ядра?
Откуда я знаю? :lol:
Возьмите конфиги от старых работающих ядер - они там лежат (должны) в /boot ... на предприятии. ;-)

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: kernel BUG at mm/memory.c при вызове remap_pfn_range()

Непрочитанное сообщение Olej » 29 окт 2013, 15:31

just_a_student писал(а):А то что я пытаюсь завести сейчас - это тот вариант этого интерфейса, который работает на предприятии.
Начнём с того, что если любая работа делается в расчёте на конкретного потребителя, то никогда не следует предполагать, что, получив какую-то новую незначительную модификацию, этот заказчик (если он не конченный идиот ;-) ) побежит задрав хвост от радости переустанавливать ПО на своих рабочих местах, в частности версию ОС, ядра...
У умных людей: "от добра добра не ищут"(с)

Поэтому и работу нужно всегда начинать с тех релизов ПО, которые использует заказчик.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: kernel BUG at mm/memory.c при вызове remap_pfn_range()

Непрочитанное сообщение Olej » 29 окт 2013, 15:35

just_a_student писал(а):Пробовал так же использовать ядро с defconfig, но результат оставался тем же.
Из всех ваших рассуждений не видно ни одного аргумента почему отработку программного проекта нужно делать в пересобранном ядре.

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

just_a_student
Писатель
Сообщения: 20
Зарегистрирован: 11 июл 2013, 20:57
Контактная информация:

Re: kernel BUG at mm/memory.c при вызове remap_pfn_range()

Непрочитанное сообщение just_a_student » 29 окт 2013, 15:58

Да, уже понял что без похода на предприятие мне не обойтись. Просто не хотелось там просто так у людей время отнимать и попробовать самому уладить, но видимо придется.
Olej писал(а):Ну, так возьмите старое ядро, и оптимизируйте
Хочется то новое!
Olej писал(а):P.S. Можно попробовать всё это организовать в виртуальной машине, в VirtualBox
Врядли возможно. Драйвер написан для весьма специфической железки (сигнального процессора) и если попытаться запустить драйвер тест на простом PC, на котором этой железки нет, то его выполнение прерывается еще где то до вызова mmap (но зато система не падает).

Кстати, пользуясь случаем, хочу сказать большое спасибо за книгу "Программирование модулей ядра Linux!". Невероятно помогла!

Ответить

Вернуться в «Linux изнутри»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 6 гостей