最悪のPCIe MSI割り込み遅延ジッタが100usを超えるのは正常ですか?

最悪のPCIe MSI割り込み遅延ジッタが100usを超えるのは正常ですか?

特に、最悪のシナリオで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_handlerRaspberry 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(&timestamp);   // get the time

    // lock the data fifo and insert the timestamp
    spin_lock(&devinfo->spinlock);
    nwritten = gpio_fifo_write(devinfo->fifo, &timestamp, 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 のレイテンシ変化があるのが正常ですか(私が欠落していますか?)。遅延時間(ジッタ)の変化を最小限に抑える方法。

関連情報