Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Выделить большую (32 Мб) непрерывную область

Автор вопроса: Kevin BowenОтветов: 2

Возможно ли вообще выделить большие (т.е. 32 Мб) физически непрерывные области памяти из кода ядра во время выполнения (т.е. без использования загрузочной памяти)? Из моих экспериментов кажется, что невозможно успешно получить что-то большее, чем 4 МБ, независимо от того, какие флаги GFP я использую. Согласно документации, которую я прочитал, GFP_NOFAIL должен заставить kmalloc просто ждать столько, сколько необходимо для освобождения запрошенной суммы, но из того, что я могу сказать, запрос просто зависает на неопределенный срок, если вы запрашиваете больше, чем доступно - не похоже, что он активно пытается освободить память для выполнения запроса (например, kswapd не работает). Есть ли какой-нибудь способ сказать ядру, чтобы оно начало агрессивно выгружать вещи, чтобы освободить запрошенное распределение?

Редактировать: Итак, из ответа Юджина я вижу, что невозможно получить 32-мегабайтный регион из одного kmalloc .... но есть ли возможность сделать это более хакерским способом? Например, определить самую большую доступную непрерывную область, а затем вручную перенести/заменить данные по обе стороны от нее?

Или как насчет такого:

1) Grab a bunch of 4mb chunks until you're out of memory.
2) Check them all to see if any of them happen to be contiguous, if so,
   combine them.
3) kfree the rest
4) goto 1)

Может ли это сработать, если дать достаточно времени для запуска?

  • Просто из любопытства, зачем вам 32 Мб физически непрерывной памяти? Eugene 26.08.2011
  • Из того, что я вижу в исходниках ядра (определение MAX_ORDER в mmzone. h и текст __alloc_pages_slowpath), выделение более (1 ‹‹ (MAX_ORDER - 1)) страниц непрерывной памяти кажется невозможным. Обычно это (1 ‹‹ 10) * 4096 = 4Мб. Кроме того, об этом должно было выводиться предупреждение в системный журнал. Eugene 26.08.2011
  • Что ж, многие встроенные устройства (например, телефоны) имеют аппаратное обеспечение (например, камеры и чипы кодеков), которым требуется физически непрерывная область памяти, поскольку они пишут напрямую в оперативную память, минуя MMU. Обычно это реализуется с помощью загрузочной памяти - выделения области во время загрузки, которая постоянно зарезервирована для них, без ограничений для выделения для чего-либо еще. Это чрезвычайно расточительно, хотя на устройствах с ограниченным объемом памяти ... меня просто действительно беспокоит то, что на моем телефоне с физической памятью всего 512. Kevin Bowen 30.08.2011
  • (продолжение) Кажется, нет никакой теоретической причины, по которой это должно быть необходимо - разве ядро ​​не должно иметь возможность обменивать и/или переносить данные по требованию, чтобы освободить необходимую область? Я понимаю, что весь этот обмен/миграция займет некоторое время, но я готов подождать несколько секунд, пока драйвер камеры загрузится в тех редких случаях, когда я его использую, если это означает освобождение дополнительных 100 МБ оперативной памяти. при обычном использовании (чип кодека использует несколько банков по 32 Мб каждый). Kevin Bowen 30.08.2011
  • Да, теперь я понимаю, почему такой объем непрерывной памяти может быть желателен. Спасибо за объяснение. Eugene 31.08.2011
  • Как решить проблему, я, к сожалению, не знаю. Описанный вами способ может работать, но я сомневаюсь, что он будет очень надежным. Тем не менее, стоит попробовать, если ничего другого нет. Eugene 31.08.2011

linux-kernel

Ответы

Ответ 1 · рейтинг 1 · Mircea

Вы можете ознакомиться с исправлениями для распределителя непрерывной памяти. Судя по статье LWN, эти патчи именно то, что вам нужно.

Ответ 2 · bdonlan

Ссылка Мирчи - один из вариантов; если на вашем устройстве есть IOMMU, вы также можете использовать его для представления непрерывного представления набора несмежных страниц в памяти.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы