Cara memaksa kernel Linux untuk "membeku" (atau hampir membeku) selama beberapa ratus milidetik

17

Kami menjalankan proses waktu-nyata pada kernel non-waktu-nyata (CentOS 6), dan ini mungkin tidak akan berubah.

Kami memiliki aplikasi video streaming yang membutuhkan sekitar 500 MB / s lalu lintas PCIe dari FPGA khusus secara terus menerus selama 1,5 jam setiap kalinya. Aplikasi berfungsi dengan baik - sebagian besar waktu. Namun, kami mengalami situasi di mana tampaknya kernel berhenti merespons untuk melayani permintaan PCIe atau memori hingga 500 milidetik sekaligus. Ini tampaknya terjadi selama file burst IO dari utas lainnya. Saya merasa tidak mungkin untuk mencoba mereplikasi masalah ini dengan hanya melakukan banyak file dummy IO dari ruang pengguna saat aplikasi utama sedang berjalan.

Apakah ada cara untuk memaksa (mensimulasikan) "pembekuan" global dari kernel Linux (khususnya, menghentikan PCIe atau semua akses memori DDR3 atau sesuatu seperti itu) sehingga kita dapat mereproduksi masalah ini?

Kami memiliki buffering hingga 10 milidetik diimplementasikan sekarang ke dalam memori FPGA internal, tetapi itu tidak cukup. Kita dapat buffer ke FPGA DDR3 dan kemudian membuang ke host, tetapi kita perlu metode untuk menguji fitur baru ini di bawah tekanan.

Kami tidak ingin kernel membeku atau mengunci secara permanen. Kami ingin kemampuan untuk mengatur interval waktu.

Saya mencari sesuatu di sepanjang baris penulisan nilai-nilai ajaib untuk /proc/sys/vmsementara yang membuat sistem hampir merangkak, dan kemudian kembali kembali setelah beberapa ratus milidetik, tetapi melihat sejumlah cara yang mungkin untuk memecahkannya bukan untuk pemula seperti saya ( https://www.kernel.org/doc/Documentation/sysctl/vm.txt ). Mungkin numactlsihir?

Mark Lakata
sumber
Perkiraan saya adalah ini membutuhkan penulisan modul kernel. Anda harus membekukan semua utas pada semua CPU, dan mengatur untuk memulai kembali pada interupsi timer.
Gilles 'SO- stop being evil'
Saya tidak ingin membekukan utasnya, saya ingin membekukan kernel! Maksud saya, saya ingin mencegah akses ke perangkat keras (memori dan / atau PCIe dan / atau disk) untuk waktu yang singkat. Jika itu tidak berhasil, saya tidak keberatan membuat hal-hal yang sangat tidak dioptimalkan, menonaktifkan L1 cache, dll. Saya hanya tidak tahu bagaimana melakukan ini.
Mark Lakata
1
Ah, jadi Anda tidak ingin membekukan kernel, Anda hanya ingin membekukan bagian dari kernel yang merespons beberapa perangkat keras? Itu juga akan membutuhkan penyelaman yang cukup dalam ke kernel.
Gilles 'SO- stop being evil'
Saya tidak keberatan membekukan kernel sepenuhnya, selama perangkat keras dibekukan sebagai bagian dari itu.
Mark Lakata
1
Ternyata, masalah ini terkait dengan meronta-ronta TLB sebagai CPU tuan rumah flushes beberapa buffer IO (kami menggunakan HDF5 untuk menulis file), dan meronta-ronta TLB ini menyebabkan coprocessor juga meronta-ronta, karena merupakan sistem NUMA. Saya kira semua yang kita butuhkan sekarang adalah cara yang andal secara terprogram yang menyebabkan TLB meronta-ronta untuk waktu yang terkendali.
Mark Lakata

Jawaban:

9

Salah satu opsi untuk melakukan tes cepat dapat menggunakan kernel yang diaktifkan KGDB dan menghentikan kernel secara manual dan menguji, lihat tautan ini .

Pada catatan lain, hal-hal yang saya ingat yang dapat menyebabkan Anda berhenti:

  • cpufreq,, cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latencynilainya dalam ns (4000 di AMD FX saya (tm) -8120 Prosesor Delapan-Inti) seharusnya tidak menjadi masalah, tetapi periksa
  • Throttling termal baik CPU itu sendiri atau modul regulator tegangan.
  • NAPI dan / atau lalu lintas jaringan yang berat
  • PCIe ASPM ( cat /sys/module/pcie_aspm/parameters/policy)
  • Pertarungan dalam buffer perangkat tujuan Anda (hard disk, nic ...)
  • Bug di firmware beberapa perangkat di bus PCIe (bahkan jika Anda tidak menggunakannya), Anda dapat mematikannya dengan /sys/bus/pci/devices/$DEVICE/power/control
Jorge Nerín
sumber
Bisakah saya menggunakan kdbalih-alih kgdbmelakukan hal yang sama? Saya tidak pernah menggunakan keduanya. Apakah ini seperti urutan perintah "Stop-A" pada workstation Sun tadi? Jika saya hanya melakukan SysRq-g cepat, lalu ketik "pergi", akankah saya memiliki probabilitas tinggi untuk tidak merusak sistem? (ref: kernel.org/pub/linux/kernel/people/jwessel/kdb/… )
Mark Lakata
1
Mungkin Anda bisa menggunakan kdb. Ketahuilah bahwa itu harus bekerja dengan keyboard yang terhubung dengan usb, tetapi cobalah untuk memiliki PS / 2 yang berguna untuk berjaga-jaga. Dan ini adalah debugger tingkat yang sangat rendah (kernel land), jadi seperti biasa, simpan cadangan dan jika rusak Anda bisa menyimpan kedua bagian :).
Jorge Nerín
Sebelum menggunakan tweaker dengan kernel, saya pertama-tama akan mencoba untuk membongkar modul kernel yang tidak digunakan untuk perangkat PCIe yang mungkin menggunakan bus (driver grafis paling menonjol), dan baik secara fisik menghapus perangkat dari sistem atau mematikannya. PCIe 1.0 x1 memiliki bandwidth 250MB / s dan PCIe 2.0 x1 mencapai 500MB / s, apakah perangkat asal dan tujuan bebas untuk menerima tingkat berkelanjutan tanpa gangguan atau apakah mereka memiliki lebih banyak jalur untuk memungkinkan lebih banyak ruang kepala?
Jorge Nerín
Sumber lain yang mungkin dari lag mungkin beberapa penangan manajemen daya ACPI dari beberapa perangkat atau bahkan beberapa penangan CPU SMM menunggu peristiwa eksternal.
Franki
2

