Как сообщить Linux, что страницу mmap() не нужно записывать для подкачки, если требуется резервная физическая страница?

Надеюсь, заголовок понятен. У меня есть кусок памяти, полученный через mmap(). Через некоторое время я пришел к выводу, что данные в этом диапазоне мне больше не нужны. Тем не менее, я все еще хочу сохранить этот диапазон. То есть я не хочу вызывать mummap(). Я пытаюсь быть хорошим гражданином и не заставлять систему менять больше, чем нужно.

Есть ли способ сообщить ядру Linux, что если данная страница поддерживается физической страницей и если ядро ​​решает, что эта физическая страница ему нужна, не утруждайте себя записью этого страницу поменять?

Я предполагаю, что под капотом этот волшебный вызов функции уничтожит любое сопоставление между данной виртуальной страницей и физической страницей, если она присутствует, без предварительной записи в своп.


person tgoodhart    schedule 23.12.2011    source источник
comment
Что не так с мунмап? Он делает именно то, что вы говорите, что хотите. Если вы хотите гарантировать, что более поздняя mmap не будет повторно использовать один и тот же виртуальный адрес, вы можете mmap с MAP_FIXED+PROT_NONE после munmap, чтобы зарезервировать адреса...   -  person Chris Dodd    schedule 23.12.2011
comment
Откуда вы знаете, что он это делает (записывает резервную физическую страницу в своп)?   -  person Janus Troelsen    schedule 23.12.2011
comment
@ChrisDodd Я мог бы использовать munmap() только в том случае, если бы я мог гарантировать, что последующий вызов mmap(), сделанный с соответствующими параметрами, повторно зарезервирует ту же страницу. Именно это отсутствие гарантии того, что второй mmap() будет успешным, мешает мне использовать munmap(). Важно, чтобы начало и конец моего фрагмента памяти не менялись, даже если я знаю в разное время, что определенные страницы больше не содержат полезных данных.   -  person tgoodhart    schedule 23.12.2011
comment
@user309483 user309483 Думаю, я не уверен, что эти страницы написаны для обмена, но опять же, это просто для того, чтобы быть хорошим гражданином в системе. В том случае, если они будут записаны в своп, я хочу избавить систему от усилий.   -  person tgoodhart    schedule 23.12.2011


Ответы (2)


Ваш вопрос (как указано) не имеет смысла.

Давайте предположим, что у вас есть способ сказать ядру делать то, что вы хотите.

Давайте также предположим, что ему действительно потребовалась дополнительная оперативная память, поэтому он забрал вашу страницу, а не заменил ее.

Теперь ваша программа пытается прочитать эту страницу (поскольку вы не хотите munmap данных, вероятно, вы можете попытаться получить к ним доступ). Что делать ядру? Варианты, которые я вижу:

  1. это может дать вам новую страницу, заполненную 0.
  2. это может дать вам SIGSEGV

Если вам нужен вариант 2, вы можете добиться того же результата с помощью munmap.

Если вам нужен вариант 1, вы можете mremap заменить существующее сопоставление с помощью MAP_ANON (или munmap с последующим новым mmap).

В любом случае вы не можете полагаться на старые данные, когда они вам понадобятся.

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

РЕДАКТИРОВАТЬ:

Возможно, вы ищете madvise(..., MADV_DONTNEED)

person Employed Russian    schedule 23.12.2011
comment
Идеальный! madvise() — это именно то, что я искал. Поведение, подобное (1), - это то, что я хотел бы, хотя нулевое заполнение не требуется. Подойдет любой мусор. Есть ли в вашей системе mremap() флаг MAP_ANON? В моей документации этого нет. - person tgoodhart; 23.12.2011

Вы можете munmap регион, затем mmap еще раз с MAP_NORESERVE

Если вы знаете во время начального сопоставления, что подкачка не нужна, используйте MAP_NORESERVE

person Basile Starynkevitch    schedule 23.12.2011
comment
Нет никакой гарантии, что второй mmap() будет успешным. - person tgoodhart; 23.12.2011