ux31a congela quando está sem memória

3

Tenho dificuldades em entender a política de troca. Eu instalei o sistema (Ubuntu 13.04 mas 12.10 teve o mesmo problema) com 4GB de partição swap porque o ux31a tem 4 GB de memória.

O problema é que toda vez que o sistema fica sem memória e começa a escrever para trocar, ele pára de responder. Congela por 5 minutos.

Então eu pensei, depois de algumas leituras, que talvez eu deva configurar a permuta para 10 e eu fiz. Depois que o sistema ficou sem memória - mesmo problema.

Então eu li SSD não deve ter nenhuma troca e eu configurei para desligar quando o sistema for iniciado

Agora eu tenho a troca desativada e meu free -m parece:

             total       used       free     shared    buffers     cached
Mem:          3840       3340        499          0         33       1293
-/+ buffers/cache:       2013       1827
Swap:            0          0   

Infelizmente, o problema permanece sem solução. Parece buffers / cache comer toda a memória e quando a memória chega a 0 eu tenho exatamente o mesmo problema. Eu pensei que buffers / cache deveriam automaticamente liberar alguma memória quando necessário, mas eu acho que isso não acontece

O que posso fazer para evitar congelamentos do sistema?

informações adicionais: quando o sistema congela depois de um tempo ele pode responder a alguns elogios e eu consegui consolar em sessões diferentes (ctrl + alt + f1) e rodar "top". Primeiros processos kswapd0, kworkers comeram CPU inteira.

Agradecemos antecipadamente por sua ajuda

    
por Mateusz Juraszek 07.05.2013 / 16:37

2 respostas

0

Eu também tive problemas com o kworker comendo toda a memória. Isso pareceu ajudar, como root:

echo N > /sys/module/drm_kms_helper/parameters/poll

Há também outro post sobre isso na internet

    
por Robert 13.05.2013 / 12:09
0

Eu corro sem swap, assim como você, e a fim de evitar qualquer congelamento do sistema operacional estou executando um patch de kernel customizado (também colado abaixo, mas as guias se tornaram espaços), o que funciona para mim, mas como não sou desenvolvedor, não posso garantir que não seja fazendo qualquer outra coisa que não deveria estar fazendo.
Estou executando o kernel com patches no dom0 e nas VMs do Qubes OS 4.0, e o apliquei sobre os kernels 4.18.9 e 4.19-rc5 mesmo. É fácil testá-lo nas VMs do Qubes, porque o sudo iotop do dom0 pode mostrar a surra do disco (apenas leitura, sem escrita) que ocorre quando a VM está congelada devido à falta de memória. O problema é que ele despeja as páginas de código dos arquivos executáveis, então eles precisam ser relidos no disco em cada comutador de contexto .

Aqui é um código que pode emular alto uso de memória, você pode usá-lo para testes. Em resumo, algo assim:

$ stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 + 4000;}' < /proc/meminfo)k --vm-keep -m 4 --timeout 10s

Aqui é o patch do kernel que evita qualquer congelamento do sistema operacional e apenas permite o acionamento normal do oom-killer para eliminar o processo que usa a maior parte da RAM (guias substituídas por espaços nessa colagem):

revision 3
preliminary patch to avoid disk thrashing (constant reading) under memory pressure before OOM-killer triggers
more info: https://gist.github.com/constantoverride/84eba764f487049ed642eb2111a20830

diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 32699b2..7636498 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -208,7 +208,7 @@ enum lru_list {

 #define for_each_lru(lru) for (lru = 0; lru < NR_LRU_LISTS; lru++)

-#define for_each_evictable_lru(lru) for (lru = 0; lru <= LRU_ACTIVE_FILE; lru++)
+#define for_each_evictable_lru(lru) for (lru = 0; lru <= LRU_INACTIVE_FILE; lru++)

 static inline int is_file_lru(enum lru_list lru)
 {
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 03822f8..1f3ffb5 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2086,9 +2086,9 @@ static unsigned long shrink_list(enum lr
                 struct scan_control *sc)
 {
    if (is_active_lru(lru)) {
-       if (inactive_list_is_low(lruvec, is_file_lru(lru),
-                    memcg, sc, true))
-           shrink_active_list(nr_to_scan, lruvec, sc, lru);
+       //if (inactive_list_is_low(lruvec, is_file_lru(lru),
+       //           memcg, sc, true))
+       //  shrink_active_list(nr_to_scan, lruvec, sc, lru);
        return 0;
    }

@@ -2234,7 +2234,7 @@ static void get_scan_count(struct lruvec *lruvec, struct mem_cgroup *memcg,

    anon  = lruvec_lru_size(lruvec, LRU_ACTIVE_ANON, MAX_NR_ZONES) +
        lruvec_lru_size(lruvec, LRU_INACTIVE_ANON, MAX_NR_ZONES);
-   file  = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) +
+   file  = //lruvec_lru_size(lruvec, LRU_ACTIVE_FILE, MAX_NR_ZONES) +
        lruvec_lru_size(lruvec, LRU_INACTIVE_FILE, MAX_NR_ZONES);

    spin_lock_irq(&pgdat->lru_lock);
@@ -2345,7 +2345,7 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc
             sc->priority == DEF_PRIORITY);

    blk_start_plug(&plug);
-   while (nr[LRU_INACTIVE_ANON] || nr[LRU_ACTIVE_FILE] ||
+   while (nr[LRU_INACTIVE_ANON] || //nr[LRU_ACTIVE_FILE] ||
                    nr[LRU_INACTIVE_FILE]) {
        unsigned long nr_anon, nr_file, percentage;
        unsigned long nr_scanned;
@@ -2372,7 +2372,8 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc
         * stop reclaiming one LRU and reduce the amount scanning
         * proportional to the original scan target.
         */
-       nr_file = nr[LRU_INACTIVE_FILE] + nr[LRU_ACTIVE_FILE];
+       nr_file = nr[LRU_INACTIVE_FILE] //+ nr[LRU_ACTIVE_FILE]
+           ;
        nr_anon = nr[LRU_INACTIVE_ANON] + nr[LRU_ACTIVE_ANON];

        /*
@@ -2391,7 +2392,8 @@ static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memc
            percentage = nr_anon * 100 / scan_target;
        } else {
            unsigned long scan_target = targets[LRU_INACTIVE_FILE] +
-                       targets[LRU_ACTIVE_FILE] + 1;
+                       //targets[LRU_ACTIVE_FILE] + 
+                       1;
            lru = LRU_FILE;
            percentage = nr_file * 100 / scan_target;
        }
@@ -2409,10 +2411,12 @@ static void shrink_node_memcg(struct pgl
        nr[lru] = targets[lru] * (100 - percentage) / 100;
        nr[lru] -= min(nr[lru], nr_scanned);

+       if (LRU_FILE != lru) { //avoid this block for LRU_ACTIVE_FILE
        lru += LRU_ACTIVE;
        nr_scanned = targets[lru] - nr[lru];
        nr[lru] = targets[lru] * (100 - percentage) / 100;
        nr[lru] -= min(nr[lru], nr_scanned);
+       }

        scan_adjusted = true;
    }

OBSERVAÇÃO: não recomendo usar isso em produção. Como eu disse, eu não sou um desenvolvedor e esse patch é mais como uma prova de conceito: ele tenta remover da RAM as Active(file) páginas quando sob alta pressão de memória, e assim a mudança de contexto não precisa leia os arquivos executáveis do disco durante sua execução, assim ele não congelará o SO devido à lentidão de reler esses executáveis do disco.

    
por Marcus Linsner 31.08.2018 / 11:29

Tags