Quá trình truy vết và sửa lỗi Linux bị treo khi sleep-resume trên GPU AMD
(nyanpasu64.gitlab.io)- Trên desktop Linux dùng AMD RX 570, khi chuyển sang chế độ ngủ trong trạng thái RAM đang được dùng nhiều, máy liên tục gặp màn hình đen hoặc không nhận input sau khi thức dậy, khiến việc truy vết phải đi xa hơn vấn đề hiển thị đơn thuần tới cả luồng quản lý nguồn của kernel
- Nguyên nhân cốt lõi nằm ở luồng amdgpu phải sao lưu VRAM vào RAM hệ thống trước khi sleep S3, nhưng trong tình huống thiếu RAM trống lại không tận dụng được disk swap đúng cách và sụp vì OOM
- Bản vá đầu tiên đưa VRAM eviction sớm từ
dpm_suspend()lêndpm_prepare()đã giảm tranh chấp với việc ngắt nguồn SSD, nhưng dopm_restrict_gfp_mask()đã vô hiệu hóa swap nên tình trạng thiếu bộ nhớ liên tiếp vẫn có thể tiếp diễn - Sau đó, khi chuyển sang gọi
amdgpu_device_evict_resources()tại thời điểmPM_SUSPEND_PREPAREbằngregister_pm_notifier(), VRAM có thể được sao lưu khi swap và ổ đĩa vẫn còn hoạt động; trong môi trường thử nghiệm, sleep thành công ngay cả khi RAM và VRAM được dùng nhiều - Thay đổi này đã được merge vào cây amdgpu nhưng bị revert vào 2025-06 vì khả năng deadlock; trong đường dẫn sleep không freeze trước các tiến trình người dùng, ứng dụng 3D có thể kéo VRAM trở lại GPU và chặn eviction
Những lần sleep lỗi lặp lại và chẩn đoán nhầm ban đầu
- Desktop được cấu hình dual-boot Windows và Linux; trên Linux, khi thử sleep lúc RAM đang được dùng nhiều, hệ thống thường xuyên hỏng
- Sau khi resume chỉ thấy màn hình đen cùng con trỏ còn di chuyển được, hoặc không có output màn hình và chỉ phản hồi với magic SysRq hoặc hard reset
- Trong một số trường hợp, đồng hồ trên màn hình khóa KDE vẫn cập nhật theo thời gian thực nhưng bị treo khi đăng nhập hoặc tương tác
- Môi trường thử nghiệm là Gigabyte B550M DS3H, GPU AMD RX 570, SSD NVMe Kingston A2000 1TB, Arch Linux, systemd-boot, Linux 6.4
- Khi kiểm tra log lần boot trước bằng
journalctl --system -b -1, một số lần thử sleep cho thấy lỗi OOM trong mã kernel dướiamdgpu_device_suspend - Nhiều ca lỗi kết thúc ở log sau, và không còn ghi nhận nào cho thấy hệ thống hỏng đã thức dậy lại
systemd-sleep:Entering sleep state 'suspend'...- kernel:
PM: suspend entry (deep)
- Ban đầu nghi ngờ chế độ tiết kiệm điện NVMe APST nên đã thử
nvme_core.default_ps_max_latency_us=0,iommu=soft, nâng cấp firmware SSD, thay SSD boot 2TB, nhưng vấn đề không được giải quyết
Các công cụ debug giúp thu hẹp vị trí lỗi
- Vì hành vi systemd thử liên tiếp nhiều chế độ sleep có thể tạo nhiễu log và làm trạng thái kernel xấu đi, đã thêm
SuspendState=memvào/etc/systemd/sleep.conf- Việc debug trở nên đơn giản hơn nhưng nguyên nhân gốc vẫn còn
- Dùng
echo 1 > /sys/power/pm_traceđể truy vết vị trí sleep thất bạipm_tracelưu trạng thái tiến trình sleep-resume vào giờ hệ thống- Nhờ tác dụng phụ là tắt sleep bất đồng bộ, cũng quan sát được hiện tượng hệ thống phục hồi sau lỗi suspend của amdgpu thay vì toàn hệ thống bị hang
- Thêm tham số kernel
systemd.debug_shellđể có thể mở root shell bằng Ctrl-Alt-F9 mà không cần KDE hay đăng nhập TTY - Dùng bàn phím PS/2 để phòng trường hợp USB controller và bàn phím bị hỏng; về sau thiết lập serial console
- Tham số kernel:
no_console_suspend console=tty0 console=ttyS0,115200 loglevel=8 - Trên laptop, liên tục bắt log bằng
sudo minicom --device /dev/ttyUSB0 --baudrate 115200 - Serial console cho phép chạy lệnh và thu thập log ngay cả sau khi màn hình và mạng bị hỏng, nhưng có hạn chế về tốc độ truyền và xử lý màu sắc/kích thước màn hình
- Tham số kernel:
Mối liên hệ giữa amdgpu VRAM eviction và OOM
- Log crash phần lớn xảy ra trong đường dẫn eviction buffer TTM của amdgpu
amdgpu_device_evict_resources()amdgpu_ttm_evict_resources()
- Từ các báo cáo lỗi liên quan, xác nhận “evict” liên quan tới việc sao chép VRAM sang RAM hệ thống hoặc chuyển RAM hệ thống sang swap
- Khi desktop vào sleep S3, GPU PCIe bị ngắt nguồn và dữ liệu trên chip VRAM biến mất
- Driver GPU phải sao chép VRAM đang dùng sang RAM hệ thống trước khi sleep
- Sau khi resume, dữ liệu đã lưu trong RAM phải được khôi phục lại
- Driver amdgpu trên Linux gặp vấn đề: khi không có đủ RAM trống để chứa toàn bộ VRAM đang dùng, thay vì đẩy RAM hệ thống sang disk-based swap, nó crash vì thiếu bộ nhớ
- Khi Linux gặp OOM trong lúc suspend, nó cố hủy sleep và khởi động lại thiết bị, nhưng vì quá trình sleep đã bị ngắt giữa chừng, một số driver có thể hỏng hoặc tiếp tục OOM trong quá trình suspend/resume
- Rủi ro cao hơn nếu sleep bất đồng bộ đang bật
- Sleep có thể đã thành công nhưng OOM xảy ra trong quá trình khởi động thiết bị khi resume
Nỗ lực sửa đầu tiên: đưa thời điểm sao lưu VRAM lên sớm hơn
- Mario Limonciello đề xuất bật
/sys/power/pm_print_timesvà/sys/power/pm_debug_messagesrồi kiểm tra log sleep - Log cho thấy driver NVMe và amdgpu vào song song
pci_pm_suspendtrong lúc sleep - Ban đầu đã tìm cách đưa GPU suspend lên trước SSD suspend, đồng thời kiểm tra cơ chế device suspend ordering của Linux
- Cơ chế này có vẻ gần với việc đồng bộ các thiết bị ngoại vi liên kết chặt chẽ hơn là nhằm suspend mọi GPU trước mọi ổ đĩa hệ thống
- Mario đề xuất evict VRAM ở giai đoạn
preparecủa Linux suspend, và viết bản vá kernel chuyển VRAM eviction từdpm_suspend()sangdpm_prepare() - Luồng trước và sau thay đổi như sau
- Cũ: sao lưu VRAM chạy ở thời điểm
dpm_suspend(), có thể trùng với luồng SSD đang tắt - Mới: thử sao lưu VRAM trước trong
dpm_prepare(), nếu thất bại thì dừng sleep trước khi suspend các thiết bị khác
- Cũ: sao lưu VRAM chạy ở thời điểm
- Thay đổi này tốt hơn trước, nhưng vì
pm_restrict_gfp_mask()vô hiệu hóa swap trướcdpm_prepare(), nên vẫn thất bại khi RAM được dùng nhiềuamdgpu_ttm_evict_resources()có thể thất bại vì thiếu bộ nhớ liên tục- Ngay cả khi nhét được toàn bộ VRAM vào RAM, nếu thiếu phần dư để xử lý các cấp phát tiếp theo của driver thì OOM vẫn có thể xảy ra khi sleep hoặc wake
Một crash amdgpu riêng được tìm bằng Ghidra
- Trong quá trình thử nghiệm, lỗi
BUG: unable to handle page fault for address: fffffffffffffffcxuất hiện, trông giống dereference một con trỏ gần null - Log crash chỉ tới vị trí
dm_resume+0x200nhưng không cung cấp số dòng trong source code - Sau khi lưu và trích xuất kernel module
amdgpu.ko, dùng Ghidra để decompile và map vị trí crash trongdm_resumevới dòng source kernel - Vấn đề xảy ra ở macro
for_each_new_crtc_in_state(dm->cached_state, crtc, new_crtc_state, i)dm->cached_statekhông phải con trỏ hợp lệ mà làfffffffffffffff4- Sau đó khi đọc trường
[RSI + 0x8], page fault xảy ra tại địa chỉfffffffffffffffc
- Nguyên nhân nằm ở luồng
dm_suspend()lưu trực tiếp giá trị trả về củadrm_atomic_helper_suspend()vào con trỏdrm_atomic_helper_suspend()có thể trả về con trỏ hợp lệ hoặcERR_PTR(err)- Do OOM nên
-ENOMEM(-12)được trả về, và được đánh giá là mã suspend của amdgpu đã dereference nó như một con trỏ
- Mario đã sửa vấn đề này bằng cách thêm mã kiểm tra giá trị trả về thất bại và dừng suspend
Hướng đã bỏ: cho phép swap trong prepare()
- Lý do sleep vẫn thất bại khi RAM được dùng nhiều là amdgpu sao lưu VRAM trong
dpm_prepare(), nhưng tại thời điểm nàypm_restrict_gfp_mask()đã vô hiệu hóa disk swap - Một thử nghiệm là cấu trúc cho phép swap trong
dpm_prepare(), rồi chỉ vô hiệu hóa swap ngay trước khidpm_suspend()tắt ổ đĩa - Để làm vậy, đã thử di chuyển lời gọi
pm_restrict_gfp_mask()từenter_state()vào sâu hơn bên trongdpm_suspend_start() - Có nhiều ràng buộc thực tế
pm_restrict_gfp_mask()được khai báo trongkernel/power/power.hvà được gọi từkernel/power/suspend.c- Vị trí muốn gọi là
drivers/base/power/main.c, còn file này thường không include header củakernel/power/ - Như một hack tạm, đã thêm
#include <../kernel/power/power.h>, nhưng đây là cấu trúc cần thuyết phục upstream
- Hybrid sleep cũng có vấn đề về tính đúng đắn
- Hybrid sleep lưu ảnh hệ thống, gọi
pm_restrict_gfp_mask(), rồi gọisuspend_devices_and_enter()trong trạng thái swap đã bị vô hiệu hóa - Nếu gọi lại cùng hàm, cảnh báo sẽ xuất hiện và
pm_restore_gfp_mask()có thể không bật lại được swap
- Hybrid sleep lưu ảnh hệ thống, gọi
- Trong thử nghiệm, tần suất lỗi hoặc crash giảm nhưng không được giải quyết hoàn toàn; vì đây là thay đổi mong manh đụng vào core power management nên không thử đưa lên upstream
Cách né ở user space: amdgpu-sleep
- Vào 2024-10, sau khi thoát SuperTuxKart rồi sleep, màn hình đen xuất hiện khi resume
- Theo log, lần thử sleep đầu tiên bị OOM ở
dpm_prepare(), lần thử tiếp theo dẫn tới crash cấp phát bộ nhớ trongbw_calcs()của amdgpu khi resume
- Theo log, lần thử sleep đầu tiên bị OOM ở
- Tham khảo cách NVIDIA sao lưu VRAM ở user space
- NVIDIA thực hiện sao lưu/khôi phục VRAM bằng cách ghi vào
/proc/driver/nvidia/suspendtrong service chạy trước và sau khi systemd gọi kernel suspend
- NVIDIA thực hiện sao lưu/khôi phục VRAM bằng cách ghi vào
- Dựa trên đó, đã tạo package amdgpu-sleep cho Arch Linux
- Trước khi sleep, đọc
/sys/kernel/debug/dri/1/amdgpu_evict_vram - Debug endpoint này ra lệnh cho amdgpu lưu toàn bộ VRAM vào RAM hệ thống
- systemd chờ GPU VRAM eviction hoàn tất rồi mới bắt đầu kernel suspend
- Trước khi sleep, đọc
- Khi sleep trên desktop, VRAM nhanh chóng được sao chép vào bộ nhớ, và nếu cần thì RAM được đẩy sang swap, nên thành công
- Khi nhiều ứng dụng 3D đang chạy, các ứng dụng tiếp tục render frame và kéo VRAM trở lại GPU, gây ra livelock giằng co với
amdgpu_evict_vram- Trạng thái này kéo dài hơn 70 giây rồi
amdgpu_evict_vrambỏ cuộc - Sau đó systemd bắt đầu kernel suspend và freeze userspace, nên ở giai đoạn kernel thì VRAM eviction thành công
- Trạng thái này kéo dài hơn 70 giây rồi
- Script này vẫn được dùng vì tần suất xảy ra livelock thấp hơn tần suất crash ở kernel-level khi tắt script
Bản vá cuối cùng: power management notifier
- Vào 2024-11, Mario yêu cầu thử nghiệm bản vá cho phép eviction khi swap vẫn còn active
- Bản vá có cấu trúc gọi
register_pm_notifier()và dùng power management notifier API của Linux - Callback nhận các message
PM_HIBERNATION_PREPAREvàPM_SUSPEND_PREPARE, rồi gọiamdgpu_device_evict_resources() PM_SUSPEND_PREPAREđược phát hành trongenter_state() → suspend_prepare()thông quapm_notifier_call_chain_robust(PM_SUSPEND_PREPARE, PM_POST_SUSPEND)PM_SUSPEND_PREPAREđược chuyển tới các driver có notifier callback- Nếu xảy ra lỗi,
PM_POST_SUSPENDđược chuyển tới các driver đã chuẩn bị, và sleep bị dừng
- Nếu evict VRAM ở vị trí này thì đó là trước khi
pm_restrict_gfp_mask()vô hiệu hóa swap, và ổ đĩa cũng chưa bị freeze - Luồng đã sửa như sau
suspend_prepare()PM_SUSPEND_PREPAREamdgpu_device_pm_notifier() → amdgpu_device_evict_resources()pm_restrict_gfp_mask()dpm_prepare()dpm_suspend()
- Kết quả build và thử nghiệm kernel tùy chỉnh chứa driver amdgpu đã sửa: không còn lỗi sau nhiều lần sleep khi RAM và VRAM được dùng nhiều
- Tuy nhiên, vì amdgpu sao lưu VRAM trước khi PipeWire hoặc kernel mute loa, xuất hiện hiện tượng âm thanh lặp lại trong vài giây
- Sau vài vòng code review, thay đổi này được merge vào amdgpu tree, dẫn tới giai đoạn sửa được bug này sau hơn một năm thử nghiệm
Cập nhật 2025-06 và revert
- Ban đầu, thay đổi được kỳ vọng sẽ có trong stable Linux kernel 6.14, nhưng sau đó bị revert vì deadlock có thể xảy ra
- Vấn đề mới phát sinh khi systemd gọi system suspend mà không freeze trước toàn bộ tiến trình user space
- Kernel cố evict VRAM vào RAM hệ thống trước khi tự freeze các tiến trình
- Đồng thời, nếu chương trình 3D kéo VRAM trở lại GPU, quá trình suspend eviction có thể deadlock
- Điều này tương tự livelock đã gặp trong cách né
amdgpu_evict_vramở user space - Linux PM maintainer đề xuất phương án di chuyển lời gọi
pm_restrict_gfp_mask()vào bên trongsuspend_devices_and_enter()- Điều này gần với hướng cho phép swap trong
prepare()đã thử nghiệm trước đó
- Điều này gần với hướng cho phép swap trong
- Không có kế hoạch tự triển khai/gửi patch
- Vì GPU AMD đã được chuyển sang một máy tính cũ hơn có CPU chậm hơn và 8GB RAM, và không muốn chạy build kernel trong môi trường đó
- Máy chính đã nâng cấp lên Intel Arc B570, nhưng cùng loại vấn đề cũng xảy ra với 10GB VRAM
- Vấn đề đó đã được báo cáo lên drm/xe kernel bug tracker
1 bình luận
Ý kiến trên Hacker News
Giả định rằng khi máy tính để bàn vào chế độ ngủ S3 thì GPU PCIe sẽ bị cắt điện là chưa chắc chắn
Đúng là S3 sẽ cắt toàn bộ nguồn điện ngoại trừ RAM, nhưng chẳng hạn các bo mạch chủ Gigabyte Aorus nổi tiếng vì lỗi ngủ của SSD NVMe khiến hệ thống không thể ngủ hoặc thức dậy đúng cách
Thường có thể обход bằng một quy tắc udev chặn đánh thức trên mọi cổng PCIe:
ACTION=="offline", SUBSYSTEM=="pci", DRIVER=="pcieport", ATTR{power/wakeup}="disabled"Hẹp hơn thì có thể chỉ định riêng cổng PCIe có vấn đề như
ATTR{vendor}=="0x8086", ATTR{device}=="0x43bc", và có thể tìm nguyên nhân bằng/proc/acpi/wakeup,/sys/class/pci_bus/*/*/yourWakeupDevicePci/uevent | grep PCI_ID,udevadm info --attribute-walk /dev/whateverThay vì udev, cũng có thể bật/tắt
/proc/acpi/wakeuptrong service systemd hoặc script tự động hóa, nhưng kém ổn định hơn; các vấn đề ngủ của Linux kiểu này thật sự rất mệt mỏiACTION=="add", KERNELS=="0000:00:01.1", ATTR{power/wakeup}="disabled"vào/etc/udev/rules.d/để chặn tự ý đánh thứcBộ thu Logitech Bolt cũng đánh thức ngay lập tức nhiều máy Linux, nhưng tôi không biết vì sao trên Windows lại không như vậy; cũng không rõ nếu muốn capture USB thì có cần thiết bị như logic analyzer hay Glasgow không
Tạm thời tôi đã thêm quy tắc
ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c548", ATTR{power/wakeup}="disabled"để chặnecho GPP0 >> /proc/acpi/wakeuptrong một unit systemd khi khởi độngTuy nhiên lần ngủ đầu tiên sau khi boot luôn thức dậy ngay lập tức; sau khi áp dụng quy tắc udev ở trên thì có vẻ vấn đề đó cũng đã được giải quyết
Có lẽ phải có thể làm theo kiểu gửi lệnh ngủ cho thiết bị PCIe rồi cho chính bus ngủ, và khi đánh thức thì khôi phục bus trước rồi mới đánh thức thiết bị
Trong trường hợp của tôi, nguyên nhân đánh thức có vẻ đến từ
.../devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A08:00/device:45/wakeup/wakeup6, nhưng tôi không rõ đường dẫn này có nghĩa gìVới tư cách là tác giả của memreserver, một trong các cách обход ở user space được nhắc đến, tôi đã debug vấn đề này vài năm trước
Bình luận công khai có thể tìm nhanh là https://gitlab.freedesktop.org/drm/amd/-/issues/2125#note_17..., và tôi nhớ là cũng có thảo luận trên mailing list
Điểm cốt lõi là Linux khi đó không có suspend hook theo từng giai đoạn, chạy được một cách đáng tin cậy trước khi một phần các subsystem đĩa và bộ nhớ bị đóng băng; giờ thì có vẻ đã có thể làm được
Đáng tiếc là Freedesktop Gitlab dường như không được lập chỉ mục tốt, nên có vẻ kiến thức này đã bị chôn vùi
Công việc thật sự xuất sắc
Nếu bạn từng thắc mắc vì sao rất khó làm cho chuyển sang chế độ tiết kiệm điện hoạt động đúng trên Linux, và vì sao việc debug cũng khó, thì chỉ riêng bài này đã cho thấy có bao nhiêu điểm có thể hỏng
Hiện tại trên ThinkPad P1G4 của tôi, nếu không tự tắt quạt trước khi sleep thì nó không tự tắt; gần đây sau khi resume, tai nghe Bluetooth lại bị nhiễu nên tôi cũng phải tắt chế độ sleep của node trong PipeWire: https://wiki.archlinux.org/title/PipeWire#Noticeable_audio_d...
Lần đầu tôi gặp kiểu vấn đề này có lẽ đã khoảng 15 năm trước
Trong số các cách workaround được đề xuất cho nhiều vấn đề, có những cách là tắt các chế độ tiết kiệm điện, nhưng mục đích dùng sleep thường là để kéo dài thời lượng pin, nên cách này không thực tế lắm vì có thể làm thời gian sử dụng thực tế giảm đáng kể
Dù vậy, làm cho S0ix sleep hoạt động không phải là bất khả thi
Tôi đã cài Arch Linux lên các thiết bị cầm tay dùng AMD 7840U và AMD 8840U, cụ thể là GPD Win Max 2, GPD Win Mini, GPD Win 4, Minisforum V3, OneXPlayer X1 Ryzen; tôi không nghĩ các công ty này thiết kế hay kiểm thử với hỗ trợ Linux trong đầu
Thế nhưng chỉ cần chỉnh một chút các nguồn đánh thức giả trong
/proc/acpi/wakeupvà/sys/devices/*/*/*/power/wakeup, ngoại trừ OneXPlayer X1 Ryzen đời mới nhất, tôi gần như có được hỗ trợ S0ix hoàn hảoHỗ trợ từ kernel Linux mặc định cũng rất tốt: màn hình cảm ứng, nhập bằng bút, Wi-Fi, Bluetooth đều chạy ổn, và lỗ hổng duy nhất tôi thấy là hỗ trợ đầu đọc vân tay
Các nhà sản xuất nhỏ kiểu này ít tùy biến linh kiện cực đoan hay tích hợp quá chặt chẽ hơn, và trên thực tế điều đó thể hiện ở việc thiết bị dày hơn vài mm
Vì vậy họ có xu hướng chọn linh kiện bảo thủ hơn, và kết quả có thể là hỗ trợ Linux tốt một cách bất ngờ
Theo kinh nghiệm của tôi, các dòng ThinkPad doanh nghiệp đã rất ổn định từ lâu, và người dùng Windows trên cùng mẫu máy dường như lại gặp vấn đề sleep thường xuyên hơn
Cá nhân tôi thật sự rất biết ơn
Laptop chính của tôi là ThinkPad dùng Ryzen chạy Linux, tôi thường xuyên dùng sleep và hibernate, và đã thỉnh thoảng gặp vấn đề này
Tôi rất mong chờ Linux 6.14
Lý do
dm->cached_statelưu-12thay vì một con trỏ nhiều khả năng là vì trong lúc suspend,dm_suspend()đã gán thẳngdm.cached_state = drm_atomic_helper_suspend(adev_to_drm(adev))Hàm
drm_atomic_helper_suspend()được gọi có thể trả về một con trỏ hợp lệ hoặcERR_PTR(err), tức mã hóa lỗi bằng con trỏ âm; caller không kiểm tra lỗi mà đưa thẳng vào con trỏ, rồi khi resume thì dereference nóLại có thêm một lý do để đưa Rust vào kernel; nếu bị buộc phải xử lý kiểu
Resultthì những việc như thế này khó xảy ra hơnNhưng default rất quan trọng, và lịch sử kernel trì hoãn hiện đại hóa các quy ước coding trong thời gian dài là bất lợi cho các cải tiến phía C
Trớ trêu là chính sự kháng cự đó cũng khiến các lập trình viên Rust nản lòng, vì ngay cả việc dọn dẹp từng subsystem hay ghi lại cách hoạt động thành tài liệu cũng không được đón nhận mấy
Những thứ như https://github.com/llvm/llvm-project/issues/74205 nếu đi xuống tới kernel có thể sẽ hữu ích, nhưng tôi nghĩ họ vẫn sẽ tiếp tục chọn cách overload con trỏ thủ công thay vì bảo đảm an toàn bằng type
Tôi đang dual boot Linux/Windows trên laptop Framework AMD có gắn module GPU mở rộng, nên công việc này có vẻ sẽ giúp ích
Tôi muốn trực tiếp tài trợ hoặc quyên góp cho tổ chức từ thiện mà bạn chọn; thông tin liên hệ có trong profile
Tôi từng nghĩ đặt tên, vô hiệu hóa cache và lỗi off-by-one là hai vấn đề lớn nhất của khoa học máy tính, nhưng sau khi biết đến vấn đề sleep/wake, tôi thấy cái này có vẻ NP-complete
Nếu mọi thiết bị ngoại vi không có trạng thái thì có lẽ đã không thành vấn đề
Trên Linux, quản lý bộ nhớ, đặc biệt là các tình huống OOM, vẫn là một cơn ác mộng đau đớn đến mức khó tin
Không phải lúc nào cũng gặp những vấn đề như vậy, nhưng chắc chắn tôi từng cố debug các vấn đề tương tự rồi thất bại, và cuối cùng khi bị OOM thì thường chỉ cắm thêm RAM
Lãng phí và đắt đỏ, nhưng xử lý tình huống OOM một cách thanh lịch có lẽ vẫn sẽ là bài toán khó đối với Linux trong tương lai
Công việc lần này rất xuất sắc, và sẽ trở thành mốc tham chiếu khi debug các vấn đề tương tự sau này
Tính năng debug-shell của systemd cũng rất đáng mừng, trước đây tôi không biết là có tính năng như vậy
Tuy nhiên bo X670E Steel Legend của tôi dường như không có header serial, nên tôi tò mò không biết cổng serial tích hợp ngày nay hoạt động thế nào
Nó có gắn vào các lane PCIe của chipset không nhỉ
Khi đào sâu vào kernel Linux, các bản ghi hình bài trình bày về subsystem kernel ở những nơi như FOSDEM hay Linux Plumbers Conference giúp ích rất nhiều; ví dụ video về subsystem bộ nhớ TTM mà hầu hết driver DRM GPU desktop sử dụng nằm ở đây: https://www.youtube.com/watch?v=MG7_tUNKSt0
DOS muôn năm
Video TTM khi nào rảnh tôi sẽ xem
Tôi không rõ có cách xử lý OOM hiện đại nào tốt hơn những gì Linux đang làm không; nếu có tài liệu đáng đọc liên quan thì tôi muốn biết
Linux không xử lý đúng tình huống OOM
Tôi biết có thể dựng guardrail bằng cgroups, cài earlyoom, tăng swap hoặc dùng zram
Nhưng rốt cuộc tất cả chỉ là những mẹo bẩn thỉnh thoảng cứu được một lần, chứ không sửa cách các tình huống này được xử lý
Mong đừng đưa những thứ đó ra như giải pháp
Tôi từng thấy kernel không cấp phát được bộ nhớ trong dm_crypt khiến volume LUKS tự mount ở chế độ chỉ đọc; làm ơn chỉ cần kill một tiến trình user-space là được
Tình trạng hiện tại thật sự không thể chấp nhận được nữa, và tôi cũng mệt với các lời biện minh rồi
Dùng zstd thì có thể dùng 8GB RAM như khoảng 20GB “RAM”, 16GB như 40GB mà không gặp vấn đề gì đáng kể
Mạnh tay hơn nữa thì còn có thể overcommit bộ nhớ vượt 100%, và Android cũng làm như vậy nên đây là cách khá ổn định
Tin tốt đấy
Driver đồ họa Linux của AMD nhìn chung hoạt động tốt, nhưng riêng vấn đề này là ngoại lệ mà tôi đã gặp nhiều lần
Vấn đề gần đây tôi gặp là sau khi thức dậy từ chế độ ngủ, driver liên tục ghi log
WARNING: CPU: 12 PID: 11871 at drivers/gpu/drm/amd/amdgpu/../display/dc/dc_helper.c:100 generic_reg_update_ex+0x1d2/0x290 [amdgpu]rồi sau đó"[drm] scheduler comp_1.0.n is not ready, skipping"https://gitlab.freedesktop.org/drm/amd/-/issues/3911
Tuy nhiên đây là laptop nên cấu hình driver khác khá nhiều và cũng không có GPU PCIe
Phần lưu rồi trích xuất module kernel
amdgpu.ko, decompile bằng Ghidra, sau đó ánh xạ vị trí crash củadm_resumevề dòng tương ứng trong source kernel luôn là cảnh tôi thích nhất trong quá trình debug