Выделение более 4 МБ закрепленной непрерывной памяти в ядре Linux

Для некоторого взаимодействия с строящимся устройством PCI мы хотели бы создать большие непрерывные участки памяти, к которым плата может получить доступ. На данный момент самый большой кусок памяти, который мне удалось выделить, составляет 4 мегабайта. Мне интересно, есть ли какие-либо методы для создания более крупных регионов.

Я знаю, что для этого я могу использовать вариант загрузки mem=, но по ряду причин я бы предпочел не идти по этому пути. Если бы, с другой стороны, кто-то знал способ сделать это, но распределить его по узлам numa, это было бы хорошо.

Как я сказал изначально, в настоящее время я ограничен 4 мегабайтами. В настоящее время распределение осуществляется __alloc_pages, т.е. ограничено MAX_ORDER. MAX_ORDER - это константа времени компиляции, и я также обеспокоен тем, что ее редактирование может повлиять на что-то еще.

Спасибо.


person Bill Lynch    schedule 09.05.2011    source источник
comment
Должен ли сегмент памяти быть физически непрерывным?   -  person Michael Foukarakis    schedule 18.05.2011
comment
@Майкл: Да. В противном случае я бы просто выделил 4 МБ с помощью __alloc_pages несколько раз.   -  person Bill Lynch    schedule 18.05.2011


Ответы (2)


Если вы можете скомпилировать свой драйвер устройства PCI в ядро ​​(то есть не скомпоновать его как модуль), вы можете попробовать выделить память во время загрузки. Это должно позволить вам обойти верхние границы динамических распределений. См. Драйверы устройств Linux, изд. 3 в.п. 8 для подробностей.

person Karmastan    schedule 09.05.2011
comment
Да. Я тоже видел это раньше. Однако мне бы очень хотелось иметь возможность сделать это без перекомпиляции ядра. Это не то, за что я хотел бы нести ответственность. - person Bill Lynch; 10.05.2011
comment
@sharth: я думаю, что единственная другая альтернатива — это увеличение MAX_ORDER. Вам решать, какая перекомпиляция ядра менее желательна. - person Karmastan; 10.05.2011
comment
На данный момент план состоит в том, чтобы выделять большие объемы памяти во время загрузки. Затем посмотрите, какие части являются смежными, и освободите остальные. Я был бы большим поклонником более последовательного решения. - person Bill Lynch; 10.05.2011

CMA (распределитель непрерывной памяти) — лучшее решение для ваших нужд, IMO. Вам просто нужно загрузить новейшее ядро.

person Lai Jiangshan    schedule 14.07.2012
comment
Я только что искал некоторую дополнительную информацию по этому поводу, и мне было интересно, не могли бы вы ее прояснить. Из того, что я вижу, вам нужно указать аргумент времени загрузки, чтобы указать, сколько памяти должно быть зарезервировано. Если это так, то это похоже (но намного чище, безопаснее и приятнее) на вариант mem=. Кроме того, из того, что я вижу, этого нет в 3.4.4 или next-20120713. Это действительно было введено в основную линию? - person Bill Lynch; 14.07.2012
comment
@sharth mem= заставляет ядро ​​​​не обращаться к верхней памяти и оставлять часть памяти для нужд драйвера, но, насколько мне известно, пользователям нужно делать больше для управления оставшейся памятью. И эта память НЕ может быть использована, даже если она свободна/пригодна для использования (то же самое для bootmem). Память CMA может использоваться другой системой (в основном пользовательским пространством), и если драйверу нужна эта память, управление памятью восстановит память CMA для драйвера. Ничего не потрачено впустую. И CMA сейчас ОБЪЕДИНЕН в основную ветку, в версии 3.5, но самая новая версия — v3.5-rc6, так что вам, возможно, придется подождать 2-3 недели для версии 3.5 или использовать версию -rc. - person Lai Jiangshan; 14.07.2012
comment
Ты прав. Это в 3.5-rc6. И я абсолютно согласен с тем, что CMA кажется гораздо более приятным интерфейсом, чем mem= чепуха. А возможность использовать неиспользуемые части для кэширования — приятный бонус. Спасибо, что сообщили мне об этом! - person Bill Lynch; 15.07.2012
comment
@sharth: дайте мне знать (или измените принятый ответ), если вы наконец используете CMA. - person Lai Jiangshan; 17.07.2012