From ac68443a1703433addf683c1f617f4c1f25de847 Mon Sep 17 00:00:00 2001 From: dongshengyuan <545258830@qq.com> Date: Wed, 24 Jun 2026 15:17:49 +0800 Subject: [PATCH] feat: improve swap --- debian/changelog | 10 +++ debian/patches/feat-swap-improve.patch | 113 +++++++++++++++++++++++++ debian/patches/series | 1 + 3 files changed, 124 insertions(+) create mode 100644 debian/patches/feat-swap-improve.patch diff --git a/debian/changelog b/debian/changelog index 569979b5..eeca2221 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,12 +1,21 @@ +systemd (255.2-4deepin37) unstable; urgency=medium + + * improve swap feat. + * https://github.com/systemd/systemd/pull/42632 + + -- dongshengyuan Wed, 24 Jun 2026 15:09:14 +0800 + systemd (255.2-4deepin36) unstable; urgency=medium * fix wrong error variable in log_error_errno() + * https://github.com/systemd/systemd/pull/42592 -- dongshengyuan Tue, 16 Jun 2026 12:05:16 +0800 systemd (255.2-4deepin35) unstable; urgency=medium * fix double-free in normalize_portable_changes() + * https://github.com/systemd/systemd/pull/42588 -- dongshengyuan Tue, 16 Jun 2026 11:17:14 +0800 @@ -19,6 +28,7 @@ systemd (255.2-4deepin34) unstable; urgency=medium systemd (255.2-4deepin33) unstable; urgency=medium * head_data_offset is declared as le64_t in journal-def.h, so it must be assigned with htole64(p). + * https://github.com/systemd/systemd/pull/42569 -- dongshengyuan Mon, 15 Jun 2026 13:09:42 +0800 diff --git a/debian/patches/feat-swap-improve.patch b/debian/patches/feat-swap-improve.patch new file mode 100644 index 00000000..c935f2f3 --- /dev/null +++ b/debian/patches/feat-swap-improve.patch @@ -0,0 +1,113 @@ +diff --git a/src/shared/hibernate-util.c b/src/shared/hibernate-util.c +index 3eb13d4..0ea4ba2 100644 +--- a/src/shared/hibernate-util.c ++++ b/src/shared/hibernate-util.c +@@ -314,6 +314,35 @@ static int read_swap_entries(SwapEntries *ret) { + return 0; + } + ++static int get_proc_meminfo_active(uint64_t *ret) { ++ _cleanup_free_ char *active_str = NULL; ++ uint64_t active; ++ int r; ++ ++ assert(ret); ++ ++ r = get_proc_field("/proc/meminfo", "Active(anon)", WHITESPACE, &active_str); ++ if (r < 0) ++ return log_debug_errno(r, "Failed to retrieve Active(anon) from /proc/meminfo: %m"); ++ ++ r = safe_atou64(active_str, &active); ++ if (r < 0) ++ return log_debug_errno(r, "Failed to parse Active(anon) '%s' from /proc/meminfo: %m", active_str); ++ ++ *ret = active; ++ return 0; ++} ++ ++static uint64_t swap_free(const SwapEntry *s) { ++ assert(s); ++ return LESS_BY(s->size, s->used); ++} ++ ++static bool swap_can_hold_image(const SwapEntry *s, uint64_t active) { ++ assert(s); ++ return active > 0 && active <= swap_free(s) * HIBERNATION_SWAP_THRESHOLD; ++} ++ + /* Attempt to find a suitable device for hibernation by parsing /proc/swaps, /sys/power/resume, and + * /sys/power/resume_offset. + * +@@ -337,10 +366,15 @@ int find_suitable_hibernation_device_full(HibernationDevice *ret_device, uint64_ + SwapEntry *entry = NULL; + uint64_t resume_config_offset; + dev_t resume_config_devno; ++ uint64_t active = 0; + int r; + + assert(!ret_size == !ret_used); + ++ /* Best-effort: used to prefer swaps that can hold the hibernation image. ++ * On failure, selection falls back to priority + free space only. */ ++ (void) get_proc_meminfo_active(&active); ++ + r = read_resume_config(&resume_config_devno, &resume_config_offset); + if (r < 0) + return r; +@@ -377,8 +411,14 @@ int find_suitable_hibernation_device_full(HibernationDevice *ret_device, uint64_ + } + + if (!entry || +- swap->priority > entry->priority || +- swap->size - swap->used > entry->size - entry->used) ++ /* prefer a swap that can hold the image over one that cannot */ ++ (swap_can_hold_image(swap, active) && !swap_can_hold_image(entry, active)) || ++ /* among equal capacity fitness: higher priority wins */ ++ (swap_can_hold_image(swap, active) == swap_can_hold_image(entry, active) && ++ (swap->priority > entry->priority || ++ /* equal priority: more free space wins */ ++ (swap->priority == entry->priority && ++ swap_free(swap) > swap_free(entry))))) + entry = swap; + } + +@@ -403,28 +443,8 @@ int find_suitable_hibernation_device_full(HibernationDevice *ret_device, uint64_ + return resume_config_devno > 0; + } + +-static int get_proc_meminfo_active(unsigned long long *ret) { +- _cleanup_free_ char *active_str = NULL; +- unsigned long long active; +- int r; +- +- assert(ret); +- +- r = get_proc_field("/proc/meminfo", "Active(anon)", WHITESPACE, &active_str); +- if (r < 0) +- return log_debug_errno(r, "Failed to retrieve Active(anon) from /proc/meminfo: %m"); +- +- r = safe_atollu(active_str, &active); +- if (r < 0) +- return log_debug_errno(r, "Failed to parse Active(anon) '%s' from /proc/meminfo: %m", active_str); +- +- *ret = active; +- return 0; +-} +- + int hibernation_is_safe(void) { +- unsigned long long active; +- uint64_t size, used; ++ uint64_t active, size, used; + bool resume_set, bypass_space_check; + int r; + +@@ -453,7 +473,7 @@ int hibernation_is_safe(void) { + return r; + + r = active <= (size - used) * HIBERNATION_SWAP_THRESHOLD; +- log_debug("Detected %s swap for hibernation: Active(anon)=%llu kB, size=%" PRIu64 " kB, used=%" PRIu64 " kB, threshold=%.2g%%", ++ log_debug("Detected %s swap for hibernation: Active(anon)=%" PRIu64 " kB, size=%" PRIu64 " kB, used=%" PRIu64 " kB, threshold=%.2g%%", + r ? "enough" : "not enough", active, size, used, 100 * HIBERNATION_SWAP_THRESHOLD); + if (!r) + return -ENOSPC; + diff --git a/debian/patches/series b/debian/patches/series index f669e803..f8a660e4 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -47,3 +47,4 @@ fix-byte-order-conversion.patch update-po-file-about-bo-and-ug.patch fix-double-free.patch fix-wrong-err-log.patch +feat-swap-improve.patch