Я хочу, чтобы все запросы на чтение и запись к устройству PCIe кэшировались кэшами ЦП.Однако это не работает, как я ожидал.
Это мои предположения о регионах MMIO с обратной записью.
- Запись на устройство PCIe происходит только при обратной записи в кэш.
- Размер полезных нагрузок TLP равен размеру блока кэша (64B).
Однако перехваченные TLP не соответствуют моим предположениям.
- Записывает в PCIeустройство происходит при каждой записи в регион MMIO.
- Размер полезной нагрузки TLP составляет 1B.
Я записываю 8-байтовый код 0xff
в область MMIO со следующим пользователемкосмическая программа и драйвер устройства.
часть пользовательской программы
struct pcie_ioctl ioctl_control;
ioctl_control.bar_select = BAR_ID;
ioctl_control.num_bytes_to_write = atoi(argv[1]);
if (ioctl(fd, IOCTL_WRITE_0xFF, &ioctl_control) < 0) {
printf("ioctl failed\n");
}
часть драйвера устройства
case IOCTL_WRITE_0xFF:
{
int i;
char *buff;
struct pci_cdev_struct *pci_cdev = pci_get_drvdata(fpga_pcie_dev.pci_device);
copy_from_user(&ioctl_control, (void __user *)arg, sizeof(ioctl_control));
buff = kmalloc(sizeof(char) * ioctl_control.num_bytes_to_write, GFP_KERNEL);
for (i = 0; i < ioctl_control.num_bytes_to_write; i++) {
buff[i] = 0xff;
}
memcpy(pci_cdev->bar[ioctl_control.bar_select], buff, ioctl_control.num_bytes_to_write);
kfree(buff);
break;
}
Я изменил MTRR для обратной записи соответствующего региона MMIO.Регион MMIO начинается с 0x0c7300000, а длина составляет 0x100000 (1 МБ).Ниже приведены cat /proc/mtrr
результаты для различных политик.Обратите внимание, что я сделал каждый регион эксклюзивным.
Uncacheable
reg00: base=0x080000000 ( 2048MB), size= 1024MB, count=1: uncachable
reg01: base=0x380000000000 (58720256MB), size=524288MB, count=1: uncachable
reg02: base=0x0c0000000 ( 3072MB), size= 64MB, count=1: uncachable
reg03: base=0x0c4000000 ( 3136MB), size= 32MB, count=1: uncachable
reg04: base=0x0c6000000 ( 3168MB), size= 16MB, count=1: uncachable
reg05: base=0x0c7000000 ( 3184MB), size= 1MB, count=1: uncachable
reg06: base=0x0c7100000 ( 3185MB), size= 1MB, count=1: uncachable
reg07: base=0x0c7200000 ( 3186MB), size= 1MB, count=1: uncachable
reg08: base=0x0c7300000 ( 3187MB), size= 1MB, count=1: uncachable
reg09: base=0x0c7400000 ( 3188MB), size= 1MB, count=1: uncachable
Комбинирование записи
reg00: base=0x080000000 ( 2048MB), size= 1024MB, count=1: uncachable
reg01: base=0x380000000000 (58720256MB), size=524288MB, count=1: uncachable
reg02: base=0x0c0000000 ( 3072MB), size= 64MB, count=1: uncachable
reg03: base=0x0c4000000 ( 3136MB), size= 32MB, count=1: uncachable
reg04: base=0x0c6000000 ( 3168MB), size= 16MB, count=1: uncachable
reg05: base=0x0c7000000 ( 3184MB), size= 1MB, count=1: uncachable
reg06: base=0x0c7100000 ( 3185MB), size= 1MB, count=1: uncachable
reg07: base=0x0c7200000 ( 3186MB), size= 1MB, count=1: uncachable
reg08: base=0x0c7300000 ( 3187MB), size= 1MB, count=1: write-combining
reg09: base=0x0c7400000 ( 3188MB), size= 1MB, count=1: uncachable
Обратная запись
reg00: base=0x080000000 ( 2048MB), size= 1024MB, count=1: uncachable
reg01: base=0x380000000000 (58720256MB), size=524288MB, count=1: uncachable
reg02: base=0x0c0000000 ( 3072MB), size= 64MB, count=1: uncachable
reg03: base=0x0c4000000 ( 3136MB), size= 32MB, count=1: uncachable
reg04: base=0x0c6000000 ( 3168MB), size= 16MB, count=1: uncachable
reg05: base=0x0c7000000 ( 3184MB), size= 1MB, count=1: uncachable
reg06: base=0x0c7100000 ( 3185MB), size= 1MB, count=1: uncachable
reg07: base=0x0c7200000 ( 3186MB), size= 1MB, count=1: uncachable
reg08: base=0x0c7300000 ( 3187MB), size= 1MB, count=1: write-back
reg09: base=0x0c7400000 ( 3188MB), size= 1MB, count=1: uncachable
Ниже приведены захваты сигнала для записи 8B с различными политиками.Я использовал встроенный логический анализатор (ILA) для захвата этих сигналов.Пожалуйста, смотрите pcie_endpoint_litepcietlpdepacketizer_tlp_req_payload_dat
, когда установлено pcie_endpoint_litepcietlpdepacketizer_tlp_req_valid
.Вы можете подсчитать количество пакетов, посчитав pcie_endpoint_litepcietlpdepacketizer_tlp_req_valid
в этом примере формы волны.
- Не кэшируемый : link -> правильный, 1B x 8 пакетов
- Комбинирование записи : ссылка -> правильно, 8B x 1 пакет
- Обратная запись : ссылка -> неожиданно, 1B x 8 пакетов
Конфигурация системы, как показано ниже.
- ЦП : Intel (R) Xeon (R)) CPU E5-2630 v4 @ 2,20 ГГц
- OS : ядро Linux 4.15.0-38
- Устройство PCIe : Xilinx FPGA KC705, запрограммированный с litepcie
Ссылки по теме
- Создание 64-байтового чтения PCIe TLP из процессора x86
- Как реализовать 64B PCIe * Burst Transfer на архитектуре Intel®
- Пишущий комбинирующий буфер записи из строя и PCIe
- Поддерживает ли Ryzen кэширование с обратной записью для Memory Mapped IO (через PCIe interface)?
- MTRR (регистр диапазона типов памяти)
- PATting Linux
- Downна TLP: как говорят устройства PCI Express (Часть I)