Обновить
12
0
Егор Воронцов@sdore

Типичный Python'ист

Отправить сообщение

Вы противоречите здравому смыслу. Нельзя оценить общее по частному.

OOM-киллер такое решение, и ограничения cgroups (в т.ч. нативно средствами systemd).

Давайте полный обзор начиная с systemctl hibernate

Го!

Systemd v257.5 и Linux 6.14:

  1. $ systemctl hibernate (кликабельно, также тык, тык, тык, тык);

  2. shared/hibernate-util.c:find_suitable_hibernation_device_full():

    Attempt to find a suitable device for hibernation by parsing /proc/swaps, /sys/power/resume, and /sys/power/resume_offset.

…
FOREACH_ARRAY(swap, entries.swaps, entries.n_swaps) {
	…
	if (… swap->size - swap->used > entry->size - entry->used)
		entry = swap;
}

if (!entry) {
	…
	return log_debug_errno(SYNTHETIC_ERRNO(ENOSPC), "No swap space available for hibernation.");
}

- нашли своп-файл/раздел по размеру;

  1. sleep/sleep.c:execute() — пишет в /sys/power/state, запуская процесс гибернации в ядре:

…
/* Configure hibernation settings if we are supposed to hibernate */
if (SLEEP_OPERATION_IS_HIBERNATION(operation)) {
	…
	r = find_suitable_hibernation_device(&hibernation_device);
	…
}

…

if (!action)
	action = sleep_operation_to_string(operation);

…

… LOG_MESSAGE("Performing sleep operation '%s'...", sleep_operation_to_string(operation)) …

r = write_state(state_fd, sleep_config->states[operation]);
if (r < 0)
	… LOG_MESSAGE("Failed to put system to sleep. System resumed again: %m") …
  • записали disk в /sys/power/state;

  1. kernel/power/main.c:state_store():

…
state = decode_state(buf, n);
if (state < PM_SUSPEND_MAX) {
	if (state == PM_SUSPEND_MEM)
		state = mem_sleep_current;

	error = pm_suspend(state);
} else if (state == PM_SUSPEND_MAX) {
	error = hibernate();
} …
  • запустили процесс гибернации;

  1. kernel/power/hibernate.c:hibernation_snapshot():

    Quiesce devices and create a hibernation image.

…
error = hibernate_preallocate_memory();
…
if (… !error)
	error = create_image(platform_mode);

/*
 * In the case that we call create_image() above, the control
 * returns here (1) after the image has been created or the
 * image creation has failed and (2) after a successful restore.
 */

/* We may need to release the preallocated image pages here. */
if (error || !in_suspend)
	swsusp_free();

- аллоцировали память и сделали дамп (и вернёмся сюда второй раз после пробуждения);

  1. kernel/power/hibernate.c:hibernate():

    Carry out system hibernation, including saving the image.

…
error = freeze_processes();
…
error = hibernation_snapshot(hibernation_mode == HIBERNATION_PLATFORM);
…
if (in_suspend) {
	…
	if (nocompress) {
		flags |= SF_NOCOMPRESS_MODE;
	} else {
	        flags |= SF_CRC32_MODE;

		/*
		 * By default, LZO compression is enabled. Use SF_COMPRESSION_ALG_LZ4
		 * to override this behaviour and use LZ4.
		 *
		 * Refer kernel/power/power.h for more details
		 */

		if (!strcmp(hib_comp_algo, COMPRESSION_ALGO_LZ4))
			flags |= SF_COMPRESSION_ALG_LZ4;
		else
			flags |= SF_COMPRESSION_ALG_LZO;
	}

	pm_pr_dbg("Writing hibernation image.\n");
	error = swsusp_write(flags);
	swsusp_free();
	if (!error) {
		…
		power_down();
	}
}
  • пережали и записали образ на диск и, наконец, выключили систему.

Ну а hibernate_preallocate_memory() мы с вами уже разбирали :))

P.S. А ещё более подробно можно почитать туть.

Я вам показываю, как гибернация реализована. Разумеется, она производится постранично — так, как содержимым памяти оперирует сам MMU, т.е. нативно. Выделяется место постранично, а копируются данные, ясное дело, побайтово. Страница из байтов состоит, а где противоречие-то?

