Kernel Electric-Fence (KFENCE) adalah alat bawaan dalam kernel Linux yang dapat diaktifkan secara online. KFENCE mendeteksi masalah pencemaran memori di kernel dan modul kernel. Saat mendeteksi masalah, KFENCE menghasilkan pesan kesalahan dengan detail lengkap. Alibaba Cloud telah meningkatkan KFENCE di Alibaba Cloud Linux 3. Anda dapat mengaktifkan atau menonaktifkannya secara fleksibel dan dinamis serta menggunakannya untuk mendeteksi masalah pencemaran memori secara komprehensif, baik untuk kebutuhan deteksi online maupun debugging offline.
Batasan pada sistem operasi
Arsitektur x86
Alibaba Cloud Linux 3 dengan versi kernel
5.10.84-10atau lebih baru.Arsitektur Arm
Alibaba Cloud Linux 3 dengan versi kernel
5.10.134-16atau lebih baru.
Jika Anda seorang pengembang kernel atau modul kernel, Anda dapat menggunakan KFENCE untuk memeriksa apakah terjadi pencemaran memori di kernel atau modul kernel.
Jika Anda seorang pengguna biasa dan mengalami crash kernel, Anda dapat menggunakan KFENCE untuk membantu Alibaba Cloud atau pengembang driver pihak ketiga mengumpulkan informasi rinci tentang crash tersebut.
Istilah
Istilah | Deskripsi |
pencemaran memori | Masalah di mana area memori dimodifikasi atau rusak secara tidak benar saat program sedang berjalan, yang menyebabkan pengecualian atau crash pada program. Pencemaran memori dapat disebabkan oleh kesalahan pemrograman, kerentanan perangkat lunak, malware, atau kegagalan perangkat keras. |
slab | Alokasi slab adalah mekanisme alokasi memori yang efisien di kernel Linux. Kernel menggunakan slab untuk pra-alokasi sejumlah objek memori tertentu di kumpulan cache memori untuk alokasi dan pelepasan memori yang cepat. Slab dapat digunakan untuk mencegah operasi alokasi dan pelepasan memori yang sering dan meningkatkan efisiensi alokasi memori. |
halaman order-0 | Alokasi halaman order-0 adalah mekanisme alokasi memori di kernel Linux. Memori dibagi menjadi blok berukuran tetap yang disebut frame halaman. Dalam banyak kasus, ukuran frame halaman order-0 adalah 4 KiB. Halaman order-0 adalah frame halaman 4-KiB, yang merupakan unit dasar untuk alokasi memori. Saat aplikasi atau kernel membutuhkan blok memori kecil, memori dialokasikan oleh halaman order-0. |
Aktifkan KFENCE
KFENCE digunakan dalam skenario bisnis berikut:
Skema deteksi online
Skenario 1: Gunakan KFENCE untuk mendeteksi apakah masalah pencemaran memori terjadi
Dalam contoh berikut, KFENCE mengonsumsi hingga 2 MiB memori tanpa memengaruhi kinerja.
Tambahkan parameter
kfence.sample_intervaluntuk mengaktifkan KFENCE.Ganti <kfence.sample_interval> dengan nilai yang ingin Anda tentukan. Sebagai contoh, nilai 100 menentukan bahwa alat debug KFENCE diaktifkan secara otomatis saat sistem mulai berikutnya, dengan interval sampling diatur ke 100 kejadian.
sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="kfence.sample_interval=<kfence.sample_interval>"Tambahkan parameter
kfence.booting_maxuntuk membatasi jumlah maksimum memori yang dapat dikonsumsi KFENCE berdasarkan spesifikasi memori.CatatanPada versi kernel
5.10.134-17atau lebih baru, konfigurasi defaultkfence.booting_max=0-2G:0,2G-32G:2M,32G-:32Mditambahkan ke daftar parameterboot commandline. Konfigurasi ini bekerja bersama dengan nilai default (255) dari parameternum_objectsuntuk memastikan overhead memori KFENCE tidak melebihi 1‰ dari total memori di semua spesifikasi memori. Dengan konfigurasi ini, KFENCE dapat mengonsumsi hingga 2 MiB memori jika halaman memori standar 4-KiB digunakan dan hingga 32 MiB memori jika halaman besar 64-KiB digunakan.Parameter kfence.booting_max hanya membatasi jumlah maksimum memori yang dapat dikonsumsi KFENCE. Parameter ini adalah batasan untuk parameter num_objects dan tidak mewakili overhead memori aktual. Overhead memori aktual kurang dari atau sama dengan nilai parameter kfence.booting_max.
Ganti
<kfence.booting_max>dengan nilai yang ingin Anda tentukan, seperti0-128M:0,128M-256M:1M,256M-:2M. Deskripsi segmen dalam nilai sampel:0-128M:0: Jika total memori pada mesin yang Anda gunakan kurang dari 128 MiB, KFENCE dinonaktifkan.
128M-256M:1M: Jika total memori pada mesin yang Anda gunakan lebih besar dari atau sama dengan 128 MiB tetapi kurang dari atau sama dengan 256 MiB, KFENCE dapat mengonsumsi hingga 1 MiB memori. Nilai parameter num_objects tidak boleh melebihi 127.
256M-:2M: Jika total memori pada mesin yang Anda gunakan lebih besar dari 256 MiB, KFENCE dapat mengonsumsi hingga 2 MiB memori. Nilai parameter num_objects tidak boleh melebihi 255.
sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="kfence.booting_max=<kfence.booting_max>"Konfigurasi ini hanya berlaku untuk skenario di mana KFENCE dimulai saat startup sistem dengan menambahkan parameter ke daftar parameter boot commandline. Konfigurasi ini tidak berlaku dalam Skenario 2, di mana KFENCE dikonfigurasi setelah sistem dimulai.
Konfigurasi ini secara otomatis berlaku saat sistem mulai berikutnya.
Skenario 2: Gunakan KFENCE untuk mendeteksi apakah masalah pencemaran memori terjadi
Dalam skenario ini, sejumlah besar memori tingkat GiB dikonsumsi. Berhati-hatilah saat menggunakan mesin dengan memori kecil.
Buat skrip alokasi memori dan tambahkan konten berikut. Dalam contoh berikut, skrip diberi nama kfence.sh dan jenis slab yang dipantau adalah
kmalloc-64.#!/bin/bash # usage: ./kfence.sh kmalloc-64 SLAB_PREFIX=/sys/kernel/slab MODULE_PREFIX=/sys/module/kfence/parameters if [ $# -eq 0 ]; then echo "err: please input slabs" exit 1 fi #check whether slab exists for i in $@; do slab_path=$SLAB_PREFIX/$i if [ ! -d $slab_path ]; then echo "err: slab $i not exist!" exit 1 fi done #calculate num_objects sumobj=0 for i in $@; do objects=($(cat $SLAB_PREFIX/$i/objects)) maxobj=1 for ((j=1; j<${#objects[@]}; j++)); do nodeobj=$(echo ${objects[$j]} | awk -F= '{print $2}') [ $maxobj -lt $nodeobj ] && maxobj=$nodeobj done ((sumobj += maxobj)) done echo "recommend num_objects per node: $sumobj" #check kfence stats if [ $(cat $MODULE_PREFIX/sample_interval) -ne 0 ]; then echo "kfence is running, disable it and wait..." echo 0 > $MODULE_PREFIX/sample_interval sleep 1 fi #disable all slabs catching for file in $SLAB_PREFIX/* do (echo 0 > $file/kfence_enable) 2>/dev/null || echo 1 > $file/skip_kfence done #disable order0 page catching echo 0 > $MODULE_PREFIX/order0_page #enable setting slabs catching for i in $@; do (echo 1 > $SLAB_PREFIX/$i/kfence_enable) 2>/dev/null || echo 0 > $SLAB_PREFIX/$i/skip_kfence done #setting num_objects and node mode echo $sumobj > $MODULE_PREFIX/num_objects echo node > $MODULE_PREFIX/pool_mode #start kfence echo -1 > $MODULE_PREFIX/sample_interval if [ $? -ne 0 ]; then echo "err: kfence enable fail!" exit 1 fi echo "kfence enabled!"Skrip ini digunakan untuk mendeteksi jumlah objek aktif dari slab, memperkirakan ukuran pool KFENCE yang sesuai berdasarkan jumlah tersebut, dan kemudian mengaktifkan KFENCE untuk mendapatkan informasi tentang alokasi memori dari semua slab.
CatatanSlab umum digunakan dalam manajemen memori untuk mengoptimalkan operasi alokasi dan pelepasan memori, meningkatkan kinerja dan efisiensi sistem. KFENCE dapat memantau slab dan halaman order-0.
Jalankan perintah berikut untuk menjalankan skrip dan memulai deteksi pencemaran memori:
sudo bash ./kfence.sh kmalloc-64
Skema debugging offline
Aktifkan KFENCE dengan menentukan parameter untuk arsitektur x86
Jalankan perintah berikut untuk mengaktifkan KFENCE:
sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="kfence.num_objects=1000000" sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="kfence.sample_interval=-1" sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="kfence.fault=panic"num_objects: Ukuran pool KFENCE, yaitu jumlah maksimum objek slab yang dapat dipantau oleh KFENCE.Saat nilai parameter num_objects lebih kecil dari atau sama dengan 131.071, jumlah maksimum memori yang dapat dikonsumsi KFENCE dihitung dengan rumus berikut: (num_objects + 1) × 8 KiB.
Saat nilai parameter num_objects lebih besar dari 131.071, jumlah maksimum memori yang dapat dikonsumsi KFENCE dihitung dengan rumus berikut: ⌈num_objects/131.071⌉ GiB. Simbol ⌈⌉ menentukan bahwa hasil perhitungan dibulatkan ke atas ke bilangan bulat terdekat.
CatatanKami merekomendasikan Anda menyetel parameter num_objects ke 10% dari memori maksimum yang tersedia. Sebagai contoh, jika Anda menyetel parameter
num_objectske 1.000.000, KFENCE dapat mengonsumsi hingga 8 GiB memori, yang dihitung dengan rumus berikut: ⌈ 1.000.000/131.071 ⌉ GiB = 8 GiB.
sample_interval: Interval di mana memori dipantau. Nilai valid:0: KFENCE dinonaktifkan dan tidak memantau memori.
Bilangan positif: Interval sampling dalam milidetik. Sebagai contoh, nilai 100 menentukan bahwa KFENCE memantau memori yang dialokasikan setiap 100 milidetik.
Bilangan negatif: Mode penuh. KFENCE memantau semua memori yang memenuhi kondisi tertentu, seperti jenis slab tertentu.
fault: Parameter ini diperkenalkan dalam versi kernel5.10.134-16. Nilai default:report. Jika Anda menyetel parameter fault kepanic, downtime terjadi pada instance tempat masalah terdeteksi untuk melestarikan file core dump yang dihasilkan saat masalah terjadi.
Mulai ulang sistem operasi agar konfigurasi berlaku.
Untuk informasi lebih lanjut, lihat Mulai Ulang Instance.
Gunakan skrip untuk mengaktifkan KFENCE untuk arsitektur x86 atau Arm
Setelah Anda menjalankan skrip untuk mengaktifkan KFENCE, KFENCE tidak dapat mendeteksi masalah pencemaran memori yang mungkin terjadi selama startup kernel.
Jika Anda ingin mengubah nilai parameter
num_objectsatausample_intervalsetelah mengaktifkan KFENCE, Anda harus terlebih dahulu menonaktifkan KFENCE.
Jalankan perintah berikut untuk mengaktifkan KFENCE:
sudo sh -c 'echo 1000000 > /sys/module/kfence/parameters/num_objects'
sudo sh -c 'echo -1 > /sys/module/kfence/parameters/sample_interval'
sudo sh -c 'echo panic > /sys/module/kfence/parameters/fault'num_objects: Ukuran pool KFENCE, yaitu jumlah maksimum objek slab yang dapat dipantau oleh KFENCE. Jumlah maksimum memori yang dapat dikonsumsi KFENCE dihitung dengan rumus berikut: ⌈num_objects/131.071⌉ GiB. Simbol ⌈⌉ menentukan bahwa hasil perhitungan dibulatkan ke atas ke bilangan bulat terdekat.CatatanKami merekomendasikan Anda menyetel parameter num_objects ke 10% dari memori maksimum yang tersedia. Sebagai contoh, jika Anda menyetel parameter
num_objectske 1.000.000, KFENCE dapat mengonsumsi hingga 8 GiB memori, yang dihitung dengan rumus berikut: ⌈ 1.000.000/131.071 ⌉ GiB = 8 GiB.sample_interval: Interval di mana memori dipantau. Nilai valid:0: KFENCE dinonaktifkan dan tidak memantau memori.
Bilangan positif: Interval sampling dalam milidetik. Sebagai contoh, nilai 100 menentukan bahwa KFENCE memantau memori yang dialokasikan setiap 100 milidetik.
Bilangan negatif: Mode penuh. KFENCE memantau semua memori yang memenuhi kondisi tertentu, seperti jenis slab tertentu.
fault: Parameter ini diperkenalkan dalam versi kernel5.10.134-16. Nilai default:report. Jika Anda menyetel parameter fault kepanic, downtime terjadi pada instance tempat masalah terdeteksi untuk melestarikan file core dump yang dihasilkan saat masalah terjadi.CatatanJika versi kernel Anda lebih awal dari
5.10.134-16, pesan kesalahan dilaporkan saat Anda menjalankan perintah sebelumnya. Kesalahan tersebut tidak memengaruhi KFENCE. Anda dapat mengabaikan pesan kesalahan tersebut.
Lihat hasil
Setelah KFENCE mendeteksi masalah pencemaran memori, Anda dapat melihat jumlah masalah dan pesan kesalahan rinci.
Lihat jumlah masalah pencemaran memori yang terdeteksi.
sudo cat /sys/kernel/debug/kfence/statsGambar berikut menunjukkan keluaran perintah, yang menunjukkan bahwa jumlah
total bugsbertambah.
Lihat detail pesan kesalahan.
dmesg | grep -i kfenceGambar berikut menunjukkan keluaran perintah, yang menunjukkan bahwa satu pesan kesalahan dikembalikan.

Nonaktifkan KFENCE
Jalankan perintah berikut untuk menonaktifkan KFENCE:
sudo bash -c 'echo 0 > /sys/module/kfence/parameters/sample_interval'Setelah Anda menonaktifkan KFENCE, KFENCE tidak lagi mendeteksi masalah alokasi memori. Saat semua memori yang dipantau di pool dilepaskan, KFENCE mengembalikan memori ke sistem buddy kernel dengan granularitas 1 GiB.
Dalam skenario di mana KFENCE dimulai dengan menambahkan parameter ke daftar parameter boot commandline, Anda dapat menjalankan perintah berikut untuk menghapus parameter. Kemudian KFENCE tidak akan diaktifkan secara otomatis saat sistem mulai berikutnya.
sudo grubby --update-kernel=/boot/vmlinuz-$(uname -r) --remove-args="kfence.sample_interval"