LINUX.ORG.RU

убивство ядра 3.0

 ,


0

2

имеется система на старом ядре

3.0.0-31-generic #48-Ubuntu SMP Mon Feb 4 13:22:36 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
причем ядро менять нельзя (точнее крайне нехочется)

и процесс который циклически отжирает почти всю имеющуюся память выделяя и заполняя массив [1024][1024][4096].

Если не дай бог ещё что-то знатно потребляет память (огнелис к примеру), то система просто падает в куищще, а надо чтоб убился тот самый процесс с массивом (Убивать его нестрашно - всё равно отладка)

подскажите что можно в системе поднастроить..

ps кстати не пойму почему оно swap не задействует - он при полностью отожранной оперативке, занят процентов на %10 всего.

решено

ошибка вызывавшая reboot была где-то между firefox, ядром и (возможно) nvidia-блобом. убивство ядра 3.0 (комментарий)

★★★★★

Последнее исправление: MKuznetsov (всего исправлений: 1)

кстати не пойму почему оно swap не задействует

почетай про пейдж реклейминк

anonymous
()

убивство ядра 3.0

убивство

куме, та ви брешете!

ZuBB ★★★★★
()
Ответ на: комментарий от anonymous

нострой ООМ Киллер

и как его настроить на убийство конкретного процесса ?

Причём по факту процесс получает всё требуемое (то есть malloc`и не NULL, при заполнении памяти SIGSEGV не приходят - это контроллируется запускающим процессом), и лишнего он не запрашивает.

Всего памяти в системе 6G + 4G swap = 10G, ребут происходит при исчерпании ОЗУ, при фактически свободном swap`е. Если б был kernel-panic или начали валиться другие процессы, ну хоть какие хреновые записи в syslog было-б понятно. Но сцуко reboot и всё.

страшновато отлаживать софтинку с риском порчи ФС и всей системы :)

MKuznetsov ★★★★★
() автор топика
Ответ на: комментарий от roy

А может память битая? Так, пальцем в небо

сильно-сильно вряд-ли. Машинка работает стабильно, глюков не наблюдается. Да и отлаживаемая программа, если её запускать в одиночку проходит ночные тесты, за ночь делая несколько тысяч циклов. Не думаю, что при этом часть физ.памяти на плашках остаётся незадействованной.