Безусловно, в коде фигурируют страницы. Повторюсь: в каком месте я говорил про байты?

Страница не является байтом. Так что всё ваши утверждения можно поделить на ноль

Простите, что? Где я утверждал обратное, или вообще что-то про байты?

Ваша задача — пользоваться системой в меру её возможностей. Если вы хотите занимать больше, чем у вас RAM — будьте добры зарезервировать своп. Если нет — не занимайте.

Да как не является-то?

Смотрим kernel/power/snapshot.c:

To make this happen, we compute the total number of available page frames and allocate at least

([page frames total] - PAGES_FOR_IO - [metadata pages]) / 2 - 2 * DIV_ROUND_UP(reserved_size, PAGE_SIZE)

of them, which corresponds to the maximum size of a hibernation image.

If image_size is set below the number following from the above formula, the preallocation of memory is continued until the total number of saveable pages in the system is below the requested image size or the minimum acceptable image size returned by minimum_image_size(), whichever is greater.

Функция даже предварительно освобождает память, покуда возможно:

/*
 * Let the memory management subsystem know that we're going to need a
 * large number of page frames to allocate and make it free some memory.
 * NOTE: If this is not done, performance will be hurt badly in some
 * test cases.
 */
shrink_all_memory(saveable - size);

Затем пробует аллоцировать всё меньше и меньше, пока не получится:

/*
 * The number of saveable pages in memory was too high, so apply some
 * pressure to decrease it.  First, make room for the largest possible
 * image and fail if that doesn't work.  Next, try to decrease the size
 * of the image as much as indicated by 'size' using allocations from
 * highmem and non-highmem zones separately.
 */
pages_highmem = preallocate_image_highmem(highmem / 2);
pages = preallocate_image_memory(alloc, avail_normal);

могу продолжить разбор, надо?

Где данные о том, что у большинства работает всё хорошо?

Бритва Оккама. Где данные о том, что у большинства работает плохо? У кого хорошо, тот не идёт на форумы писать об этом.

Оно займёт его, только если вы сами запустите то, чем его занять. Боритесь не с симптомами, а с первопричиной.

Хочу как Windows и Macosx.. Что непонятного? Для меня Linux это винда.

Так вы не по адресу. Линукс — не винда. И не может быть ею, и рассматриваться как оная.

Я вам уже ответил ранее, что swappiness выставлять — решение без необходимости увеличения объёма swap-файла, а раз мы вольны его увеличивать, то этой манипуляции не требуется.

Основной тезис из начала вашей статьи:

Неважно, какой у вас размер swap. Гибернация может не сработать даже если на swap достаточно свободного места. Догадайтесь, почему??? ... Да — фрагментация. Похоже, система пытается выделить непрерывный участок в swap.

Мы этот тезис уже опровергли два месяца назад.

К чему же вы продолжаете спорить?

Если я увеличу размер своп файла, то Линукс его будет использовать

У вас проблема в понимании. Не линукс использует своп, а вы. Это вам не винда, где система пользуется вами, а не вы ею. Своп должен быть задан такого объёма, который вы, своим использованием, не займёте в нормальных условиях — и под гибернацию место останется.

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

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

А в каком моменте я с этим утверждением спорил? Потрудитесь указать.

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

В чём нарушение? Ваш скрипт держит это пространство неиспользованным до начала гибернации, а штатное решение позволяет системе скинуть туда то, что не влезает в RAM при пиковой загруженности. Абсолютно все кейсы, где работает ваше решение, продолжают работать на штатном. Просто штатное, в духе линукса, дополнительно даёт бонусные возможности под вашу собственную ответственность: выдержать больше нагрузки ценой невозможности гибернации ДО СНИЖЕНИЯ этой нагрузки. А без свопа ваша система такую нагрузку попросту не выдержала бы, приведя к фризу/крашу. Риторический вопрос: что лучше?)

Если вы так уверены в своей правоте, то напишите статью и предложите свое решение

Писать статью об очевидном моменте использования — бред. Здесь не нужно никакой статьи, у большинства людей (включая меня) всё прекрасно работает из коробки, достаточно просто установить нужный объём swap.

Вероятно, имеется ввиду Credentials API или его аналоги.

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

