Vfs cache pressure android

imoseyon

Thursday, January 20, 2011

Sysctl tweaking for faster, longer lasting Android

If your ROM supports sysctl, you can do lots of cool things. (Well even if your ROM doesn’t you can as long as you’re rooted with busybox, but it takes a bit more work).

In this post, let’s focus on three settings: vm.dirty_ratio, vm.dirty_backgroud_ratio, and vm.vfs_cache_pressure.

vm.dirty_ratio and vm.dirty_background_ratio control how often kernel writes data to «disk» (well in our case the microSD card). When your apps write data to disk, Linux actually doesn’t write the data out to disk right away, it actually writes the stuff to system memory and the kernel handles when/how the data is actually going to be flushed to disk.

I dunno — how much difference can it actually make? We’re not talking about traditional hard drives with spindles, we’re talking about solid state stuff. I suppose there could be a slight savings in battery life and increase in performance if you delay the data flush as much as you can.

I ended up with:

vm.dirty_ratio = 90
vm.dirty_background_ratio = 70

Now vm.vfs_cache_pressure is much more interesting. File system cache (dentry/inode) is really more important than the block cache above, so we really want the kernel to use up much of the RAM for them. The default value is 100, and what you want to do is lower that value to tell the kernel to favor the file system cache and not drop them aggressively.

You can also take it a step further and set it to 1 (lowest possible without being dangerous). With the value of 1 the kernel will drop cache only when it’s completely out of memory.

echo 3 > /proc/sys/vm/drop_caches
# tells kernel to drop all file system caches

And what I do to ensure that the caches are dropped nightly is to run the following sl4a scripts via tasker. Cron would be better but busybox on android doesn’t seem to support it yet.

(It also reverts the dirty settings because I don’t care if my phone writes to disk aggresively while i’m sleeping and it’s being charged.)

s u -c ‘echo 3 > /proc/sys/vm/drop_caches;\
sysctl -w vm.dirty_background_ratio=3;\
sysctl -w vm.dirty_ratio=15′

su -c ‘echo 3 > /proc/sys/vm/drop_caches;\
sysctl -w vm.dirty_background_ratio=70;\
sysctl -w vm.dirty_ratio=90′

# cat /etc/sysctl.conf
# shouldn’t matter — no swap is used
vm.swappiness = 0

# try to keep at least 4MB in memory
vm.min_free_kbytes = 4096

# favor block cache
vm.dirty_ratio = 90
vm.dirty_background_ratio = 70

# extremely favor file cache
vm.vfs_cache_pressure = 1

# reboot when OOM happens
vm.panic_on_oom = 2

# wait 5 sec before rebooting when OOM
kernel.panic = 5



# currently experimenting
kernel.shmmax = 268435456
kernel.shmall = 16777216

I’ve been running at the above settings for a few days now, and the phone has been faster than ever with zero ill effects. Your mileage may vary of course.

Источник

Настройка ядра Linux для GlusterFS

Перевод статьи подготовлен в преддверии старта курса «Administrator Linux. Professional».

Периодически то тут, то там возникают вопросы о рекомендациях Gluster относительно настройки ядра и есть ли в этом необходимость.

Такая необходимость возникает редко. На большинстве нагрузок ядро работает очень хорошо. Хотя есть и обратная сторона. Исторически ядро Linux охотно потребляет много памяти, если ему предоставить такую возможность, в том числе и для кэширования в качестве основного способа повышения производительности.

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

У нас есть большой опыт работы с системами, потребляющими много памяти, такими как, CAD, EDA и подобными, которые начинали тормозить при высокой нагрузке. И иногда мы сталкивались с проблемами в Gluster. Тщательно понаблюдав не один день за используемой памятью и временем ожидания дисков мы получили их перегрузку, огромные iowait, ошибки ядра (kernel oops), зависания и т.п.

Эта статья является результатом многих экспериментов по настройке параметров, выполненных в различных ситуациях. Благодаря этим параметрам не только улучшилась отзывчивость в целом, но и значительно стабилизировалась работа кластера.

Когда дело доходит до настройки памяти, то первым делом надо смотреть на подсистему виртуальной памяти (VM, virtual memory), у которой есть большое количество опций, способных ввести вас в замешательство.

vm.swappiness