на всяк случай вечером прогоню memtest`ы

MKuznetsov ★★★★★
() автор топика
Ответ на: комментарий от MKuznetsov

reboot и всё

Это свидетельствует о проблеме с железом.

anonymous
()

почитай логи, если это OOM Killer, то там будет запись об этом.

Но не похоже, ибо OOM убивает что-то, что много жрёт. Значит проблема в железе.

своп и не должен юзаться, ибо ядро считает, что твой массив _нужный_, и его нельзя свопить

drBatty ★★
()
Ответ на: комментарий от drBatty

своп и не должен юзаться, ибо ядро считает, что твой массив _нужный_, и его нельзя свопить

И с чего же это оно будет так считать?

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

И с чего же это оно будет так считать?

потому-что твой код его дро^Wиспользует постоянно. Потому оно в RES, а не в VIRT.

drBatty ★★
()

можно его в свою мемори цгруппу и подтюнить кол-во памяти и свопа, которые он может отжирать

qnikst ★★★★★
()
Ответ на: комментарий от drBatty

потому-что твой код его дро^Wиспользует постоянно

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

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

Попробовать что, пучок из 4 миллиардов проводов? Ты сам-то для начала попробуй.

нет. выдели N Gb памяти, и потыкай её рандомно. Ну или сожми что-нить программой xz (она так и делает).

я уже пробовал…

drBatty ★★
()
Ответ на: комментарий от drBatty

потому-что твой код его дро^W

кстати, не в курсе как ядро узнаёт какие используются страницы ? не счётчиками-же или временными метками..

конечно двойная-тройная косвенная адресация в C-шных массивах это тот ещё подарок для шины..но это не повод ядру неюзать swap.

MKuznetsov ★★★★★
() автор топика
Ответ на: комментарий от drBatty

Сейчас алгоритм ООМ намного более совершенней, и практически не ошибается.

У ядра появилась телепатия и он знает какие процессы можно трогать а какие нет?

true_admin ★★★★★
()
Ответ на: комментарий от MKuznetsov

это не повод ядру неюзать swap.

Слишком мало данных чтобы судить что происходит. Покажи top, free -m, ps awwux, dmesg...

slabtop пока трогать не будем.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

У ядра появилась телепатия и он знает какие процессы можно трогать а какие нет?

Нет. /proc/${PID}/oom_adj
Из того что я знаю - ssh будет убит в самом последнем случае. А вот насчет всего остального хз

Pinkbyte ★★★★★
()
Ответ на: комментарий от drBatty

нет. выдели N Gb памяти, и потыкай её рандомно. Ну или сожми что-нить программой xz (она так и делает).

Что это за бред и какие результаты это, по-твоему, должно дать? При выделении N Gb памяти, как ты её не тыкай, если физической не хватает она выгружается в своп. При рандоме будет больше чтения, посколько часть страниц нужно будет загружать из swap обратно в память, при поточном же (в оригинальном сообщении ничего про рандомный доступ, кстати, не сказано) чтений вообще не будет - всё просто уходит в swap. Разумеется ничего подобного

своп и не должен юзаться, ибо ядро считает, что твой массив _нужный_, и его нельзя свопить

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

slovazap ★★★★★
()
Ответ на: комментарий от Pinkbyte

/proc/${PID}/oom_adj

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

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

мало данных чтобы судить что происходит

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

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

Построено так - ведущий процесс в цикле запускает(fork) дочерний, который отжирает всё что можно, и должен провести анализ отожранного мусора, а пока тупо(и безрезультатно) ищет заданное слово в 2-х мерном массиве.

(подсакращённый впрочем)основной цикл «того кто жрёт память»

#define L1 1024
#define L2 1024
#define L3 4096
void snif_in_hip(char *origin,int orilen) {
        static int i,j;
        void **vec[L1];
        fprintf(stderr,"test hip\n");
        for(i=0;i<L1;i++) {
                //fprintf(stderr,"test %d\n",i);
                vec[i]=(void **)malloc(sizeof(void *)*L2);
                if (found(origin,orilen,vec[i],sizeof(void *)*L2)) {
                        printf("found in hip #1\n");
                        exit(2);
                }
                for(j=0;j<L2;j++) {
                        vec[i][j]=(void *)malloc(L3);
                        if (found(origin,orilen,vec[i][j],L3)) {
                                printf("found in hip #2\n");
                                exit(3);
                        }
                }
        }
        fprintf(stderr,"test done\n");
        return;
}

приведённый код спокойно работает ночь, мордуя туда-сюда 4,3Gb; но стоит включить ещё один потребитель, чтобы съелась вся ОЗУ - то auto-reboot :)

MKuznetsov ★★★★★
() автор топика
Ответ на: комментарий от MKuznetsov

Лучше работай с /proc/mem напрямую

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

Если он всё отожрал то как тогда другие процессы смогут запускаться?

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Если он всё отожрал то как тогда другие процессы смогут запускаться?

вот и вопрос - почему процесс эмулирующий обычное поведение (через libc, оставаясь в рамках posix) безалаберной программы вызвал крах системы. Вариантов ответа 3 штуки, и если начинать от наиболее вероятных, то это: 1) детская ошибка в программе 2) аппаратная ошибка в памяти 3) ошибка в ядре

но чтобы поймать №1, надо чтобы система в случае кризиса убивала конкретную запущенную программу, а не тупо ребутилась.

Лучше работай с /proc/mem напрямую

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

MKuznetsov ★★★★★
() автор топика

Посмотрите, сколько в /proc/meminfo в поле ″Inactive″, вроде как это тот объём памяти, которое ядро готово положить в swap.

Может поможет ″echo 2 > /proc/sys/vm/overcommit_memory″

И может у вас включёна автоматическая перезагрузка при паники ядра?

mky ★★★★★
()
Ответ на: комментарий от MKuznetsov

кстати, не в курсе как ядро узнаёт какие используются страницы ?

У каждой страницы есть дескриптор, Если обратиться к засвопенной странице возникнет аппаратное исключение page fault. Обработчик этого исключения подгрузит страничку. Так что ядро и не знает, какие используются страницы :). Только собирает статистику ну и, ЕМНИП можно указать, что страницу вообще нельзя свопить.

ziemin ★★
()
Ответ на: комментарий от ziemin

Так что ядро и не знает, какие используются страницы :)

Хотя нет, что это я. Диспетчер памяти читает/пишет эти дескрипторы. Он же и свопит.

ziemin ★★
()
Ответ на: комментарий от MKuznetsov

2) аппаратная ошибка в памяти

Ну так memtest запусти.

bhfq ★★★★★
()
Ответ на: комментарий от MKuznetsov

и как его настроить на убийство конкретного процесса

man proc

anonymous
()
Ответ на: комментарий от MKuznetsov

крах системы

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

Наверно ты меня не послушаешь, но позволь поделиться своим видением того как сделать так чтобы система не падала. Надо просто лимиты на память расставить. Через cgroups это делается очень гибко. Всё остальные решения может и интересны в плане «поковыряться», но ненадёжны.

true_admin ★★★★★
()

прогон memtest ошибок не выявил,

зато после обновления firefox (а именно он одновременно запускался) проблема сама собой исчерпалась :)

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

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

MKuznetsov ★★★★★
() автор топика
Ответ на: комментарий от slovazap

Что это за бред и какие результаты это, по-твоему, должно дать? При выделении N Gb памяти, как ты её не тыкай, если физической не хватает она выгружается в своп.

в случае ТСа как раз хватает. Вот она и не выгружается. И не должна. Судя по всему, у него система ребутится либо ДО, либо во время нехватки RAM.

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

если ты будешь юзать память последовательно, то ядро в принципе может как-то прогнозировать, что ты заюзаешь дальше, а что можно и засвопить. Если ты думаешь, что в PTE нет места для статистики - ты заблуждаешься. Вот, почитай: http://en.wikipedia.org/wiki/Page_table

Но если ты юзаешь память рандомно, то никакая статистика, и никакие кеши (в т.ч. TLB) тебе не помогут, и система не сможет никак определить, что тебе из этого надо. Будет считать, что надо ВСЁ, и свопить что-то другое. И только в крайнем случае начнёт свопить этот массив.

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

у каждой страницы есть хозяин - соотв. процесс. Массива конечно для ядра нет, а вот 4Гб памяти, которую юзает вполне конкретный процесс - есть. Есть и статистика по процессам. Именно её и собирает OOM Killer, и начисляет всем процессом score. У кого скор больше, того и убивает. Правила начисления скора очень сложные на сегодня, и учитывают Over9000 эвристик.

drBatty ★★
()
Ответ на: комментарий от MKuznetsov

vec[j]=(void *)malloc(L3); if (found(origin,orilen,vec[j],L3)) {

можешь объяснить, что происходит в этом месте, и каким образом используется vec?

ЗЫЖ я точно не знаю, но боюсь, что выделять 4096 байтов - плохая идея. Дело в том, что malloc надо выделить не только память, но и немного служебной информации там же (хотя-бы размер блока), потому выделяется не одна страница, а ДВЕ, т.е. 8192 байта. Так это или нет - зависит от версии malloc. Но я-бы не стал рисковать, и выделял например 3К, или ровно 4000 байт.

drBatty ★★
()
Ответ на: комментарий от MKuznetsov

но чтобы поймать №1, надо чтобы система в случае кризиса убивала конкретную запущенную программу, а не тупо ребутилась.

по дефолту если ТС ничего не крутил, программу убьёт OOM Killer. Который в принципе может ошибиться, и убить что-то другое. Если он убьёт init, то будет reboot. Вот только запись в логе всё равно будет. Короче - ТС не только написал кривую программу, но ещё и что-то там накриворучил в настройках.

drBatty ★★
()
Ответ на: комментарий от ziemin

Так что ядро и не знает, какие используются страницы :)

Хотя нет, что это я. Диспетчер памяти читает/пишет эти дескрипторы. Он же и свопит.

ты всё правильно сказал - обычно ядро ничего не знает. В процессоре есть TLB, которая обычно и используется для трансляции. Ядро тут участия не принимает. (обычно! sic!).

конечно ядро может и узнать, если «захочет». например если юзер top смотрит.

drBatty ★★
()
Ответ на: комментарий от MKuznetsov

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

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

drBatty ★★
()
Ответ на: комментарий от drBatty

vec[j]=(void *)malloc(L3); if (found(origin,orilen,vec[j],L3)) {

можешь объяснить, что происходит в этом месте, и каким образом используется vec?

там происходит поиск одного массива в другом а-ля strstr. vec там только читается. Чтение кстати получается random`ным - обращение к vec[j] подзасирает страничный кеш :)

