วิธีบังคับให้เคอร์เนลของ Linux“ หยุด” (หรือเกือบหยุดนิ่ง) เป็นเวลาสองสามร้อยมิลลิวินาที


17

เรากำลังเรียกใช้กระบวนการแบบเรียลไทม์บนเคอร์เนลที่ไม่ใช่แบบเรียลไทม์ (CentOS 6) และนี่อาจจะไม่เปลี่ยนแปลง

เรามีแอพพลิเคชั่นวิดีโอสตรีมมิ่งที่ต้องการปริมาณการรับส่งข้อมูล PCIe ประมาณ 500 MB / s จาก FPGA ที่กำหนดเองอย่างต่อเนื่องเป็นเวลา 1.5 ชั่วโมงต่อครั้ง แอปพลิเคชั่นทำงานได้ดี - ส่วนใหญ่ อย่างไรก็ตามเรามีสถานการณ์ที่ดูเหมือนว่าเคอร์เนลจะหยุดตอบสนองต่อการให้บริการ PCIe หรือหน่วยความจำร้องขอสูงสุด 500 มิลลิวินาทีในแต่ละครั้ง สิ่งนี้ดูเหมือนว่าจะเกิดขึ้นในระหว่างการระเบิดไฟล์ IO จากเธรดอื่น ฉันพบว่ามันเป็นไปไม่ได้ที่จะพยายามทำซ้ำปัญหานี้โดยการทำไฟล์ดัมมี่จำนวนมาก IO จากพื้นที่ผู้ใช้ขณะที่แอปพลิเคชันหลักทำงานอยู่

มีวิธีบังคับ (จำลอง) "หยุด" ทั่วโลกของ Linux kernel (โดยเฉพาะการหยุด PCIe หรือการเข้าถึงหน่วยความจำ DDR3 ทั้งหมดหรืออะไรทำนองนั้น) เพื่อให้เราสามารถสร้างปัญหานี้ได้หรือไม่

ขณะนี้เรามีบัฟเฟอร์มากถึง 10 มิลลิวินาทีในหน่วยความจำ FPGA ภายใน แต่ก็ยังไม่เพียงพอ เราสามารถบัฟเฟอร์ไปยัง FPGA DDR3 แล้วถ่ายโอนไปยังโฮสต์ แต่เราต้องการวิธีการทดสอบคุณสมบัติใหม่นี้ภายใต้การข่มขู่

เราไม่ต้องการให้เคอร์เนลหยุดหรือล็อคอย่างถาวร เราต้องการความสามารถในการกำหนดช่วงเวลา