Параметр vm.swappiness определяет насколько ядро использует свопинг (swap, подкачку) по сравнению с оперативной памятью. В исходном коде он также определен как «tendency to steal mapped memory» (склонность к краже отображаемой памяти). Высокое значение swappiness означает, что ядро будет более склонно к выгрузке отображенных страниц. Низкое значение swappiness означает обратное: ядро будет меньше выгружать страницы из памяти. Другими словами, чем выше значение vm.swappiness , тем больше система будет использовать swap.

Большое использование свопинга нежелательно, так как в оперативную память загружаются и выгружаются огромные блоки данных. Многие утверждают, что значение swapiness должно быть большим, но по моему опыту, к увеличению производительности приводит установка в «0».

Подробнее можно почитать здесь — lwn.net/Articles/100978

Но, опять же, эти настройки должны применяться с осторожностью и только после тестирования конкретного приложения. Для высоконагруженных потоковых приложений этот параметр следует устанавливать в «0». При изменении на «0» отзывчивость системы улучшается.

vm.vfs_cache_pressure

Этот параметр контролирует память, потребляемую ядром для кэширования объектов каталогов и индексных дескрипторов (dentry и inode).

При значении по умолчанию в 100 ядро будет пытаться освобождать кэш dentry и inode по «справедливости» по отношению к pagecache и swapcache. Уменьшение vfs_cache_pressure приводит к тому, что ядро будет сохранять кэши dentry и inode. Когда значение равно «0», ядро никогда не будет очищать кэш dentry и inode из-за нехватки памяти (memory pressure), и это может легко привести к ошибке out-of-memory. Увеличение vfs_cache_pressure больше 100 приводит к тому, что ядро отдает приоритет выгрузке dentry и inode.

При использовании GlusterFS много пользователей с большими объемами данных и множеством маленьких файлов легко могут использовать на сервере значительное количество оперативной памяти из-за кэширования inode/dentry, что может привести к снижению производительности, так как ядру приходится обрабатывать структуры данных в системе с 40 ГБ памяти. Установка этого параметра больше 100 помогла многим пользователям добиться более справедливого кэширования и улучшить отзывчивость ядра.

vm.dirty_background_ratio и vm.dirty_ratio

Первый параметр ( vm.dirty_background_ratio ) определяет процент памяти с грязными страницами, достигнув который необходимо начать фоновый сброс грязных страниц на диск. Пока этот процент не достигнут, страницы не сбрасываются на диск. А когда сброс начинается, он выполняется в фоновом режиме, не прерывая работающие процессы.

Второй параметр ( vm.dirty_ratio ) определяет процент памяти, который может быть занят грязными страницами до начала принудительного сброса (forced flash). При достижении этого порога все процессы становятся синхронными (блокируются), и им не разрешается продолжать работу до тех пор, пока запрошенная ими операция ввода-вывода не будет фактически завершена и данные не окажутся на диске. При высоконагруженном вводе-выводе это вызывает проблему, так как кэширование данных отсутствует, и все процессы, выполняющие ввод-вывод, блокируются в ожидании ввода-вывода. Это приводит к большому количеству зависших процессов, высокой нагрузке, нестабильной работе системы и плохой производительности.

Уменьшение значений этих параметров приводит к тому, что данные чаще сбрасываются на диск и не хранятся в ОЗУ. Это может помочь системам с большим количеством памяти, для которых нормально сбрасывать на диск кэш страниц размером 45–90 ГБ, что приводит к огромному времени ожидания для фронтенд-приложений, снижая общую отзывчивость и интерактивность.

«1» > /proc/sys/vm/pagecache

Страничный кэш (page cache) — это кэш, в котором хранятся данные файлов и исполняемых программ, то есть это страницы с фактическим содержимым файлов или блочных устройств. Этот кэш используется для уменьшения количества чтений с диска. Значение «1» означает, что для кэша используется 1% ОЗУ и операций чтения с диска будет больше, чем из ОЗУ. Изменять этот параметр не обязательно, но если вы параноидально относитесь к контролю над кэшем страниц, то можете им воспользоваться.

«deadline» > /sys/block/sdc/queue/scheduler