по дефолту если ТС ничего не крутил, программу убьёт OOM Killer. Который в принципе может ошибиться, и убить что-то другое

теперь (после обновы ff) убивает. Точнее если запустить 3 экземпляра программмы, то срабатывает oom. На 2-х, всё как и должно быть - система начинает тормозить, шуршать swap`ом, но работает. Повторюсь, единственная жертва в таком «стресс-тесте» - огнелис, у которого штатно отваливаются скрипты или ловится segfault.

Начальный эксперимент был не совсем чистым - где-то всегда работал ff. И который косвенно вызывал аппаратную ошибку (судя по всему аппаратную - reboot без записи в логи). memtest показал что память исправна, остаётся видео.

Чтобы сейчас повторить креш надо откатывать ff обратно, только смысла в этом не вижу.

MKuznetsov ★★★★★
() автор топика
Ответ на: комментарий от MKuznetsov

там происходит поиск одного массива в другом а-ля strstr. vec там только читается.

вот и я не понял - как ты читаешь то, чего нет? Сначала записать туда что-то надо. Это либо ошибка, либо бессмыслица, и потому негодно даже для теста.

ЕМНИП, UB происходит НЕ только при записи в невыделенную память, но и при чтении её. (могу и ошибаться). Потому твой ребут - вполне нормальная реакция на кривой код.

Начальный эксперимент был не совсем чистым - где-то всегда работал ff. И который косвенно вызывал аппаратную ошибку (судя по всему аппаратную - reboot без записи в логи). memtest показал что память исправна, остаётся видео. ]

могу намекнуть, что хотя сам ФФ и нормально работает и сделан, но вот флешплагин к нему - 100% быдлокод. И может работать как угодно. Особенно, если памяти мало. Не принимай близко к сердцу, не ты первый.

drBatty ★★
()
Ответ на: комментарий от drBatty

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

проблема в том, что malloc НЕ выделяет памяти. Страница есть, но памяти под неё нет. Такие страницы называются виртуальными, и видны в top'е как VIRT. Память выделяется ядром в момент первой ЗАПИСИ в эту страницу(потому-что чтение не имеет смысла). Очевидно, что реакция на чтение НЕ ОПРЕДЕЛЕНА. Единственное, что может(и должно) сделать ядро в такой ситуации - обеспечить сохранность другого кода, а что там с этим процессом будет - не важно.

drBatty ★★
()
Ответ на: комментарий от drBatty

Ну это вообще пушка. На уровне С поведение чтения из выделенной malloc() памяти определено («The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.»), потому что С вообще ничего не знает про MMU, а на уровне linux - тем, что malloc() использует mmap() с флагами PROT_READ|PROT_WRITE.

AptGet ★★★
()
Ответ на: комментарий от AptGet

На уровне С поведение чтения из выделенной malloc() памяти определено («The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.»), потому что С вообще ничего не знает про MMU, а на уровне linux - тем, что malloc() использует mmap() с флагами PROT_READ|PROT_WRITE.

может быть. Может глюк какой-то. Я же говорю - никогда не задумывался, что будет, если читать из неинициализированной памяти. Ну раз только value неопределенно, то ладно, я не спорю.

Читайте, раз можно…

drBatty ★★
()
Ответ на: комментарий от drBatty

Можно читать. На это именно и строится постулат, что нельзя хранить пароли в открытом виде в памяти и нельзя делать free() на области памяти, хранящии конфеденциальную информацию. Сначала обнулить память, а уже потом освобождать.

В случае ТС, либо серьёзный глюк ядра, либо настройка ядра на reboot в случае паники.

mky ★★★★★
()
Ответ на: комментарий от MKuznetsov

Начальный эксперимент был не совсем чистым - где-то всегда работал ff. И который косвенно вызывал аппаратную ошибку

Программную скорее всего: запрашивалась память для видеоподсистемы -> облом -> ребут.

LamerOk ★★★★★
()
Ответ на: комментарий от mky

Можно читать. На это именно и строится постулат, что нельзя хранить пароли в открытом виде в памяти и нельзя делать free() на области памяти, хранящии конфеденциальную информацию. Сначала обнулить память, а уже потом освобождать.

пароли не при чём тут. А читать нельзя просто потому, что это не имеет смысла.

drBatty ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.