TL; DR
Как запросы конфигурации MMIO, IO и PCI направляются на нужный узел в системе NUMA?
У каждого узла есть "таблица маршрутизации", но у меня сложилось впечатление, что ОС, как предполагается, не знает об этом.
Как ОС может переназначить устройства, если она не может изменить "таблицу маршрутизации"?
Для правильного знакомства с "таблицей маршрутизации", то есть декодерами исходного адреса (SAD), см. Декодирование физических адресов в Intel Xeon. ЦП v3/v4: дополнительная таблица данных.
Сначала я попытаюсь подытожить то, что я собрал из бумаг и едва документированных таблиц. К сожалению, это еще больше усугубит вопрос и может не иметь всех частей.
Когда запрос выходит из LLC 1, необходимо выяснить, куда его направить.
На процессорах рабочих станций целевыми объектами являются либо DRAM, либо один корневой порт PCIe/интегрированное устройство, либо интерфейс DMI.
Uncore может легко определить, принадлежит ли запрос памяти к DRAM благодаря регистрам iMC 2 или одному из корневого порта PCIe 3/встроенному устройству, и в конечном итоге откатится к DMI.
Это, конечно, также включает MMIO и практически идентично для ввода-вывода с отображением портов (которое пропускает только проверку DRAM).
Запросы конфигурации PCI (CFG) маршрутизируются согласно спецификации с единственным предупреждением, что запросы CFG на шине 0, не предназначенные для интегрированных устройств, отправляются по интерфейсу DMI 4.
На ЦП сервера целевой адрес может быть вне сокета.
Таблица используется для поиска идентификатора узла (NID) 5. Эта таблица называется SAD.
Фактически, SAD состоит из двух декодеров: декодера DRAM (который использует таблицу) и декодера IO 6 (который состоит в основном из фиксированных диапазонов и разрешающих битов, но также должен содержать таблицы).
При необходимости IO-декодер переопределяет декодер DRAM.
Декодер DRAM работает со списком диапазонов, каждый из которых связан со списком целевых NID 7.
Если запрос конфигурации памяти, MMIO или PCIe (MMCFG) совпадает с диапазоном, uncore отправит запрос по пути QPI/UPI выбранной цели (неясно, может ли SAD предназначаться для самого узла-запросчика).
Декодер ввода-вывода работает либо с разрешающими битами для фиксированных диапазонов с фиксированными целями (например, вернуть устаревшие окна BIOS на "BIOS NID"), либо с переменным диапазоном, где часть адреса используется для индексации списка целей.
Назначения портов ввода-вывода с сопоставлением портов ищутся в таблице, обозначенной как IO[yyy]
.
Назначения ввода-вывода MMCFG ищутся в таблице с именем PCI[zzz]
.
Пункты назначения CFG повторно используют таблицу PCI[zzz]
.
Здесь yyy
и zzz
обозначают индексную функцию, то есть часть адреса запроса (zzz
- номер шины для CFG).
Все это имеет смысл для меня, но эти таблицы не задокументированы в таблице данных, поэтому такой символ, как PCI[zzz]
, может фактически означать что-то совершенно другое.
Хотя документации по этим декодерам практически нет, этого достаточно для примитивной ментальной модели.
Мне все еще неясно, используются ли SAD даже для запросов, предназначенных для локальных ресурсов, или они используются только для исходящих запросов.
Это будет важно позже.
Предположим, что когда запрос покидает LLC, SAD используются для маршрутизации его к компоненту (в конечном итоге в том же сокете), а затем он обрабатывается аналогично случаю рабочей станции 8.
Пока аппаратная конфигурация не изменена, SAD может быть настроен микропрограммным обеспечением, а ОС может быть полностью независимой от них.
Но что произойдет, если ОС переназначит устройство PCIe, которое находится за локальным каналом PCIe узла?
Чтобы запрос MMIO достиг такого устройства, он должен сначала достичь узла устройства (поскольку это единственная связь с остальной частью системы), но это может произойти, только если SAD правильно переконфигурированы.
Переконфигурирование SAD может потребоваться даже для запросов, исходящих из того же узла, что и устройство 9.
Но предполагается, что ОС не знает о SAD или нет?
У меня есть несколько возможных ответов:
- SAD не используются для доступа к локальным ресурсам, и ОС ограничивает доступ к локальному вводу-выводу только процессам (или ядру), работающим в родительском узле. Это исключает необходимость перенастройки SAD.
- Микропрограмма конфигурирует SAD так, чтобы каждый узел имел часть адресного пространства (скажем, 2 k/N, где k - размер физического адресного пространства, а N - номер узла) и сообщает об этом в таблице SRAT ACPI., (но не является ли SRAT необязательным?) 10 Затем ОС распределяет ресурсы MMIO только внутри каждой части памяти узла. Это может привести к неоптимальному использованию памяти.
- SAD - это оптимизация, если неядерный не знает, куда направить запрос, он будет передавать его по ссылкам QPI/UPI до тех пор, пока он не будет принят узлом.
- Все выше не так.
1, например. из-за пропуска или из-за того, что UC.
2, например, TOUM
для максимального физического адреса, который может быть восстановлен посредством DRAM, хотя это не непрерывный блок.
3 Это мост PCI-PCI (P2P), имеющий регистры для установки окон ввода-вывода, памяти с предварительной выборкой и без предварительной выборки.
4 Вот почему устройства PCH появляются на шине 0. ЦП сервера имеют две "внутренние" шины, и их номера могут быть изменены.
5 Идентификатор узла состоит из номера сокета и неосновного идентификатора компонента. Я знаю, что uncore-компонент, который может быть целью (после перевода имени из номенклатуры "box"): первый или второй Home agent (iMC), системный агент и ссылка DMI.
6 Таблица IO-декодера разделена на IOS (IO Small декодер) и IOL (IO Large декодер). Это отражает аппаратные возможности двух таблиц, при этом IOS почти фиксирована, а IOL - CAM. С обоими обращаются параллельно с таблицей DRAM, IOS переопределяет IOL, если оба совпадают.
7 Диапазон автоматически перемежается (то есть подразделяется) между всеми восемью целями. Чтобы использовать менее восьми целей, могут использоваться повторяющиеся записи (например, все установленные на одни и те же цели совпадают с отсутствием чередования).
8 Интересно, что произойдет, если SAD направит запрос к неосновному компоненту (скажем, iMC), но за пределами его исправленного диапазона? Я предполагаю, что это отброшено.
9 См. жирную часть выше, я не знаю, как SAD работает с запросами, ориентированными на локальные ресурсы.
10 Linux подделывает узел NUMA на машинах UMA. В моем ящике количество памяти, выделенной узлу, включает MMIO (почти 10 ГБ, выделенных против 8 ГБ или DRAM). Кажется, весь диапазон, возвращаемый E8020, используется.