Планировщик ввода-вывода (I/O scheduler) — это компонент ядра Linux, который обрабатывает очереди чтения и записи. Теоретически для умного RAID-контроллера лучше использовать «noop», потому что Linux ничего не знает о физической геометрии диска, поэтому эффективнее позволить контроллеру, хорошо знающему геометрию диска, как можно быстрее обработать запрос. Но похоже, что «deadline» повышает производительность. Подробнее о планировщиках можно прочитать в документации к исходному коду ядра Linux: linux/Documentation/block/*osched.txt . И также я наблюдал увеличение пропускной способности чтения во время смешанных операций (много операций записи).

«256» > /sys/block/sdc/queue/nr_requests

Количество запросов ввода-вывода в буфере перед тем как они передаются планировщику. Размер внутренней очереди некоторых контроллеров (queue_depth) больше, чем nr_requests планировщика ввода-вывода, так что у планировщика ввода-вывода мало шансов правильно приоритезировать и выполнить слияние запросов. Для планировщиков deadline и CFQ лучше, когда nr_requests в 2 раза больше внутренней очереди контроллера. Объединение и переупорядочивание запросов помогает планировщику быть более отзывчивым при большой нагрузке.

echo «16» > /proc/sys/vm/page-cluster

Параметр page-cluster управляет количеством страниц, которые записываются в своп за один раз. В приведенном выше примере значение устанавливается равным «16» в соответствии с размером страйпа (stripe size) RAID в 64 КБ. Это не имеет смысла при swappiness = 0, но если вы установили swappiness в 10 или 20, то использование этого значения поможет вам, когда размер страйпа RAID составляет 64 КБ.

blockdev —setra 4096 /dev/ devname > (-sdb, hdc или dev_mapper)

Настройки блочных устройств по умолчанию для многих RAID-контроллеров часто приводят к ужасной производительности. Добавление вышеуказанной опции, настраивает упреждающее чтение для 4096 * 512-байтных секторов. По крайней мере, для потоковых операций увеличивается скорость, наполняя встроенный кэш диска за счет упреждающего чтения в течение периода, используемого ядром для подготовки ввода-вывода. В кэш могут помещаться данные, которые будут запрошены при следующем чтении. Слишком большое упреждающее чтение может убить случайный ввод-вывод для больших файлов, если он использует потенциально полезное время диска или загружает данные за пределами кэша.

Ниже приведены еще несколько рекомендаций на уровне файловой системы. Но они еще не были протестированы. Убедитесь, что ваша файловая система знает размер страйпа и количество дисков в массиве. Например, что это массив raid5 с размером страйпа 64K из шести дисков (фактически из пяти, потому что один диск используется для четности). Эти рекомендации основаны на теоретических предположениях и собраны из различных блогов/статей экспертов по RAID.

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

ВНИМАНИЕ! Все, что описано выше крайне субъективно для некоторых типов приложений. Эта статья не гарантирует какие-либо улучшения без предварительного тестирования соответствующих приложений со стороны пользователя. Ее следует применять только в случае необходимости улучшения общей отзывчивости системы или, если она решает текущие проблемы.

Источник

Z-Ram, Swappiness, Dirty Ratios, VFS_cache_pressure and how they all interact

Nolfer

Senior Member

Hey there, android enthusiasts!
Hopefully this post will gather many experienced users and solve these problems and doubts once and for all.
I’ve searched pretty much everywhere on google and the usual material showed up, copied and pasted around the web.

So I’m posting here, hoping that developers and hackers come and share their precious knowledge, producing new material that will put light in this often misunderstood field.

1) What does vfs_cache_pressure do? How does it interact with RAM and Swappiness?

2) What happens when I have Z-Ram enabled and Swappiness set at 0?

3) Are the init.d tweaks by franco’s developers team still good for Nougat and Oreo? I understand these guys know what they do and put a good amount of effort in finding the best settings, however maybe they were wrong, or they intended to engineer them for a different kind of usage (I’m thinking about the perennial debate between Performance, Balanced, and Multitasking).
The VM tweak sets Swappiness at 0. Is this stupid if I have z-ram on because that z-ram will never be used?

4) That also tweaks vfs_cache_pressure at 100. Why not using lower values of vfs_cache_pressure like 50, or even 30 or 10? These all raise perceived performance and overall fluidity, at the expense of real performance. Even though this seems counterintuitive, one only needs to try these settings to be convinced of their value in overall fluidity and smoothness (to know more about that, see Tales from Responsivenessland by Rudd-o, and also Imoseyon’s Sysctl tweaking for faster, longer lasting Android)

5) What about dirty_ratio and dirty_background_ratio? Why values of 20 and 5 respectively? What happens if we set them at, say, 90 and 55? How do they interact with swappiness and vfs_cache_pressure? I remember reading somewhere that setting them high would delay writes and save battery, but at what price?

6) How do dirty_background_ratio, dirty_ratio, swappiness and vfs_cache_pressure all interact with low memory killer values?

7) Not related: What does the Arch Power option do, exactly? Why is it good/bad for x or y?

8) What is RQ Affinity and how should I set it and why?

Источник

Блог начинающего линуксоида.

советы, руководства, инструкции.

Страницы

среда, 10 июня 2015 г.

Устраняем тормоза системы при операциях ввода-вывода, или вспомним о #12309

Баг #12309 — самый знаменитый баг в ядре Linux, довольно долго досаждавший пользователям Linux на десктопах. Сам баг исправлен в ядре Linux 3.3, но симптомы, похожие на таковые при 12309, могут проявляться на некоторых конфигурациях до сих пор. В сети можно найти много инструкций по лечению этих симптомов. Приведу в пример статью с сайта linux.org.ru, оригинал которой можно найти по ссылке с некоторыми дополнениями.

На самом деле 12309 — это не один, а несколько багов, смешанных в кучу. Можно выделить следующие случаи появления:

при копировании больших объемов данных с диска на диск (или с раздела на раздел одного диска);
при нехватке ОЗУ (и, соответственно, диком своппинге);
при копировании на USB-девайсы;
при использовании зашифрованных разделов;

Соответственно, фиксы тоже будут разные.

Сначала тест: восприимчива ли ваша система к 12309? введите в терминале:

dd if=/dev/zero of=/tmp/test bs=1M count=1M

и понаблюдайте за отзывчивостью системы. Если всё по-прежнему быстро — то читать статью можно разве что для профилактики и расширения кругозора.

Оптимистическое выделение памяти

Возможно, в научных программах какого-нибудь толка позволить выделить терабайт ОЗУ при наличии 3 Гб физической памяти и считается приемлемым, но на десктопе, где много процессов должны спокойно сосуществовать, такой расклад неприемлем — зажравшаяся программа спокойно вытеснит все остальное, после чего система практически остановится. Хуже всего то, что суть бага 12309 в том, что ядро принимает решения о том, какие страницы вытеснять, мягко говоря, неоптимально, а чинить это долго, муторно, и не в каждой ситуации решение будет приемлемым.

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

Пока что же можно сделать так, чтобы на явно дикие запросы malloc() отвечал решительным отказом, и чтобы зажратость программы определялась на этапе выделения памяти, а не тогда, когда программа радостно вывалит туда пару гигабайт данных.

Для этого нужно прописать в /etc/sysctl.conf

Максимум памяти, который можно будет выделить, будет равен в сумме
объему свопа + некоторому проценту физической памяти. Этот процент по
умолчанию равен 50, но можно его несколько увеличить. Во всяком случае, я
выставил его в 80 и пока что катастроф нет.

Некоторые люди полагают, что если отключить своп, то 12309 исчезнет. А вот как бы не так. Своп (swap) — это хранилище анонимных страниц памяти. Код исполняемых программ и всяких библиотек не анонимен и по умолчанию не изменяем. В то время как на 32-битных системах исполняемый код зачастую зависим от позиции (начального адреса), что приводит к тому, что, во-первых, динамический линковщик проводит вычисление смещений каждый раз при загрузке и, соответственно, страницы кода анонимны (это несет с собой недостаток в виде наличия нескольких копий одной и той же библиотеки, но и преимущество в виде невозможности вытеснить страницы кода для освобождения памяти), то на 64-битных системах практически весь код линкуется в независимом от позиции виде (PIC).

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

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

Уменьшение размеров дисковых буферов

С одной стороны, отдавать под дисковые буферы практически всю свободную память — здравая идея. А с другой стороны, чем больше ОЗУ, на самом деле, тем сильнее это способно ударить в критической ситуации.

Это работает вот как. У ядра есть буфер файловой системы. Мы пишем много данных. Этот буфер заполняется грязными страницами, а потом выполняется системный вызов sync() и буфер сбрасывается на носитель. Чем больше буфер, тем больше данных надо будет сбрасывать. Все бы ничего, да вот когда кому-то вдруг вздумается выделить себе памяти, в первую очередь будут сбрасываться все эти буферы, и если при этом вдруг надо будет закачать страницы с исполняемым кодом, им опять-таки придется ждать в очереди. Опять слайдшоу, с возможной цепной реакцией.

То есть, кеш на чтение — это ничего так, а слишком большой кеш на запись способен встать поперек горла в критических случаях.

Есть еще одна неприятная особенность, связанная трудно сказать, с чем — возможно, с реализацией DMA, но вполне возможно, что не с ней, или не только с ней. Берем какой-нибудь медленный для записи носитель, типа той же USB-флешки, и пробуем записать на него данных побольше, фильм какой или что-то навроде. Мы увидим, что происходит это рывками — сначала заполняется буфер, сколько влезет, а потом весь сбрасывается, потом весь заполняется. и так далее. При этом суммарно потраченное время почему-то ощутимо больше, чем как если бы мы примонтировали носитель с -o sync, а скорость записи на, собственно, носитель невообразимо мала.

Но если уменьшить порог количества грязных блоков, после которого начнется их сброс на носитель, не до сверхмалых величин, но все же — это позволит проводить зачитку данных из источника и запись на носитель параллельными DMA-трансферами. Я у себя выставил этот объем равным 2 мегабайтам, что, с одной стороны, уменьшает количество перезаписей в случае частой смены маленьких файлов и значительно увеличивает скорость переноса больших объёмов данных. Возможно, если поиграться размером, можно найти оптимальное быстродействие, но не думаю, что буфер больше 16 мегабайт будет эффективным.

echo 2097152 >/proc/sys/vm/dirty_bytes
echo 2097152 >/proc/sys/vm/dirty_background_bytes

Для сохранения после перезагрузки, прописать в /etc/sysctl.conf

Стоит учесть, что кеши чтения файловой системы будут все так же занимать почти все свободное ОЗУ, но при этом запись будет осуществляться, как только блоков, помеченных на запись, наберется на 2 мегабайта.

Значение dirty_bytes должно делиться на 4096 нацело.

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

Кеш файловых систем

Иногда бывает такая проблема: у вас относительно новое ядро, тесты с dd проходят на ура, а вот когда надо много маленьких файликов создавать/менять/убивать, например, командой dpkg, система встает колом и не может даже регистрами пошевелить.

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

По умолчанию оно почему-то 100, что просто безумно на десктопных нагрузках.

Установить параметр swappiness равным 10 или 5, чтобы подкачка задействовалась только при исчерпании 90 и 95% памяти соответственно:

sudo nano /etc/sysctl.conf

Добавить в конец vm.swappiness = 10

Сохранить и выполнить sudo sysctl -p

Сменить планировщик ввода-вывода. В такой ситуации рекомендуют использовать BFQ, но он не в основной ветке ядра, и его нужно добавлять в ядро

самому (в некоторых дистрибутивах, например Calculate Linux, BFQ по умолчанию). В остальных же случаях можно сменить планировщик на лету.

Перевесить системные прерывания на одно ядро (на многоядерном процессоре) скриптом:

for interruption in `grep usb /proc/interrupts | awk ‘‘| sed ‘s/\://g’` ; do

echo 1 > /proc/irq/$/smp_affinity;

При самостоятельной сборке ядра, задействовать 100Hz таймер ядра и опцию No Force Preemption (Server) mode.

Выставить приоритет ionice для ядра 1 (realtime) для пространства пользователя (userspace) — 3.

Установить ядро с патчами для реализации режима реального времени (linux-lowlatency, есть по умолчанию в репозиториях

Подводя итог, можно отметить: самого бага давно нет, но на некоторых конфигурациях могут возникнуть его симптомы, по совершенно

разным причинам, от нехватки памяти до аппаратных проблем с дисками. Пугаться этого не стоит, ибо например в Windows, эта проблема

ещё более серьёзна, а самое главное — никак не решаемая. Система может с лёгкостью встать колом при копировании больших объёмов данных,

и её придётся перезагружать кнопкой Reset. Неоднократно с этим сталкивался. А вот симптомы 12309 удалось увидеть лишь при копировании фильма с

NTFS-раздела на старую, потрёпанную жизнью, флешку. И то потом проблему так и не удалось воспроизвести, потому списал на случайность.

Обзор планировщиков ввода-вывода

Статья о решении проблем с 12309 (на английском).

Источник

Читайте также:  Dolphin emulator android vulkan
Оцените статью