ฉันกำลังมองหาบางสิ่งบางอย่างตามแนวการเขียนค่าเวทย์มนตร์/proc/sys/vmเป็นการชั่วคราวที่ทำให้ระบบแทบจะคลานแล้วคืนกลับหลังจากไม่กี่ร้อยมิลลิวินาที แต่มองหาวิธีที่เป็นไปได้ที่จะทำลายมันไม่ใช่สำหรับมือใหม่อย่างฉัน ( https://www.kernel.org/doc/Documentation/sysctl/vm.txt ) อาจจะมีnumactlเวทมนตร์บ้างไหม?


ลางสังหรณ์ของฉันคือสิ่งนี้ต้องการการเขียนโมดูลเคอร์เนล คุณจะต้องหยุดเธรดทั้งหมดบน CPU ทั้งหมดอย่างใดอย่างหนึ่งและจัดการเพื่อเริ่มการทำงานใหม่บนตัวจับเวลาขัดจังหวะ
Gilles 'หยุดความชั่วร้าย'

ฉันไม่ต้องการตรึงเธรดฉันต้องการตรึงเคอร์เนล! ฉันหมายถึงฉันต้องการป้องกันการเข้าถึงฮาร์ดแวร์ (หน่วยความจำและ / หรือ PCIe และ / หรือดิสก์) ในเวลาอันสั้น ถ้านั่นไม่ได้ผลฉันไม่รังเกียจที่จะทำสิ่งต่าง ๆ ที่ไม่ได้เพิ่มประสิทธิภาพเป็นอย่างมากปิดใช้งานแคช L1 และอื่น ๆ ฉันก็ไม่รู้จะทำอย่างไร
Mark Lakata

1
อาดังนั้นคุณไม่ต้องการตรึงเคอร์เนลคุณเพียงต้องการตรึงส่วนของเคอร์เนลที่ตอบสนองต่อฮาร์ดแวร์บางตัวเท่านั้น นั่นก็จะต้องดำน้ำลึกเข้าไปในเคอร์เนล
Gilles 'SO- หยุดความชั่วร้าย'

ฉันไม่รังเกียจที่จะแช่แข็งเคอร์เนลอย่างสมบูรณ์ตราบใดที่ฮาร์ดแวร์นั้นค้างเป็นส่วนหนึ่งของมัน
Mark Lakata

1
ปรากฎว่าปัญหาเกี่ยวข้องกับ TLB thrashing เนื่องจากโฮสต์ CPU ล้างข้อมูลบัฟเฟอร์ IO บางตัว (เราใช้ HDF5 เพื่อเขียนไฟล์) และ TLB thrashing นี้ทำให้ตัวประมวลผลร่วมทำงานเป็น thrash เนื่องจากเป็นระบบ NUMA ฉันเดาว่าทุกอย่างที่เราต้องการในตอนนี้เป็นวิธีที่เชื่อถือได้ในการสร้างโปรแกรม TLB เพื่อการควบคุมเวลา
Mark Lakata

คำตอบ:


9

ทางเลือกหนึ่งที่จะทำการทดสอบอย่างรวดเร็วคือการใช้เคอร์เนลที่เปิดใช้งาน KGDB และหยุดเคอร์เนลด้วยตนเองและทดสอบดูลิงค์นี้

ในบันทึกอื่น ๆ สิ่งที่ฉันจำได้ว่าอาจทำให้คุณหยุดชั่วคราว:

  • cpufreq, cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_transition_latencyค่าอยู่ใน ns (4000 ใน AMD FX (tm) -8120 โปรเซสเซอร์แปดคอร์ของฉัน) ไม่น่ามีปัญหา แต่ตรวจสอบ
  • การควบคุมปริมาณความร้อนทั้งซีพียูเองหรือโมดูลควบคุมแรงดันไฟฟ้า
  • NAPI และ / หรือการรับส่งข้อมูลเครือข่ายจำนวนมาก
  • PCIe ASPM ( cat /sys/module/pcie_aspm/parameters/policy)
  • การช่วงชิงในบัฟเฟอร์ของอุปกรณ์ปลายทางของคุณ (ฮาร์ดดิสก์, นิก ... )
  • บั๊กในเฟิร์มแวร์ของอุปกรณ์บางอย่างในบัส PCIe (แม้ว่าคุณจะไม่ได้ใช้งาน) คุณสามารถลองปิดเครื่องด้วย /sys/bus/pci/devices/$DEVICE/power/control

ฉันสามารถใช้kdbแทนที่จะkgdbทำแบบเดียวกันได้หรือไม่? ฉันไม่เคยใช้ นี่เหมือนกับลำดับคำสั่ง "Stop-A" บนเวิร์กสเตชัน Sun ของปีกลายหรือไม่? หากฉันเพิ่งทำ SysRq-g อย่างรวดเร็วจากนั้นพิมพ์ "go" ฉันจะมีโอกาสสูงที่จะไม่ทำลายระบบหรือไม่ (อ้างอิง: kernel.org/pub/linux/kernel/people/jwessel/kdb/… )
Mark Lakata

1
อาจเป็นไปได้ว่าคุณจะสามารถใช้ kdb พึงระวังว่ามันควรจะทำงานกับคีย์บอร์ดที่เชื่อมต่อด้วย usb แต่ลองใช้ PS / 2 ที่มีประโยชน์ในกรณี และนี่คือ debugger ระดับต่ำมาก (เคอร์เนล land) ดังนั้นควรสำรองข้อมูลไว้เสมอและถ้ามันทำให้คุณได้รับทั้งสองส่วน :)
Jorge Nerín

