Этот вопрос довольно длительный, поэтому я задам вопросы в верхней части, а затем расскажу, как перейти к вопросам:
- Разве (на основе Busybox) rm не выполнялся, потому что не было достаточно непрерывной оперативной памяти?
- Если так, есть ли легкий способ дефрагментации DMA - без перезапуска системы?
- Если нет, то чем это вызвано? Как я могу предотвратить это в будущем?
После того, как наша тестовая система работала довольно интенсивно в течение последних нескольких дней - я telnet'd в систему и проверил результаты теста. Когда я пришел удалить некоторые данные, система вернула командную строку (как если бы команда была выполнена правильно). Когда я пришел проверить каталог на наличие другого набора результатов, я увидел, что файл все еще существует (с помощью ls).
После этого я заметил, что все больше и больше моих команд оболочки работают не так, как ожидалось.
Я начну с вывода из dmesg после того, как rm не выполнится правильно:
Выделение длины 61440 из процесса 6821 (rm) не удалось
DMA на процессор:
CPU 0: hi: 0, btch: 1 usd: 0
Active_anon: 0 active_file: 1 inactive_anon: 0 inactive_file: 0 univictable: 6 dirty: 0 writeback: 0 unstable: 0 free: 821 slab: 353 сопоставлено: 0 pagetables: 0 bounce: 0
Свободное DMA: 3284 КБ, минимальное: 360 КБ, низкое: 448 КБ, высокое: 540 КБ, активный_анон: 0 КБ, inactive_anon: 0 КБ, активный_файл: 4 КБ, неактивный_файл: 0 КБ, необратимый: 24 КБ, присутствует: 8128 КБ, страниц: просмотрено: 0 все_ не подлежит возврату? нет
lowmem_reserve []: 0 0 0
DMA: 31 * 4 КБ 47 * 8 КБ 42 * 16 КБ 64 * 32 КБ 1 * 64 КБ 0 * 128 КБ 0 * 256 КБ 0 * 512 КБ 0 * 1024 КБ 0 * 2048 КБ 0 * 4096 КБ = 3284 КБ
Всего 14 страниц кэша страниц
Невозможно выделить ОЗУ для данных процесса, errno 12
Первоначально я думал, что не смог запустить программу в большей части непрерывной памяти. Это означает, что DMA был слишком фрагментирован, и мне нужно было бы найти способ заставить систему дефрагментировать память.
Затем я сделал быструю проверку математики и здравомыслия и понял, что программа должна была быть в состоянии работать в единственном слоте памяти объемом 64 КБ. Rm запрашивает 61440 байт (60 КБ).
Я сделал старый добрый «ручной дефрагментации» и перезагрузил систему. Когда я перезагрузил систему, я вывел / proc / buddyinfo:
Node 0, zone DMA 2 8 3 12 0 1 0 1 0 1 0
Который я подозреваю карту:
- 2 х 4 кБ
- 8 х 8 кБ
- 3 х 16 кБ
- 12 х 32 кБ
- 1 х 128 кБ
- 1 х 512 кБ
Но если суммировать приведенный выше список значений, он не совпадает с выводом / proc / meminfo :
MemTotal: 6580 kB
MemFree: 3164 kB
Buffers: 0 kB
Cached: 728 kB
SwapCached: 0 kB
Active: 176 kB
Inactive: 524 kB
Active(anon): 0 kB
Inactive(anon): 0 kB
Active(file): 176 kB
Inactive(file): 524 kB`
Unevictable: 0 kB
Mlocked: 0 kB
MmapCopy: 844 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 0 kB
Mapped: 0 kB
Slab: 1268 kB
SReclaimable: 196 kB
SUnreclaim: 1072 kB
PageTables: 0 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 3288 kB
Committed_AS: 0 kB
VmallocTotal: 0 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
Напомним, мои вопросы:
- Rm не выполнялся, потому что не было достаточно непрерывной оперативной памяти?
- Если так, есть ли легкий способ дефрагментации DMA - без перезапуска системы?
- Если нет, то чем это вызвано? Как я могу предотвратить это в будущем?
Я использую Lortronix XPort Pro (8 МБ, ОС Linux) под управлением uClinux версии 2.6.30. Оболочка в использовании является тихой.
Ответы:
На ваш вопрос 2 (дефрагментация памяти), цитата из https://www.kernel.org/doc/Documentation/sysctl/vm.txt :
это означает, что следующая команда (выполняется с правами суперпользователя и если упомянутая выше опция ядра включена)
следует сообщить ядру, чтобы попытаться максимально дефрагментировать память. Помните, что, например, в некоторых версиях RHEL6 это может привести к сбою ядра ...
источник
Это заняло немного времени, но я подумал, что не буду отвечать, пока не получу ответы на все 3 моих подвопроса.
Прежде чем я начну, я упомяну, что правильный термин, когда речь идет о «де-фрагментации» рабочей памяти, относится к «сжатию» рабочей памяти.
1. rm не выполнялся, потому что не было достаточно непрерывной оперативной памяти?
Я был прав в своем заключении - rm не выполнялся, потому что было недостаточно непрерывной оперативной памяти. Система собирала ОЗУ и фрагментировала ее, что делало ее невосстановимой.
2. Если так, есть ли легкий способ дефрагментации прямого доступа к памяти - без перезапуска системы?
Оказывается, нет способа сжать память, кроме перезапуска встроенной системы. В случае системы без MMU предотвращение - это название игры.
Часть меня размышляет, возможно ли взломать ядро linux для эмуляции MMU в программном обеспечении. Я полагаю, если бы это было возможно, кто-то уже сделал бы это. Я не могу представить, что это совершенно новая концепция;)
3. Как я могу предотвратить это в будущем?
Для этого проекта я использовал cron для ручного запуска программы каждый раз, когда это требовалось. Гораздо лучший способ сделать это - вызвать программу при запуске, а затем принудительно перевести программу в спящий режим, пока она не потребуется. Таким образом, память не должна быть распределена при каждом использовании. Таким образом снижается фрагментация.
На первой итерации проекта мы использовали вызовы моего сценария оболочки для выполнения критических функций (таких как rm). Мы не видели необходимости заново изобретать колесо, если в этом не было необходимости.
Тем не менее, я бы рекомендовал по возможности избегать оболочки для системы без MMU -
( Вопрос , что произойдет, если вы выполните
ls -la /path/to/directory/ | grep file-i-seek
?)( Ответ : запускается новый подпроцесс)
Если вам нужно реализовать некоторые функциональные возможности сценария ядра оболочки в вашей C-программе, я рекомендую проверить исходный код, используемый в BusyBox . Скорее всего, вы будете использовать C во встроенной системе.
источник