Antes de experimentar os ajustes em questão, convém monitorar o seu sistema durante uma simulação, a fim de confirmar o problema. O sintoma mais óbvio é a lentidão, mas se você quiser ir mais a fundo, pode monitorar a quantidade de dirty memory com o seguinte comando:
# watch -n1 grep -e Dirty: /proc/meminfo
Enquanto monitora, copie um arquivo grande, de alguns gigabytes, para um pendrive (não vale aquele pendrive USB 3.0 de última geração, hein?). Observe a dirty memory aumentar assustadoramente, para alguns GBs, até que o pdflush entra em ação e começa a escrever os dados no dispositivo.
Percebeu que, aparentemente, a cópia rapidamente deu-se como concluída, mas na prática ela estava longe de terminar? Daí a importância de não remover o pendrive sem ejetar antes: podem haver muitos dados pendentes de escrita em background, e a operação de ejeção só vai concluir após eles estarem devidamente gravados.
Agora, vamos ao tuning: os parâmetros importantes aqui são "vm.dirty_background_bytes", "vm.dirty_background_ratio", "vm.dirty_bytes" e "vm.dirty_ratio". Na documentação do kernel você encontra uma explicação detalhada do que cada parâmetro faz [5], mas pelos nomes já dá para ter uma ideia. Só há um detalhe: os parâmetros com "bytes" e "ratio" são mutuamente exclusivos, ou seja, ajustando um, o outro automaticamente é desabilitado (ficando com valor 0). No meu sistema, os valores default são:
- vm.dirty_background_bytes = 0
- vm.dirty_background_ratio = 20
- vm.dirty_bytes = 0
- vm.dirty_ratio = 50
Perceba que até 50% da memória RAM total pode ser dirty! Vamos então ajustar os parâmetros para uma das recomendações, e ver o que acontece, repetindo a simulação:
# sysctl -w vm.dirty_background_bytes=16777216
# sysctl -w vm.dirty_bytes=50331648
# watch -n1 grep -e Dirty: /proc/meminfo
(repetir cópia do arquivo)
Bem diferente, não é? Sem contar que agora o indicador de progresso da cópia é mais confiável.
Outra opção, que dá resultados similares mas trabalha com percentuais da memória RAM, ao invés de valores absolutos em bytes, é:
# sysctl -w vm.dirty_background_ratio=5
# sysctl -w vm.dirty_ratio=10
Conclusão
Tal situação de "bufferbloat" é mais usual em desktops, onde é comum realizar a cópia de arquivos grandes para pendrives lentos, mas é também possível de acontecer, com cenários alternativos, em servidores, sendo importante conhecer o problema, a solução, e o que está por trás dela. Claro que os valores sugeridos no tuning são, como disse, recomendações; o ideal para o seu caso pode variar.
O que acho mais interessante em solucionar esses problemas é que, quando queremos ir além do básico, além da receita de bolo, aprendemos muito. Espero que também tenha sido sua percepção, e se quiser ir ainda além, é só explorar as referências.
Referências
[1]
http://yarchive.net/comp/linux/dirty_limits.html
[2]
http://lwn.net/Articles/682582/
[3]
http://unix.stackexchange.com/questions/107703/why-is-my-pc-freezing-while-im-copying-a-file-to-a-pendrive/107722#107722
[4]
http://askubuntu.com/questions/397249/system-freezes-unresponsive-unusable-when-copying-large-file-to-usb
[5]
https://www.kernel.org/doc/Documentation/sysctl/vm.txt