特に、最悪のシナリオでLinuxの割り込みジッタ値を見つけようとしています。 2つのテストプラットフォームが考えられた。 1つはRaspberry Pi 4Bで、もう1つはIntel i9 CPUとASUSマザーボードを搭載した高度なPCでした。
+-+ +-+ +-+ Raspberry Pi 4B
| | | | | | -------------+
--+ +-+ +-+ +- 1. GPIO | +--------------+
Signal Generator | | |
+----> +-----+ | Linux |
| CPU | | ------------ |
+----> +-----+ | Kernel |
| | | | |
+-+--+-+ 2. PCIe MSI | +--------------+
--+ FPGA +-- ------------+
+-+--+-+ high-end PC (i9-9900K)
| |
Raspberry Piの場合、固定周波数方形波を割り込みソースに出力する信号発生器を使用します。高度なPCでは、PCIeを含むXilinx FPGAボードが割り込み要因として使用され、割り込みタイプはMSIです。信号発生器とザイリンクスFPGAボードの両方は、非常に小さなタイミングジッタ(<1us)で割り込みを生成できます。
以下はirq_handler
Raspberry Pi 4Bのドライバコード機能です。
static irqreturn_t gpio_ts_handler(int irq, void *arg) {
struct timespec64 timestamp;
struct gpio_ts_devinfo *devinfo;
int nwritten;
ktime_get_real_ts64(×tamp); // get the time
// lock the data fifo and insert the timestamp
spin_lock(&devinfo->spinlock);
nwritten = gpio_fifo_write(devinfo->fifo, ×tamp, 1);
spin_unlock(&devinfo->spinlock);
if (nwritten != 1) {
printk(KERN_ERR "GPIOTS: ISR fifo overflow\n");
}
// wake up the waiting thread which then read timestamp from the fifo
wake_up(&devinfo->waitqueue);
return IRQ_HANDLED;
}
irq_handler
高度なPCのドライバコード機能は次のとおりです。
// IRQ handler
static irqreturn_t fPCI_event_isr (int irq, void *cookie)
{
struct timespec64 tsc_now = {.tsc_high = 0; .tsc_low = 0};
struct fPCI_dev *drv_data = (struct fPCI_dev *) cookie;
int nwritten;
int fifo_size;
// get TSC timestamp
get_tsc_cpuid((tsc_now.tsc_high), (tsc_now.tsc_low));
spin_lock(&(drv_data->spin_lock));
nwritten = fpci_fifo_write(drv_data->fifo, &tsc_now, 1);
spin_unlock(&(drv_data->spin_lock));
if (nwritten != 1)
printk(KERN_INFO, "fPCI_event_isr: fifo overflow!\n");
fifo_size = fpci_fifo_size(drv_data->fifo);
if (fifo_size > FIFO_SIZE/2)
wake_up(&(drv_data->waitqueue));
return IRQ_HANDLED;
}
IRQハンドラコードでは、まず現在の時刻をFIFOに保存します。次に、ユーザ空間スレッドはFIFOからタイミングデータを読み出し、割り込みジッタを計算する。結果を次の2つの図に示す。
私の質問は次のとおりです
1 PCIe MSI割り込みがGPIO割り込みよりも待ち時間ジッタが大きいのはなぜですか?
2 最新の PCIe MSI 割り込みが最悪の場合、約 100us のレイテンシ変化があるのが正常ですか(私が欠落していますか?)。遅延時間(ジッタ)の変化を最小限に抑える方法。