Воооот. Шелл долго стартует. Теперь, две эти задачи уведи с системного винта на некий посторонний, и убедись, что система один фиг хренеет, хотя инвалидировать кусок памяти и замапить туда пару метров какого-то баш с библиотеками первой необходимости (да и то, половина уже в shared сидит) с простаивающего винта - большая проблема. Это при том, что сегодня уже даже по отдельному каналу на винт везде, кэшей в винтах до задницы, а сабж всё еще ждет, пока «дискетка доформатируется».
Теперь, две эти задачи уведи с системного винта на некий посторонний, и убедись, что система один фиг хренеет, хотя инвалидировать кусок памяти и замапить туда пару метров какого-то баш с библиотеками первой необходимости (да и то, половина уже в shared сидит)
Не сидит уже. В том и дело, что чтение из источника вроде /dev/zero переполняет любой кэш, и там уже ничего нет, кроме нулей. И, естественно, неважно, что у диска есть свой канал - это не проблема IO.
Ну, как минимум, приоритет кэша всегда ниже buffers, shared, RSS. Таким образом, ни при каких условиях кэширование не выбивает уже отмапленные работающие приложения и используемые ими библиотеки. Потому что кэш - это «а вдруг еще раз понадобится», а shared, RSS и buffers - это «да, понадобится, может, не сейчас, но 146% понадобится». Ну, и автоматическое освобождение тех же библиотечных сегментов shared при умирании последнего процесса, их использующего.
А по поводу переполнения кэша чтением из /dev/zero... Так разве нельзя различать источники по признаку volatile/stable/immutable ? Тот же /dev/zero в таком случае в кэше можно было бы либо не писать (а /dev/null и подавно), либо писать 1 байт, т.к. он иммутабельный при любом аргументе (адресе смещения/размере считываемого блока/т.п.) Локальные файловые системы, к примеру, вполне себе можно отнести к stable. Внешние (и да, /dev/u?random) - да, volatile.
Да и эффективность (кол-во действий по изменению конфигурации/наведению порядка) работы за счет «commit check»/rollback/compar и т.п. возрастает многократно.
Ну, как минимум, приоритет кэша всегда ниже buffers, shared, RSS
Вообще-то во всех современных Unix давно unified page cache (а RSS - это вообще из другой оперы); буферы - просто вспомогательные структуры ввода-вывода.
Таким образом, ни при каких условиях кэширование не выбивает уже отмапленные работающие приложения и используемые ими библиотеки.
Тогда «12309» будет выглядеть так:
создать файл размером с память;
замапить этот файл и прочитать по байту с каждой страницы
кэш - это «а вдруг еще раз понадобится», а shared, RSS и buffers - это «да, понадобится, может, не сейчас, но 146% понадобится».
Оба раза «нет». Всё зависит от access patterns, которые нельзя предсказать (и снова напоминаю - buffers и page cache - одно и то же); поэтому же нельзя однозначно дать приоритет страницам, считанным с внешней памяти, перед страницами анонимной памяти.
Проблемы, похожие на эту проблему с /dev/zero, элементарно решаются, если известен access pattern - было даже предложение добавить флаг открытия O_STREAM.
Ну, и автоматическое освобождение тех же библиотечных сегментов shared при умирании последнего процесса, их использующего.
У shared-страниц (объектов, на самом деле) уменьшается счетчик использования.
А по поводу переполнения кэша чтением из /dev/zero... Так разве нельзя различать источники по признаку volatile/stable/immutable ?
Нет, не имеет (хоть я и не понял, в чем разница volatile и stable). Просто потому, что не имеет большого смысла защищаться от подобного использования /dev/zero (его роль вполне может сыграть само приложение).
хоть я и не понял, в чем разница volatile и stable
Аналогия взята из посгресовой доки по хранимкам:
IMMUTABLE indicates that the function cannot modify the database and always returns the same result when given the same argument values; that is, it does not do database lookups or otherwise use information not directly present in its argument list...
STABLE indicates that the function cannot modify the database, and that within a single table scan it will consistently return the same result for the same argument values, but that its result could change across SQL statements...
VOLATILE indicates that the function value can change even within a single table scan, so no optimizations can be made...
---------
/dev/null невозможно прочитать :)
Скажем так, попытка чтения из него вернет 0 байт в шелле, как там в IO - пусть даже ошибку, не суть важно.
Почему же? /dev/zero - immutable (всегда возвращает 1 char, независимо от параметров чтения), любой файл в mount:!_netdev - stable (файлуха управляется локально и только локально, любая запись в нее просто инвалидирует кэш соответствующих объектов, если есть, чтение одних и тех же блоков между операциями записи в них гарантированно возвращает одни и те же данные), любой файл в mount:_netdev - volatile (хрен его знает, сколько там рыл пишут, как пишут и будет ли в случае чего отправлен NOTIFY об изменениях, зависит от протокола, никакого кэширования в принципе быть не может). Хотя с _netdev сабж (и не только он) сразу скатится в УГ по операциям с сетевыми файловыми системами, но ведь можно в случае чего прикрутить возможность зафорсить соответствующий тип поведения файлухи, даже сетевой, типа «хотите STABLE/IMMUTABLE на _netdev - да ради б_га, но на свой страх и риск». Тут даже iscsi вписывается (STABLE будет, ага).