Bisakah kita memiliki detail lebih lanjut tentang bagaimana aplikasi Anda berkomunikasi dengan FPGA? Apakah itu aplikasi yang membaca buffer dari FPGA, atau FPGA yang mengirim interupsi ke kernel (seperti kartu jaringan)?

Saya berharap untuk membuka blok / char di / dev dan kemudian berkomunikasi dengannya. Ini berarti ia menggunakan driver untuk melakukan komunikasi antara aplikasi dan file / dev / XXX.

Saya ingin memiliki output cat /proc/interrupts:; lsmod;ls -al /dev/yourmod

Inilah idenya:

  • Jika didorong oleh interupsi, Anda dapat mengatur PIC CPUs untuk menonaktifkan IRQ yang sesuai, kemudian mengaktifkannya kembali. Ini akan menyebabkan setiap permintaan kartu diabaikan (tanpa kartu menyadarinya).
  • jika itu seperti buffer read, Anda dapat:
    • Letakkan aplikasi Anda dalam kondisi sleep, sehingga data dari FPGA tidak akan dibaca, dan buffer Anda akan terisi, kemudian bangun aplikasi Anda dan lanjutkan membaca.
    • Gunakan "crash" atau "kgdb" untuk mengubah nilai "read" menjadi "noop" selama beberapa detik, kemudian atur kembali ke fungsi default.

Harap berikan semua informasi yang Anda temukan berguna.

Adrien M.
sumber
FPGA melakukan DMA menulis ke memori host, dan selama periode pemadaman ini, FPGA tidak dapat menulis ke memori host, sehingga FIFO internal mendukung. Ada antarmuka berbasis pesan ke proses host (terjadi pada PCIe), tapi saya yakin ini tidak terlibat. Untuk keperluan validasi, saya pada dasarnya memerlukan cara untuk melarang perangkat keras FPGA untuk menulis ke memori host selama beberapa ratus milidetik. Saya tidak ingin menyelesaikan masalah memori, tetapi saya ingin memastikan bahwa implementasi kami pada FPGA dapat menangani pemadaman memori (hingga 1000 ms).
Mark Lakata
Ok, jika menggunakan DMA, Anda dapat melihatnya di: kernel.org/doc/Documentation/DMA-ISA-LPC.txt khususnya pada claim_dma_lock () dan dma_disable (). Namun, Anda harus mengetahui alamat yang digunakan oleh FPGA Anda.
Adrien M.
1

Tidak yakin apakah itu membantu. Tetapi jika Anda dapat menulis modul kernel yang memanggil suspendfungsi modul kernel perangkat lain, itu mungkin dilakukan.

Setiap perangkat PCI dapat ditangguhkan sesuai dengan file header http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/pci.h#L479

Sebagai contoh, inilah fungsi menangguhkan Intel e1000 NIC http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/drivers/net/e1000e/netdev.c#L4643

Dari apa yang saya ingat, fungsi ini terutama digunakan ketika sistem beralih ke hibernasi, driver perangkat perlu menyimpan status yang sedang berjalan dan mematikannya sendiri.

yegle
sumber
terima kasih, tapi saya pikir itu tidak akan berhasil. Saya tidak benar-benar ingin menunda perangkat, yang merupakan kernel memberitahu perangkat untuk mempersiapkan hibernasi; Saya ingin kernel mengabaikan perangkat tertentu (dalam hal ini papan anak FPGA) tanpa sepengetahuan (selain latensi panjang atau waktu habis) - atau saya ingin menghentikan semua transfer memori SDRAM.
Mark Lakata
0

Saya pikir Anda berpikir di jalur yang salah. Tujuan Anda jelas.

Caranya bukan menghentikan proses yang lain tetapi memberikan proses utama Anda mendekati prioritas penjadwalan waktu-nyata. Gunakan yang bagus untuk proses ruang pengguna penting Anda untuk itu.

Masalah yang lebih sulit adalah penanganan interupsi PCIe, yang berada di ruang kernel.

Karena perangkat keras terlibat, Anda harus mulai melihat lebih dekat pada jalur PCIe yang terlibat di mainboard Anda dan bagaimana hal itu mungkin terhubung ke soket CPU tertentu.

irqbalance biasanya bekerja dengan baik di sini, tetapi Anda mungkin mengonfigurasi bahaviour sesuai dengan kebutuhan Anda.

Nils
sumber