Картографирование MMIO региона с обратной записью не работает - PullRequest
0 голосов
/ 15 ноября 2018

Я хочу, чтобы все запросы на чтение и запись к устройству PCIe кэшировались кэшами ЦП.Однако это не работает, как я ожидал.

Это мои предположения о регионах MMIO с обратной записью.

  1. Запись на устройство PCIe происходит только при обратной записи в кэш.
  2. Размер полезных нагрузок TLP равен размеру блока кэша (64B).

Однако перехваченные TLP не соответствуют моим предположениям.

  1. Записывает в PCIeустройство происходит при каждой записи в регион MMIO.
  2. Размер полезной нагрузки 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 в этом примере формы волны.

  1. Не кэшируемый : link -> правильный, 1B x 8 пакетов
  2. Комбинирование записи : ссылка -> правильно, 8B x 1 пакет
  3. Обратная запись : ссылка -> неожиданно, 1B x 8 пакетов

Конфигурация системы, как показано ниже.

  • ЦП : Intel (R) Xeon (R)) CPU E5-2630 v4 @ 2,20 ГГц
  • OS : ядро ​​Linux 4.15.0-38
  • Устройство PCIe : Xilinx FPGA KC705, запрограммированный с litepcie

Ссылки по теме

  1. Создание 64-байтового чтения PCIe TLP из процессора x86
  2. Как реализовать 64B PCIe * Burst Transfer на архитектуре Intel®
  3. Пишущий комбинирующий буфер записи из строя и PCIe
  4. Поддерживает ли Ryzen кэширование с обратной записью для Memory Mapped IO (через PCIe interface)?
  5. MTRR (регистр диапазона типов памяти)
  6. PATting Linux
  7. Downна TLP: как говорят устройства PCI Express (Часть I)

1 Ответ

0 голосов
/ 15 ноября 2018

Короче говоря, кажется, что отображение обратной записи MMIO не работает преднамеренно.

Пожалуйста, загрузите ответ, если кто-нибудь обнаружит, что это возможно.

Я пришел, чтобы найти статьи и ответы Джона Маккальпина. Во-первых, отображение обратной записи MMIO невозможно. Во-вторых, на некоторых процессорах возможен обходной путь.

  1. Невозможно выполнить обратную запись в регион MMIO

    Цитировать по этой ссылке

    К вашему сведению: тип WB не будет работать с отображенным в память вводом-выводом. Вы можете запрограммируйте биты, чтобы установить отображение как WB, но система сбой, как только он получает транзакцию, что он не знает, как справиться. Теоретически возможно использовать WP или WT для кэширования читает из MMIO, но согласованность должна обрабатываться программно.

    Цитировать по этой ссылке

    Только когда я устанавливаю для PAT и MTRR значение WB, происходит сбой ядра

  2. Обходной путь возможен на некоторых процессорах

    Замечания о кэшированном доступе к отображенным в память областям ввода-вывода, Джон МакКалпин

    Существует один набор отображений, который можно настроить для работы, по крайней мере, с некоторыми процессоры x86-64, и это основано на отображении пространства MMIO дважды . Сопоставьте диапазон MMIO с набором атрибутов, которые позволяют комбинировать записи хранит (но читает только без кэша). Сопоставьте диапазон MMIO во второй раз с набором атрибутов, которые позволяют чтение строки кэша (но только некэшированные, не записанные в комбинированные хранилища).

...