ก่อนที่จะใช้วิธีปรับแต่งเคอร์เนลฉันจะลองยกเลิกการโหลดเคอร์เนลโมดูลที่ไม่ได้ใช้สำหรับอุปกรณ์ PCIe ที่สามารถใช้บัสได้ (ไดรเวอร์กราฟิกที่สะดุดตาที่สุด) และถอดอุปกรณ์ออกจากระบบหรือปิดเครื่อง PCIe 1.0 x1 มีแบนด์วิดธ์ 250MB / s และ PCIe 2.0 x1 สูงถึง 500MB / s ทั้งอุปกรณ์ต้นทางและปลายทางฟรีที่จะยอมรับอัตราที่ยั่งยืนดังกล่าวโดยไม่หยุดชะงักหรือมีช่องทางเพิ่มเติมเพื่อให้มีพื้นที่ว่างมากขึ้นหรือไม่
Jorge Nerín

อีกแหล่งที่มาของความล่าช้าอาจเป็นตัวจัดการการจัดการพลังงาน ACPI ของอุปกรณ์บางตัวหรืออาจเป็นตัวจัดการ CPU SMM บางตัวที่รอเหตุการณ์ภายนอก
Franki

2

เราสามารถมีรายละเอียดเพิ่มเติมว่าแอปพลิเคชันของคุณสื่อสารกับ FPGA ได้อย่างไร มันเป็นแอพพลิเคชั่นที่อ่านบัฟเฟอร์จาก FPGA หรือ FPGA ที่ส่งอินเตอร์รัปต์ไปยังเคอร์เนล (เช่นการ์ดเครือข่าย) หรือไม่?

ฉันคาดว่ามันจะเปิดบล็อก / ถ่านใน / dev แล้วสื่อสารกับมัน ซึ่งหมายความว่าจะใช้ไดรเวอร์ในการสื่อสารระหว่างแอปพลิเคชันและไฟล์ / dev / XXX

ฉันต้องการได้ผลลัพธ์ของ: cat /proc/interrupts; lsmod;ls -al /dev/yourmod

นี่คือความคิด:

  • หากมีการขัดจังหวะด้วยการขับเคลื่อนคุณสามารถตั้งค่า CPUs PIC ให้ปิดการใช้งาน IRQ ที่เกี่ยวข้องจากนั้นเปิดใช้งานอีกครั้ง สิ่งนี้จะทำให้ทุกคำขอของการ์ดถูกเพิกเฉย (โดยไม่ต้องคำนึงถึงการ์ด)
  • หากเป็นเหมือนการอ่านบัฟเฟอร์คุณอาจ:
    • ทำให้แอปพลิเคชันของคุณอยู่ในสถานะสลีปดังนั้นข้อมูลจาก FPGA จะไม่ถูกอ่านและบัฟเฟอร์ของคุณจะเต็มจากนั้นปลุกแอปพลิเคชันของคุณและอ่านต่อ
    • ใช้ "crash" หรือ "kgdb" เพื่อเปลี่ยนค่า "read" เป็น "noop" สองสามวินาทีจากนั้นตั้งค่ากลับเป็นฟังก์ชันเริ่มต้น

โปรดให้ข้อมูลทั้งหมดที่คุณอาจพบว่ามีประโยชน์


