Deadlock printk mengacu pada situasi di mana beberapa thread dalam sistem menunggu satu sama lain untuk melepaskan sumber daya dan tidak dapat melanjutkan ketika fungsi printk di kernel Linux dipanggil untuk mencetak log. Deadlock printk secara negatif memengaruhi operasi aplikasi dan layanan sistem serta menyebabkan downtime kernel. Oleh karena itu, pencegahan dan penyelesaian deadlock printk secepat mungkin sangat penting untuk memastikan stabilitas dan keandalan sistem. Topik ini menjelaskan penyebab masalah downtime di Alibaba Cloud Linux akibat deadlock printk dan cara menyelesaikannya.
Deskripsi masalah
Ketika masalah downtime terjadi di kernel sistem operasi Alibaba Cloud Linux, analisis file vmcore mengungkapkan gejala berikut:
Ketika masalah downtime terjadi, file dump bernama vmcore dibuat. Anda dapat melihat log kernel di file vmcore, memperoleh informasi calltrace yang dimulai dengan "Call Trace:" untuk menganalisis penyebabnya, dan kemudian menyelesaikan masalah.
Log kernel yang ditampilkan setelah perintah dmesg dijalankan berisi log
peringatanyang terkait dengan penjadwalan dan work_queue.Informasi calltrace dari proses tertentu memiliki karakteristik berikut:
Fungsi-fungsi yang terakhir dipanggil bertujuan untuk mendapatkan spinlock, seperti fungsi
_raw_spin_lock,queued_spin_lock_slowpath, danraw_spin_rq_lock_netsted.Sistem memanggil fungsi
printk, fungsiconsole_unlock, dan fungsi-fungsi sebelumnya yang mendapatkan spinlock secara berurutan.
Penyebab
Masalah ini disebabkan oleh deadlock yang terjadi saat mekanisme printk dari komunitas Linux digunakan. Deadlock printk jarang terjadi, tetapi mungkin terjadi di versi kernel 5.10.134-16.3 dari Alibaba Cloud Linux 3.
Mengapa deadlock printk terjadi?
Jika fungsi printk dipanggil untuk mencetak log kernel setelah kernel memegang spinlock work_queue atau runqueue (rq), printk memanggil driver Direct Rendering Manager (DRM) tingkat rendah untuk mencoba mengunci work_queue atau rq lagi. Akibatnya, deadlock printk terjadi, yang menyebabkan masalah downtime sistem.
CatatanUntuk informasi tentang bagaimana driver DRM mencoba mengunci objek, lihat patch drm/fb-helper: Add fb_deferred_io support.
Mengapa log
peringatanterkait penjadwalan dan work_queue muncul?Ketika kernel memegang spinlock work_queue atau rq dan memanggil fungsi printk untuk mencetak log, printk mencetak pesan peringatan tentang penjadwalan dan work_queue ke log kernel. Inilah alasan mengapa output perintah demesg berisi log peringatan untuk penjadwalan dan work_queue.
Mengapa versi kernel
5.10.134-16.3dari Alibaba Cloud Linux 3 memiliki probabilitas deadlock printk yang lebih tinggi?Log
peringatanuntuk penjadwalan dan work_queue hanya dicetak dalam beberapa skenario. Di versi kernel5.10.134-16.3dari Alibaba Cloud Linux 3, fitur asynchronous unthrottle yang di-backport dari komunitas Linux memiliki cacat regresi. Cacat ini meningkatkan probabilitas pencetakan logperingatandan menghasilkan probabilitas tinggi deadlock printk di Alibaba Cloud Linux 3.
Versi yang terpengaruh
Deadlock printk adalah masalah yang dikenal diperkenalkan dalam patch drm/fb-helper: Add fb_deferred_io support di Linux 4.10 yang dirilis oleh komunitas Linux.
Masalah ini ada di versi kernel
4.19dan5.10dari Alibaba Cloud Linux.Probabilitas masalah ini tinggi di versi kernel
5.10.134-16.3dari Alibaba Cloud Linux 3.
Solusi
Jalankan perintah berikut untuk mengubah level log guna mencegah fungsi printk mencetak log peringatan ke port serial.
Jika sistem jurnal Anda menangkap log di port serial tetapi tidak menangkap log kernel yang dicetak dengan menjalankan perintah dmesg, berhati-hatilah saat Anda mengubah level log.
Perubahan level log menyebabkan log
peringatandi port serial hilang, tetapi tidak memengaruhi logperingatandi log kernel yang dicetak dengan menggunakan perintah dmesg.
sysctl -w kernel.printk="<console_loglevel> <default_message_loglevel> <minimum_console_loglevel> <default_console_loglevel>" >> /etc/sysctl.confNilai valid parameter kernel.printk:
console_loglevel: menentukan level log. Fungsi printk mencetak log yang level lognya lebih tinggi dari level log yang ditentukan di port serial.default_message_loglevel: menentukan level log default. Jika tidak ada level log yang ditentukan, fungsi printk dipanggil untuk mencetak log level default.minimum_console_loglevel: menentukan nilai minimum parameterconsole_loglevel.default_console_loglevel: menentukan nilai default parameterconsole_loglevel.
Linux mendefinisikan delapan level log dari log kernel. Level log yang lebih rendah menunjukkan prioritas yang lebih tinggi. Untuk mencegah log peringatan dicetak di port serial, kami sarankan Anda mengatur parameter console_loglevel ke nilai kurang dari atau sama dengan 4. Contoh perintah:
sysctl -w kernel.printk="4 4 1 7" >> /etc/sysctl.confLevel log berikut tersedia:
#define LOGLEVEL_EMERG 0 /* system is unusable */
#define LOGLEVEL_ALERT 1 /* action must be taken immediately */
#define LOGLEVEL_CRIT 2 /* critical conditions */
#define LOGLEVEL_ERR 3 /* error conditions */
#define LOGLEVEL_WARNING 4 /* warning conditions */
#define LOGLEVEL_NOTICE 5 /* normal but significant condition */
#define LOGLEVEL_INFO 6 /* informational */
#define LOGLEVEL_DEBUG 7 /* debug-level messages */