Hoodwin
Apr 25 2013, 20:47
Вот такая имеется проблема. вызов команды mount для монтирования файловой системы NFS выдает ошибку bad address, причем именно в системной UART-овской консоли. Если зайти в систему telnet'ом, то работает без проблем. Что бы это могло быть? Можно это как-то полечить?
Hoodwin
Apr 28 2013, 17:57
Ну, до такой глубины пока не лезли. Судя по симптомам, там какая-то проблема с выравниванием структур в памяти. Мы тут недавно развлекались с транслятором, оказалось, что он как-то интересно компилит код с "нехорошими" структурами, у которых есть вопросы с выравниванием полей. И, что интересно, структура с объявлением __attribute__(packed) в реальности работает лучше, чем без него. Сам процессор не имеет никаких трапов по случаю неправильного выравнивания, просто ненужные биты адреса не попадают на шину и все. Читать слово по адресу 3 все равно что читать его с адреса 0.
Сам по себе эффект изначально отсутствовал, но вот при очередной сборке ядра вдруг вылез. Тогда, когда он появился впервые, я собственно изменил в ядре одну вещь. Функции copy_to_user, copy_from_user были объявлены как static inline прямо в хедере, и в них в общем-то ничего не делалось, а подставлялся вызов memcpy. А я решил поизучать, какие длины блоков наиболее часто копируются, чтобы в перспективе большие блоки копировать с помощью DMA и отдавать процессору время на вычисления. С этой целью функции были вынесены в модуль, и к вызову memcpy был добавлен код, который накапливал статистику в небольшой массив бинов.
Поначалу я думал, что проблема с nfs может быть связана с моим изменением, но потом обнаружил, что под телнетовской консолью проблемы нет. Потом полез в исходник mount в busybox и вставил туда дополнительную диагностику. Потом еще какие-то комментарии там нашел, намекающие на то, что какая-то бага там возможно еще есть.
Не то, чтобы она прямо жить не дает, но я подумал, вдруг кто отгадку знает.
Ваш код то корректный? а то тут делали уже stackoverflow.com/questions/14970698/copy-to-user-vs-memcpy
Hoodwin
Apr 29 2013, 10:07
Ну, во-первых у меня платформа без защиты памяти, так что разница между copy_to_user и memcpy вообще почти отсутствует.
Во-вторых, я вообще не изменил логики самой функции, оставил то, что сделали до меня авторы порта линукса нс c6x. Я только добавил подсчет статистики.
В третьих, это все не объясняет, почему под телнетом проблема не проявляется.