FPGA ทำ DMA เขียนไปยังหน่วยความจำโฮสต์และในระหว่างช่วงเวลาที่ขาดหายไป FPGA จะไม่สามารถเขียนไปยังหน่วยความจำโฮสต์ได้ดังนั้น FIFO ภายในจะสำรอง มีอินเทอร์เฟซแบบข้อความเพื่อกระบวนการโฮสต์ (เกิดขึ้นบน PCIe) แต่ฉันมั่นใจว่านี่ไม่เกี่ยวข้อง เพื่อวัตถุประสงค์ในการตรวจสอบความถูกต้องโดยทั่วไปฉันต้องการวิธีห้ามฮาร์ดแวร์ FPGA เพื่อเขียนไปยังหน่วยความจำโฮสต์สำหรับสองสามร้อยมิลลิวินาที ฉันไม่ต้องการแก้ปัญหาหน่วยความจำ แต่ฉันต้องการตรวจสอบให้แน่ใจว่าการติดตั้ง FPGA ของเราสามารถจัดการกับปัญหาหน่วยความจำหมด (สูงสุด 1,000 ms)
Mark Lakata

ตกลงถ้าใช้ DMA คุณอาจมีลักษณะ: kernel.org/doc/Documentation/DMA-ISA-LPC.txt โดยเฉพาะที่ claim_dma_lock () และ dma_disable () อย่างไรก็ตามคุณจะต้องรู้ที่อยู่ที่ใช้โดย FPGA ของคุณ
Adrien M.

1

ไม่แน่ใจว่ามันช่วยได้หรือไม่ แต่ถ้าคุณสามารถเขียนโมดูลเคอร์เนลที่เรียกใช้suspendฟังก์ชั่นของโมดูลเคอร์เนลของอุปกรณ์อื่นนั่นอาจทำ

อุปกรณ์ PCI แต่ละตัวสามารถถูกระงับได้ตามไฟล์ส่วนหัวhttp://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/pci.h#L479

ตัวอย่างเช่นฟังก์ชันระงับ Intel e1000 NIC นี่คือhttp://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/drivers/net/e1000e/netdev.c#L4643

จากสิ่งที่ฉันจำได้ฟังก์ชั่นนี้ส่วนใหญ่จะใช้เมื่อระบบเข้าสู่โหมดไฮเบอร์เนตไดรเวอร์อุปกรณ์จำเป็นต้องบันทึกสถานะการทำงานปัจจุบันและปิดตัวเอง


ขอบคุณ แต่ฉันไม่คิดว่ามันจะได้ผล ฉันไม่ต้องการหยุดอุปกรณ์ชั่วคราวซึ่งเคอร์เนลบอกให้อุปกรณ์เตรียมการจำศีล ฉันต้องการให้เคอร์เนลละเว้นอุปกรณ์เฉพาะ (ในกรณีนี้คือบอร์ดลูกสาว FPGA) โดยไม่ทราบ (นอกเหนือจากเวลาแฝงหรือหมดเวลานาน) - หรือฉันต้องการหยุดการถ่ายโอนหน่วยความจำ SDRAM ทั้งหมด
Mark Lakata

0

ฉันคิดว่าคุณกำลังคิดผิดไป เป้าหมายของคุณชัดเจน

วิธีไม่ได้หยุดกระบวนการที่เหลือ แต่ให้กระบวนการหลักของคุณใกล้ลำดับความสำคัญการกำหนดเวลาจริง ใช้ดีสำหรับกระบวนการพื้นที่ผู้ใช้ที่สำคัญของคุณ

ปัญหาที่ยากขึ้นคือการจัดการขัดจังหวะ PCIe ซึ่งอยู่ในเคอร์เนลพื้นที่

เนื่องจากฮาร์ดแวร์มีส่วนเกี่ยวข้องคุณควรเริ่มดู PCIe เลนที่เกี่ยวข้องอย่างใกล้ชิดบนเมนบอร์ดของคุณและวิธีที่อาจเชื่อมต่อกับซ็อกเก็ต CPU เฉพาะ

irqbalanceทำหน้าที่ได้ดีที่นี่ แต่คุณอาจกำหนดค่า bahaviour ให้เหมาะกับความต้องการของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.