Это не работает. Своп будет занят

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

я выделя как раз минимальный необходимый объем

Но вам же всё равно приходится выделять отдельный файл для гибернации, помимо основного свопа. А без свопа в принципе нельзя.

И оперативки мне хватает

Если бы хватало, не забивался бы своп. Вы ведь понимаете, что он чем-то занимается? Это что-то — ваше. Возможно, без свопа у вас просто не возникает таких нагрузок, иначе бы фризило и OOM'илось.

Если я отключу своп, то в гибурнацию система никак не уйдет

Так ваш скрипт же это и делает — держит его по умолчанию отключенным.

Как вы хотите уходить в гибернацию без зарезервированного для этого пространства?

Я такого не утверждал. А утверждал следующее:

возможность уйти в гибернацию с 48 Гб … отрезая данный объём от дискового пространства, или … выдержать с его помощью больший пик

имея ввиду, что включенный своп принесёт бо́льшую пользу, чем отключенный.

Откуда 48ГБ. У меня в системе 32ГБ

Как, откуда? Вы же сами скинули скриншот, где из ваших 32 Гб перелилось ещё около 5 Гб в своп. Значит, в пиковой нагрузке у вас было занято точно больше 32 Гб, я взял следующее «круглое» для примера.

Своп не участвует в этом процессе. Там данные и так на диске
Данные и так на диске, но нужно ещё не более одного объёма RAM для гибернации. Простая арифметика: выделите объём RAM + свопа сколько нужно в пике.

Вы изначально понимаете эту проблему неправильно. И пытаетесь прикрутить туда какой-то костыль перенастраивая ядро

Я вам предложил решение параметром ядра, исходя из того, что вы не хотите резервировать больше места. Исходя из вашего нового тезиса, что место на диске не является ценностью, я теперь вам предлагаю решение, как оно задумано по дизайну: увеличить объём своп-файла/раздела.

Вам не кажется странным, что вы единственный, кто поставил дизлайк и критикует этот подход?

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

RTFM

Кто бы говорил :)

дефолтные настройки любого дистрибутива. какой бы он ни был не позволяют использовать систему как обычный пользователь windows/macosx

Наверное, потому что это дистрибутивы Linux?

сделал тест на пару дней

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

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

из-за неправильного дизайна системы хайбернейта

Вы решаете костылями проблему, которую сами себе создали. Что лучше: иметь возможность уйти в гибернацию с 48 Гб занятой памяти, при этом фактически бесполезно отрезая данный объём от дискового пространства, или же иметь возможность выдержать с его помощью больший пик (вероятно, с вашим юзкейсом там могут выйти и все 64 Гб) вместо того, чтобы система постоянно уходила в OOM, и при этом НЕ терять возможности уйти в гибернацию с прежними 48 Гб? По-моему, ответ очевиден. Исходя из этого и дизайн.

если у меня будет памяти 96ГБ, то я выделю ровно столько же для hibernate

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

Далее просто процитирую ваши же слова, без комментариев:

свободное место - не гарантия ухода в хайбернейт. проверено неоднократьно

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

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

Wat? Вы сравниваете установку софта с работой сервера, причём непонятно, имеете ли вы представление о разнице моментальных и временны́х единиц — объём оперативной памяти не может быть «за минуту» или «за месяц», это безвременная немонотонная единица.

но в общем мне то какое дело. железо это или несовершенство архитектуры

Дело вам как раз должно быть — железо вы самостоятельно не усовершенствуете, а вот архитектуру — запросто. Повторяюсь, GNU/Linux и его компоненты опенсорсны.

я не единственный юзер у которого такие проблемы с линуксом.

Вы не единственный юзер, у которого любые проблемы с линуксом. Это нормально, как видите, и у всех разный уровень. Всё пройдёт с опытом.

дефолтные настройки и поведение ядра и systemd в ubuntu 24.04 не позво ляют всего того о чём вы пишите.

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

я хочу просто быть довольныс пользователем. и моё решение делает меня вполне довольным

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

Некрореплай на некрокоммент: NtopNG.

Информация

В рейтинге
4 848-й
Откуда
Москва, Москва и Московская обл., Россия
Дата рождения
Зарегистрирован
Активность