Logo

Linux 核心

6.16.0-rc4

快速搜尋

目錄

  • 開發流程
  • 提交補丁
  • 行為準則
  • 維護者手冊
  • 所有開發流程文件
  • 核心 API
  • 驅動程式 API
    • 驅動程式作者的一般資訊
    • 有用的支援庫
    • 匯流排級文件
      • 輔助匯流排
      • Compute Express Link
      • EISA 匯流排支援
      • Firewire (IEEE 1394) 驅動程式介面指南
      • I3C 子系統
      • ISA 驅動程式
      • MEN Chameleon 匯流排
      • Linux PCI 驅動程式實現者 API 指南
      • Linux RapidIO 子系統
      • Linux 核心 SLIMbus 支援
      • Linux USB API
      • Virtio
      • VME 裝置驅動程式
      • W1: Dallas 的 1-wire 匯流排
      • 用於通用 FPGA 介面的 Xillybus 驅動程式
    • 子系統特定 API
  • 子系統
  • 鎖定
  • 許可規則
  • 編寫文件
  • 開發工具
  • 測試指南
  • 駭客指南
  • 跟蹤
  • 故障注入
  • Livepatching
  • Rust
  • 管理
  • 構建系統
  • 報告問題
  • 使用者空間工具
  • 使用者空間 API
  • 韌體
  • 韌體和裝置樹
  • CPU 架構
  • 未排序的文件
  • 翻譯

本頁

  • 顯示原始碼

Compute Express Link 驅動程式操作理論¶

Compute Express Link 記憶體裝置是一個實現 CXL.mem 協議的 CXL 元件。它包含一定量的易失性儲存器、永續性儲存器或兩者。它被列舉為 PCI 裝置,用於配置和透過 MMIO 郵箱傳遞訊息。它對系統物理地址空間的貢獻透過 HDM(主機管理裝置記憶體)解碼器處理,這些解碼器可以選擇性地定義裝置對主機橋下的多個裝置或跨主機橋交織的地址範圍的貢獻。

CXL 匯流排¶

類似於 RAID 驅動程式如何獲取磁碟物件並將它們組裝成新的邏輯裝置,CXL 子系統的任務是獲取 PCIe 和 ACPI 物件並將它們組裝成 CXL.mem 解碼拓撲。CXL.mem 拓撲的執行時配置需求也類似於 RAID,因為具有相同硬體配置的不同環境可能會決定以不同的方式組裝拓撲。一種方式可以選擇效能(RAID0),跨多個主機橋和端點進行記憶體條帶化,而另一種方式可以選擇容錯並停用 CXL.mem 拓撲中的任何條帶化。

平臺韌體在“CXL 根埠”(Linux 術語,表示 CXL 解碼拓撲的頂部)列舉一個交織選項選單。從那裡,PCIe 拓撲決定了哪些端點可以參與哪些主機橋解碼方案。根埠和端點之間的路徑中的每個 PCIe 交換機都引入了一個可以分割交織的點。例如,平臺韌體可能會說在給定的範圍內僅解碼到一個主機橋,但該主機橋可能會依次跨多個根埠交織週期。埠和端點之間的中間交換機可能會跨多個下游交換機埠交織週期,等等。

這是一個由“cxl_test”定義的 CXL 拓撲示例列表。“cxl_test”模組生成一個模擬 CXL 拓撲,包含 2 個主機橋,每個主機橋有 2 個根埠。每個根埠都連線到 2 路交換機,端點連線到這些下游埠,總共有 8 個端點

# cxl list -BEMPu -b cxl_test
{
  "bus":"root3",
  "provider":"cxl_test",
  "ports:root3":[
    {
      "port":"port5",
      "host":"cxl_host_bridge.1",
      "ports:port5":[
        {
          "port":"port8",
          "host":"cxl_switch_uport.1",
          "endpoints:port8":[
            {
              "endpoint":"endpoint9",
              "host":"mem2",
              "memdev":{
                "memdev":"mem2",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x1",
                "numa_node":1,
                "host":"cxl_mem.1"
              }
            },
            {
              "endpoint":"endpoint15",
              "host":"mem6",
              "memdev":{
                "memdev":"mem6",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x5",
                "numa_node":1,
                "host":"cxl_mem.5"
              }
            }
          ]
        },
        {
          "port":"port12",
          "host":"cxl_switch_uport.3",
          "endpoints:port12":[
            {
              "endpoint":"endpoint17",
              "host":"mem8",
              "memdev":{
                "memdev":"mem8",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x7",
                "numa_node":1,
                "host":"cxl_mem.7"
              }
            },
            {
              "endpoint":"endpoint13",
              "host":"mem4",
              "memdev":{
                "memdev":"mem4",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x3",
                "numa_node":1,
                "host":"cxl_mem.3"
              }
            }
          ]
        }
      ]
    },
    {
      "port":"port4",
      "host":"cxl_host_bridge.0",
      "ports:port4":[
        {
          "port":"port6",
          "host":"cxl_switch_uport.0",
          "endpoints:port6":[
            {
              "endpoint":"endpoint7",
              "host":"mem1",
              "memdev":{
                "memdev":"mem1",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0",
                "numa_node":0,
                "host":"cxl_mem.0"
              }
            },
            {
              "endpoint":"endpoint14",
              "host":"mem5",
              "memdev":{
                "memdev":"mem5",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x4",
                "numa_node":0,
                "host":"cxl_mem.4"
              }
            }
          ]
        },
        {
          "port":"port10",
          "host":"cxl_switch_uport.2",
          "endpoints:port10":[
            {
              "endpoint":"endpoint16",
              "host":"mem7",
              "memdev":{
                "memdev":"mem7",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x6",
                "numa_node":0,
                "host":"cxl_mem.6"
              }
            },
            {
              "endpoint":"endpoint11",
              "host":"mem3",
              "memdev":{
                "memdev":"mem3",
                "pmem_size":"256.00 MiB (268.44 MB)",
                "ram_size":"256.00 MiB (268.44 MB)",
                "serial":"0x2",
                "numa_node":0,
                "host":"cxl_mem.2"
              }
            }
          ]
        }
      ]
    }
  ]
}

在該列表中,每個“root”、“port”和“endpoint”物件對應一個核心“struct cxl_port”物件。“cxl_port”是一個可以將其後代解碼為 CXL.mem 的裝置。因此,“root”宣告非 PCIe 可列舉的平臺解碼範圍並將它們解碼為“ports”,“ports”解碼為“endpoints”,而“endpoints”表示從 SPA(系統物理地址)到 DPA(裝置物理地址)的解碼。

繼續 RAID 類比,磁碟既有拓撲元資料,也有裝置上的元資料,用於確定 RAID 集的組裝。CXL 埠拓撲和 CXL 埠連結狀態是 CXL.mem 集組裝的元資料。CXL 埠拓撲是透過 CXL.mem 裝置的到達來列舉的。也就是說,除非 PCIe 核心將 cxl_pci 驅動程式附加到 CXL 記憶體擴充套件器,否則 CXL 埠物件沒有任何作用。相反,對於熱插拔/移除場景,Linux PCI 核心不需要拆除交換機級別的 CXL 資源,因為 endpoint ->remove() 事件會清理為支援該記憶體擴充套件器而建立的埠資料。

可以透過以下命令確定埠元資料和給定記憶體裝置可能參與的潛在解碼方案

# cxl list -BDMu -d root -m mem3
{
  "bus":"root3",
  "provider":"cxl_test",
  "decoders:root3":[
    {
      "decoder":"decoder3.1",
      "resource":"0x8030000000",
      "size":"512.00 MiB (536.87 MB)",
      "volatile_capable":true,
      "nr_targets":2
    },
    {
      "decoder":"decoder3.3",
      "resource":"0x8060000000",
      "size":"512.00 MiB (536.87 MB)",
      "pmem_capable":true,
      "nr_targets":2
    },
    {
      "decoder":"decoder3.0",
      "resource":"0x8020000000",
      "size":"256.00 MiB (268.44 MB)",
      "volatile_capable":true,
      "nr_targets":1
    },
    {
      "decoder":"decoder3.2",
      "resource":"0x8050000000",
      "size":"256.00 MiB (268.44 MB)",
      "pmem_capable":true,
      "nr_targets":1
    }
  ],
  "memdevs:root3":[
    {
      "memdev":"mem3",
      "pmem_size":"256.00 MiB (268.44 MB)",
      "ram_size":"256.00 MiB (268.44 MB)",
      "serial":"0x2",
      "numa_node":0,
      "host":"cxl_mem.2"
    }
  ]
}

...它查詢 CXL 拓撲以詢問“給定核心裝置名稱為‘mem3’的 CXL 記憶體擴充套件器,此裝置可能參與哪些平臺級別解碼範圍”。給定的擴充套件器可以同時參與多個 CXL.mem 交織集,具體取決於它有多少解碼器資源。在此示例中,mem3 可以參與一個或多個跨主機橋的 PMEM 交織,一個針對單個主機橋的 PMEM 交織,一個跨 2 個主機橋的易失性記憶體交織,以及一個僅針對單個主機橋的易失性記憶體交織。

相反,可以透過以下命令確定可以參與給定平臺級別解碼方案的記憶體裝置

# cxl list -MDu -d 3.2
[
  {
    "memdevs":[
      {
        "memdev":"mem1",
        "pmem_size":"256.00 MiB (268.44 MB)",
        "ram_size":"256.00 MiB (268.44 MB)",
        "serial":"0",
        "numa_node":0,
        "host":"cxl_mem.0"
      },
      {
        "memdev":"mem5",
        "pmem_size":"256.00 MiB (268.44 MB)",
        "ram_size":"256.00 MiB (268.44 MB)",
        "serial":"0x4",
        "numa_node":0,
        "host":"cxl_mem.4"
      },
      {
        "memdev":"mem7",
        "pmem_size":"256.00 MiB (268.44 MB)",
        "ram_size":"256.00 MiB (268.44 MB)",
        "serial":"0x6",
        "numa_node":0,
        "host":"cxl_mem.6"
      },
      {
        "memdev":"mem3",
        "pmem_size":"256.00 MiB (268.44 MB)",
        "ram_size":"256.00 MiB (268.44 MB)",
        "serial":"0x2",
        "numa_node":0,
        "host":"cxl_mem.2"
      }
    ]
  },
  {
    "root decoders":[
      {
        "decoder":"decoder3.2",
        "resource":"0x8050000000",
        "size":"256.00 MiB (268.44 MB)",
        "pmem_capable":true,
        "nr_targets":1
      }
    ]
  }
]

...其中解碼器的命名方案是“decoder<port_id>.<instance_id>”。

驅動程式基礎設施¶

本節介紹 CXL 記憶體裝置的驅動程式基礎設施。

CXL 記憶體裝置¶

這實現了 CXL 裝置由 Compute Express Link 規範定義的 PCI 獨有功能。即使未啟用 CXL,CXL 裝置也可能會顯示某些功能。雖然此驅動程式專注於 CXL 裝置的 PCI 特定方面,但它繫結到特定的 CXL 記憶體裝置類程式碼,因此 cxl_pci 的實現專注於 CXL 記憶體裝置。

該驅動程式有幾個職責,主要包括
  • 建立 memX 裝置並在 CXL 總線上註冊。

  • 列舉裝置的暫存器介面並對映它們。

  • 使用 cxl_core 註冊 nvdimm 橋接裝置。

  • 使用 cxl_core 註冊 CXL 郵箱。

int __cxl_pci_mbox_send_cmd(struct cxl_mailbox *cxl_mbox, struct cxl_mbox_cmd *mbox_cmd)¶

執行郵箱命令

引數

struct cxl_mailbox *cxl_mbox

CXL 郵箱上下文

struct cxl_mbox_cmd *mbox_cmd

要傳送到記憶體裝置的命令。

上下文

任何上下文。需要持有 mbox_mutex。

返回

-ETIMEDOUT 如果等待完成時發生超時。成功則返回 0。

呼叫者應檢查 mbox_cmd 中的返回值,以確保它成功。

描述

這是 CXL 郵箱傳送命令的通用形式,因此僅使用郵箱功能 ID 定義的暫存器 - CXL 2.0 8.2.8.4。記憶體裝置,以及其他型別的 CXL 裝置,可能在錯誤情況下提供更多資訊。希望傳送郵箱命令的驅動程式設施應使用包裝器命令。

CXL 規範允許最多兩個郵箱。目的是讓主郵箱由作業系統控制,而輔助郵箱由系統韌體使用。這允許作業系統和韌體與裝置通訊,而無需相互協調。驅動程式僅使用主郵箱。

CXL 記憶體端點裝置和交換機是參與 CXL.mem 協議的具有 CXL 功能的裝置。它們的功能建立在 CXL.io 協議之上,該協議允許透過標準 PCI 機制列舉和配置元件。

cxl_mem 驅動程式擁有啟動此 CXL.mem 功能列舉的許可權。透過檢測到具有 CXL 功能的端點,驅動程式將向上查詢其連線到的平臺特定埠,並確定路徑中是否存在中間交換機。如果存在交換機,則輔助操作是列舉這些交換機(在 cxl_core 中實現)。最後,cxl_mem 驅動程式將它繫結的裝置新增為 CXL 端點埠,以用於更高級別的操作。

struct cxl_memdev¶

表示 Type-3 記憶體裝置的 CXL 匯流排物件

定義:

struct cxl_memdev {
    struct device dev;
    struct cdev cdev;
    struct cxl_dev_state *cxlds;
    struct work_struct detach_work;
    struct cxl_nvdimm_bridge *cxl_nvb;
    struct cxl_nvdimm *cxl_nvd;
    struct cxl_port *endpoint;
    int id;
    int depth;
    u8 scrub_cycle;
    int scrub_region_id;
    void *err_rec_array;
};

成員

dev

驅動程式核心裝置物件

cdev

用於 ioctl 操作的字元裝置核心物件

cxlds

支援此裝置的裝置狀態

detach_work

活動 memdev 在其祖先中失去了一個埠

cxl_nvb

如果存在 cxl_nvd,則協調移除

cxl_nvd

如果裝置支援 pmem,則可選的 nvdimm 橋

endpoint

此記憶體裝置與 CXL 埠拓撲的連線

id

此 memdev 例項的 ID 號。

depth

端點埠深度

scrub_cycle

為此裝置設定的當前 scrub 週期

scrub_region_id

為其設定當前 scrub 週期的支援區域的 ID 號(如果有)

err_rec_array

儲存 memdev 錯誤記錄的 xarrays 列表,用於檢查記憶體修復操作的屬性是否來自當前啟動。

struct cxl_event_state¶

事件日誌驅動程式狀態

定義:

struct cxl_event_state {
    struct cxl_get_event_payload *buf;
    struct mutex log_lock;
};

成員

buf

用於接收事件資料的緩衝區

log_lock

序列化 event_buf 和日誌使用

struct cxl_poison_state¶

驅動程式中毒狀態資訊

定義:

struct cxl_poison_state {
    u32 max_errors;
    unsigned long enabled_cmds[BITS_TO_LONGS(CXL_POISON_ENABLED_MAX)];
    struct cxl_mbox_poison_out *list_out;
    struct mutex lock;
};

成員

max_errors

裝置快取中儲存的最大介質錯誤記錄數

enabled_cmds

CEL 中啟用的所有中毒命令

list_out

裝置返回的中毒列表有效負載

lock

保護中毒列表的讀取

描述

中毒列表的讀取是同步的,以確保讀取器不會獲得不完整的列表,因為他們的請求重疊(被中斷或前面有)同一 DPA 範圍的另一個讀取請求。CXL 規範 3.0 第 8.2.9.8.4.1 節

struct cxl_fw_state¶

韌體上傳/啟用狀態

定義:

struct cxl_fw_state {
    unsigned long state[BITS_TO_LONGS(CXL_FW_STATE_BITS)];
    bool oneshot;
    int num_slots;
    int cur_slot;
    int next_slot;
};

成員

state

fw_uploader 狀態位掩碼

oneshot

韌體上傳是否適合單次傳輸

num_slots

可用的韌體插槽數

cur_slot

當前活動的插槽號

next_slot

新韌體的插槽號

struct cxl_security_state¶

裝置安全狀態

定義:

struct cxl_security_state {
    unsigned long state;
    unsigned long enabled_cmds[BITS_TO_LONGS(CXL_SEC_ENABLED_MAX)];
    int poll_tmo_secs;
    bool sanitize_active;
    struct delayed_work poll_dwork;
    struct kernfs_node *sanitize_node;
};

成員

state

上次安全操作的狀態

enabled_cmds

CEL 中啟用的所有安全命令

poll_tmo_secs

輪詢超時

sanitize_active

待處理的清理完成

poll_dwork

輪詢工作項

sanitize_node

要通知的清理 sysfs 檔案

struct cxl_dpa_perf¶

DPA 效能屬性條目

定義:

struct cxl_dpa_perf {
    struct range dpa_range;
    struct access_coordinate coord[ACCESS_COORDINATE_MAX];
    struct access_coordinate cdat_coord[ACCESS_COORDINATE_MAX];
    int qos_class;
};

成員

dpa_range

DPA 地址的範圍

coord

QoS 效能資料(即延遲、頻寬)

cdat_coord

來自 CDAT 的原始 QoS 效能資料

qos_class

QoS 類 Cookie

struct cxl_dpa_partition¶

DPA 分割槽描述符

定義:

struct cxl_dpa_partition {
    struct resource res;
    struct cxl_dpa_perf perf;
    enum cxl_partition_mode mode;
};

成員

res

DPA 資源樹 (cxlds->dpa_res) 中分割槽的快捷方式

perf

來自 CDAT 的分割槽的效能屬性

mode

DPA 容量的操作模式,例如 ram、pmem、dynamic...

struct cxl_dev_state¶

驅動程式裝置狀態

定義:

struct cxl_dev_state {
    struct device *dev;
    struct cxl_memdev *cxlmd;
    struct cxl_register_map reg_map;
    struct cxl_regs regs;
    int cxl_dvsec;
    bool rcd;
    bool media_ready;
    struct resource dpa_res;
    struct cxl_dpa_partition part[CXL_NR_PARTITIONS_MAX];
    unsigned int nr_partitions;
    u64 serial;
    enum cxl_devtype type;
    struct cxl_mailbox cxl_mbox;
#ifdef CONFIG_CXL_FEATURES;
    struct cxl_features_state *cxlfs;
#endif;
};

成員

dev

與此 CXL 狀態關聯的裝置

cxlmd

表示 dev 的 CXL.mem 功能的裝置

reg_map

元件和 ras 暫存器對映引數

regs

已解析的暫存器塊

cxl_dvsec

PCIe 裝置 DVSEC 的偏移量

rcd

在 RCD 模式下執行 (CXL 3.0 9.11.8 連線到 RCH 的 CXL 裝置)

media_ready

指示裝置介質是否可用

dpa_res

裝置的整體 DPA 資源樹

part

DPA 分割槽陣列

nr_partitions

DPA 分割槽數

serial

PCIe 裝置序列號

type

通用記憶體類裝置或供應商特定記憶體裝置

cxl_mbox

CXL 郵箱上下文

cxlfs

CXL 功能上下文

描述

cxl_dev_state 表示 CXL 驅動程式/裝置狀態。它提供與郵箱命令的介面以及有關裝置的一些快取資料。目前僅表示記憶體裝置。

struct cxl_memdev_state¶

通用 Type-3 記憶體裝置類驅動程式資料

定義:

struct cxl_memdev_state {
    struct cxl_dev_state cxlds;
    size_t lsa_size;
    char firmware_version[0x10];
    u64 total_bytes;
    u64 volatile_only_bytes;
    u64 persistent_only_bytes;
    u64 partition_align_bytes;
    u64 active_volatile_bytes;
    u64 active_persistent_bytes;
    struct cxl_event_state event;
    struct cxl_poison_state poison;
    struct cxl_security_state security;
    struct cxl_fw_state fw;
    struct notifier_block mce_notifier;
};

成員

cxlds

跨 Type-2 和 Type-3 裝置的核心驅動程式狀態

lsa_size

標籤儲存區域的大小 (CXL 2.0 8.2.9.5.1.1 識別記憶體裝置)

firmware_version

記憶體裝置的韌體版本。

total_bytes

所有可能容量的總和

volatile_only_bytes

硬易失性容量

persistent_only_bytes

硬永續性容量

partition_align_bytes

可分割槽容量的對齊大小

active_volatile_bytes

硬 + 軟易失性容量的總和

active_persistent_bytes

硬 + 軟永續性容量的總和

event

事件日誌驅動程式狀態

poison

中毒驅動程式狀態資訊

security

安全驅動程式狀態資訊

fw

韌體上傳/啟用狀態

mce_notifier

MCE 通知程式

描述

CXL 8.1.12.1 PCI 標頭 - 類程式碼暫存器記憶體裝置定義了通用記憶體裝置功能,例如郵箱的存在以及與之相關的功能,例如識別記憶體裝置和獲取分割槽資訊。有關容量引數的詳細資訊,請參見 CXL 3.0 8.2.9.8.2 容量配置和標籤儲存。

struct cxl_mem_command¶

記憶體裝置命令的驅動程式表示

定義:

struct cxl_mem_command {
    struct cxl_command_info info;
    enum cxl_opcode opcode;
    u32 flags;
#define CXL_CMD_FLAG_FORCE_ENABLE BIT(0);
};

成員

info

UAPI 中存在的命令資訊

opcode

用於郵箱協議的實際位

flags

影響驅動程式行為的一組標誌。

  • CXL_CMD_FLAG_FORCE_ENABLE:在發生錯誤的情況下,無論硬體可能已通告什麼,驅動程式都將啟用帶有此標誌的命令。

描述

cxl_mem_command 是驅動程式內部表示驅動程式支援的命令。某些命令可能不受硬體支援。驅動程式將使用 info 來驗證使用者傳入的欄位,然後將 opcode 提交給硬體。

參見 struct cxl_command_info。

struct cxl_hdm¶

HDM 解碼器暫存器和快取/解碼功能

定義:

struct cxl_hdm {
    struct cxl_component_regs regs;
    unsigned int decoder_count;
    unsigned int target_count;
    unsigned int interleave_mask;
    unsigned long iw_cap_mask;
    struct cxl_port *port;
};

成員

regs

對映的暫存器,參見 devm_cxl_setup_hdm()

decoder_count

此埠的解碼器數量

target_count

對於交換機解碼器,最大下游埠目標數

interleave_mask

交織粒度功能,參見 check_interleave_cap()

iw_cap_mask

支援的交織方式的位掩碼,參見 check_interleave_cap()

port

對映的 cxl_port,參見 devm_cxl_setup_hdm()

void set_exclusive_cxl_commands(struct cxl_memdev_state *mds, unsigned long *cmds)¶

原子地停用使用者 cxl 命令

引數

struct cxl_memdev_state *mds

要操作的裝置狀態

unsigned long *cmds

要標記為獨佔的命令的點陣圖

描述

以寫入模式獲取 cxl_memdev_rwsem 以重新整理飛行中的 ioctl 路徑呼叫,然後停用未來執行在 cmds 中設定了命令 ID 的命令。

void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds, unsigned long *cmds)¶

原子地啟用使用者 cxl 命令

引數

struct cxl_memdev_state *mds

要修改的裝置狀態

unsigned long *cmds

要標記為對使用者空間可用的命令的點陣圖

int cxl_mem_get_fw_info(struct cxl_memdev_state *mds)¶

獲取韌體資訊

引數

struct cxl_memdev_state *mds

操作的裝置資料

描述

檢索指定裝置的韌體資訊。

參見 CXL-3.0 8.2.9.3.1 獲取韌體資訊

返回

如果沒有錯誤,則返回 0;否則返回郵箱命令的結果。

int cxl_mem_activate_fw(struct cxl_memdev_state *mds, int slot)¶

啟用韌體

引數

struct cxl_memdev_state *mds

操作的裝置資料

int slot

要啟用的插槽號

描述

啟用指定裝置中給定插槽中的韌體。

參見 CXL-3.0 8.2.9.3.3 啟用韌體

返回

如果沒有錯誤,則返回 0;否則返回郵箱命令的結果。

int cxl_mem_abort_fw_xfer(struct cxl_memdev_state *mds)¶

中止正在進行的韌體傳輸

引數

struct cxl_memdev_state *mds

操作的裝置資料

描述

中止指定裝置的正在進行的韌體傳輸。

參見 CXL-3.0 8.2.9.3.2 傳輸韌體

返回

如果沒有錯誤,則返回 0;否則返回郵箱命令的結果。

CXL 埠¶

埠驅動程式透過 PCI 列舉 dport,並透過代理註冊埠時傳入的 component_reg_phys 值掃描 HDM(主機管理裝置記憶體)解碼器資源。CXL 根埠(由平臺韌體描述)的所有後代埠都在此驅動程式上下文中進行管理。每個驅動程式例項負責拆除直接後代埠的驅動程式上下文。此鎖定的驗證由 CONFIG_PROVE_CXL_LOCKING 完成。

此驅動程式提供的主要服務是向其他驅動程式提供 API 以利用解碼器,並透過繫結狀態向用戶空間指示整個 PCIe 拓撲中 CXL.mem 協議的連線。

CXL Core¶

CXL 核心物件(如埠、解碼器和區域)在子系統驅動程式 cxl_acpi、cxl_pci 和核心驅動程式(埠驅動程式、區域驅動程式、nvdimm 物件驅動程式等)之間共享。

struct cxl_register_map¶

DVSEC 收集的暫存器塊對映引數

定義:

struct cxl_register_map {
    struct device *host;
    void __iomem *base;
    resource_size_t resource;
    resource_size_t max_size;
    u8 reg_type;
    union {
        struct cxl_component_reg_map component_map;
        struct cxl_device_reg_map device_map;
        struct cxl_pmu_reg_map pmu_map;
    };
};

成員

host

用於 devm 操作和日誌記錄的裝置

base

暫存器塊的虛擬基地址 - BAR + block_offset

resource

暫存器塊的物理資源基地址

max_size

執行暫存器搜尋的最大對映大小

reg_type

參見 enum cxl_regloc_type

{unnamed_union}

anonymous

component_map

元件暫存器的 cxl_reg_map

device_map

裝置暫存器的 cxl_reg_maps

pmu_map

CXL 效能監視單元的 cxl_reg_maps

struct cxl_decoder¶

通用 CXL HDM 解碼器屬性

定義:

struct cxl_decoder {
    struct device dev;
    int id;
    struct range hpa_range;
    int interleave_ways;
    int interleave_granularity;
    enum cxl_decoder_type target_type;
    struct cxl_region *region;
    unsigned long flags;
    int (*commit)(struct cxl_decoder *cxld);
    void (*reset)(struct cxl_decoder *cxld);
};

成員

dev

此解碼器的裝置

id

核心裝置名稱 ID

hpa_range

此解碼器對映的主機物理地址範圍

interleave_ways

此解碼中的 cxl_dports 數量

interleave_granularity

每個 dport 的資料步幅

target_type

加速器與擴充套件器(type2 與 type3)選擇器

region

當前為此解碼器分配的區域

flags

記憶體型別功能和鎖定

commit

特定於裝置/解碼器型別的回撥,用於將設定提交到硬體

reset

特定於裝置/解碼器型別的回撥,用於重置硬體設定

struct cxl_endpoint_decoder¶

端點/ SPA 到 DPA 解碼器

定義:

struct cxl_endpoint_decoder {
    struct cxl_decoder cxld;
    struct resource *dpa_res;
    resource_size_t skip;
    enum cxl_decoder_state state;
    int part;
    int pos;
};

成員

cxld

基本 cxl_decoder_object

dpa_res

此解碼器主動宣告的 DPA 跨度

skip

dpa_res 中的偏移量,其中對映 cxld.hpa_range

state

autodiscovery 狀態

part

此解碼器對映的分割槽索引

pos

cxld.region 中的交織位置

struct cxl_switch_decoder¶

交換機特定的 CXL HDM 解碼器

定義:

struct cxl_switch_decoder {
    struct cxl_decoder cxld;
    int nr_targets;
    struct cxl_dport *target[];
};

成員

cxld

基本 cxl_decoder 物件

nr_targets

target 中的元素數量

target

當前解碼器配置中的活動有序目標列表

描述

“switch”解碼器型別表示 cxl_port 的解碼器例項,這些例項將 CXL 記憶體解碼拓撲的根路由到端點。它們有兩種型別:根級解碼器,由平臺韌體靜態定義;以及中間級解碼器,其中交織粒度、交織寬度和目標列表是可變的。

struct cxl_root_decoder¶

靜態平臺 CXL 地址解碼器

定義:

struct cxl_root_decoder {
    struct resource *res;
    atomic_t region_id;
    cxl_hpa_to_spa_fn hpa_to_spa;
    void *platform_data;
    struct mutex range_lock;
    int qos_class;
    struct cxl_switch_decoder cxlsd;
};

成員

res

區域分配的主機/父資源

region_id

下一個區域配置事件的區域 ID

hpa_to_spa

將 CXL 主機物理地址轉換為平臺系統物理地址

platform_data

特定於平臺的配置資料

range_lock

按地址範圍同步區域自動發現

qos_class

QoS 效能類 Cookie

cxlsd

基本 cxl 交換機解碼器

struct cxl_region_params¶

區域設定

定義:

struct cxl_region_params {
    enum cxl_config_state state;
    uuid_t uuid;
    int interleave_ways;
    int interleave_granularity;
    struct resource *res;
    struct cxl_endpoint_decoder *targets[CXL_DECODER_MAX_INTERLEAVE];
    int nr_targets;
    resource_size_t cache_size;
};

成員

state

允許驅動程式鎖定進一步的引數更改

uuid

永續性區域的唯一 ID

interleave_ways

區域中的端點數量

interleave_granularity

每個端點對條帶的貢獻容量

res

為此區域分配的 iomem 容量

targets

當前解碼器配置中的活動有序目標

nr_targets

目標數量

cache_size

如果存在,則為擴充套件線性快取大小,否則為零。

描述

狀態轉換由 cxl_region_rwsem 保護

struct cxl_region¶

CXL 區域

定義:

struct cxl_region {
    struct device dev;
    int id;
    enum cxl_partition_mode mode;
    enum cxl_decoder_type type;
    struct cxl_nvdimm_bridge *cxl_nvb;
    struct cxl_pmem_region *cxlr_pmem;
    unsigned long flags;
    struct cxl_region_params params;
    struct access_coordinate coord[ACCESS_COORDINATE_MAX];
    struct notifier_block memory_notifier;
    struct notifier_block adist_notifier;
};

成員

dev

此區域的裝置

id

此區域的 ID。ID 在所有區域中都是全域性唯一的

mode

對映容量的操作模式

type

端點解碼器目標型別

cxl_nvb

用於協調 cxlr_pmem 設定/關閉的 nvdimm 橋

cxlr_pmem

(對於 pmem 區域)nvdimm 橋的快取副本

flags

區域狀態標誌

params

區域的活動 + 配置引數

coord

區域的 QoS 訪問座標

memory_notifier

用於將訪問座標設定為節點的通知程式

adist_notifier

用於計算節點抽象距離的通知程式

struct cxl_port¶

上游埠裝置和下游埠裝置的邏輯集合,用於構建 CXL 記憶體解碼層次結構。

定義:

struct cxl_port {
    struct device dev;
    struct device *uport_dev;
    struct device *host_bridge;
    int id;
    struct xarray dports;
    struct xarray endpoints;
    struct xarray regions;
    struct cxl_dport *parent_dport;
    struct ida decoder_ida;
    struct cxl_register_map reg_map;
    int nr_dports;
    int hdm_end;
    int commit_end;
    bool dead;
    unsigned int depth;
    struct cxl_cdat {
        void *table;
        size_t length;
    } cdat;
    bool cdat_available;
    long pci_latency;
};

成員

dev

此埠的裝置

uport_dev

實現上游埠功能的 PCI 或平臺裝置

host_bridge

此埠的平臺附加點的快捷方式

id

埠裝置名稱的 ID

dports

解碼器引用的 cxl_dport 例項

endpoints

cxl_ep 例項,是此埠後代的端點

regions

cxl_region_ref 例項,由此埠對映的區域

parent_dport

指向父埠中的該埠的 dport

decoder_ida

解碼器 ID 的分配器

reg_map

元件和 ras 暫存器對映引數

nr_dports

dports 中的條目數

hdm_end

跟蹤最後分配的 HDM 解碼器例項以進行分配排序

commit_end

跟蹤最高提交解碼器的遊標以進行提交排序

dead

已移除最後一個 ep,強制埠重新建立

depth

此埠相對於根埠的深度。深度 0 為根埠。

cdat

快取的 CDAT 資料

cdat_available

sysfs 中是否應提供 CDAT 屬性

pci_latency

上游延遲(皮秒)

struct cxl_root¶

根 cxl_port 項的邏輯集合

定義:

struct cxl_root {
    struct cxl_port port;
    const struct cxl_root_ops *ops;
};

成員

port

cxl_port 成員

ops

cxl 根操作

struct cxl_dport¶

CXL 下游埠

定義:

struct cxl_dport {
    struct device *dport_dev;
    struct cxl_register_map reg_map;
    int port_id;
    struct cxl_rcrb_info rcrb;
    bool rch;
    struct cxl_port *port;
    struct cxl_regs regs;
    struct access_coordinate coord[ACCESS_COORDINATE_MAX];
    long link_latency;
    int gpf_dvsec;
};

成員

dport_dev

表示下游鏈路的 PCI 橋或韌體裝置

reg_map

元件和 ras 暫存器對映引數

port_id

解碼器目標列表中 dport 的唯一硬體識別符號

rcrb

有關根複合體暫存器塊佈局的資料

rch

指示此 dport 是在 RCH 模式還是 VH 模式下列舉的

port

對包含此下游埠的 cxl_port 的引用

regs

已解析的 Dport 暫存器塊

coord

訪問座標(頻寬和延遲效能屬性)

link_latency

計算的 PCIe 下游延遲

gpf_dvsec

快取的 GPF 埠 DVSEC

struct cxl_ep¶

跟蹤端點對埠的興趣

定義:

struct cxl_ep {
    struct device *ep;
    struct cxl_dport *dport;
    struct cxl_port *next;
};

成員

ep

託管通用 CXL 端點(擴充套件器或加速器)的裝置

dport

哪個 dport 在 port 上路由到此端點

next

跨連線到 dport 的鏈路的 cxl 交換機埠,如果連線到端點則為 NULL

struct cxl_region_ref¶

跟蹤區域對埠的興趣

定義:

struct cxl_region_ref {
    struct cxl_port *port;
    struct cxl_decoder *decoder;
    struct cxl_region *region;
    struct xarray endpoints;
    int nr_targets_set;
    int nr_eps;
    int nr_targets;
};

成員

port

拓撲中安裝此參考的點

decoder

為 port 中的 region 分配的解碼器

region

此參考的區域

endpoints

位於 port 下方的區域成員的 cxl_ep 參考

nr_targets_set

跟蹤設定期間已程式設計的目標數

nr_eps

port 下方的端點數

nr_targets

到達 nr_eps 所需的不同目標數

struct cxl_endpoint_dvsec_info¶

快取的 DVSEC 資訊

定義:

struct cxl_endpoint_dvsec_info {
    bool mem_enabled;
    int ranges;
    struct cxl_port *port;
    struct range dvsec_range[2];
};

成員

mem_enabled

初始化時 DVSEC 中 mem_enabled 的快取值

ranges

此裝置使用的活動 HDM 範圍的數量。

port

與此資訊例項關聯的端點埠

dvsec_range

DVSEC 中範圍的快取屬性,PCIE_DEVICE

int add_cxl_resources(struct resource *cxl_res)¶

在 iomem_resource 中反映 CXL 固定記憶體視窗

引數

struct resource *cxl_res

一個獨立的資源樹,其中每個 CXL 視窗都是同級視窗

描述

遍歷 cxl_res 中的每個 CXL 視窗,並將其新增到 iomem_resource,可能會擴充套件其邊界以確保任何衝突的資源都成為子資源。如果視窗被擴充套件,則它可能與另一個視窗條目衝突,並需要截斷或修剪視窗。考慮這種情況

|-- "CXL Window 0" --||----- "CXL Window 1" -----|
|--------------- "System RAM" -------------|

...其中平臺韌體已在 2 個視窗中建立為系統 RAM 資源,但已將視窗 1 的某些部分留用於動態 CXL 區域配置。在這種情況下,“視窗 0”將跨越整個“系統 RAM”跨度,而“CXL 視窗 1”將被截斷到該“系統 RAM”資源末尾之後的剩餘尾部。

Compute Express Link Host Managed Device Memory(主機託管裝置記憶體),從 CXL 2.0 規範開始,由每個 CXL 埠和每個 CXL 端點的一系列 HDM 解碼器暫存器例項管理。定義用於列舉這些暫存器和功能的常用助手。

struct cxl_hdm *devm_cxl_setup_hdm(struct cxl_port *port, struct cxl_endpoint_dvsec_info *info)¶

對映 HDM 解碼器元件暫存器

引數

struct cxl_port *port

要對映的 cxl_port

struct cxl_endpoint_dvsec_info *info

快取的 DVSEC 範圍暫存器資訊

int request_skip(struct cxl_dev_state *cxlds, struct cxl_endpoint_decoder *cxled, const resource_size_t skip_base, const resource_size_t skip_len)¶

在 cxlds->dpa_res 資源樹中跟蹤 DPA“跳過”

引數

struct cxl_dev_state *cxlds

CXL.mem 裝置上下文,它是 cxled 的父級

struct cxl_endpoint_decoder *cxled

端點解碼器建立跳過較低 DPA 的新分配

const resource_size_t skip_base

DPA < 新 DPA 分配的開始(DPAnew)

const resource_size_t skip_len

skip_base + skip_len == DPAnew

描述

相對於多個分割槽中的可用容量,DPA“跳過”源自亂序 DPA 分配事件。這是一個浪費的事件,因為可用的 DPA 被丟棄,但如果部署有例如雙 RAM+PMEM 裝置,想要使用 PMEM,並且有未分配的 RAM DPA,則必須犧牲空閒 RAM DPA 才能開始分配 PMEM。有關更多詳細資訊,請參閱 CXL 3.1 8.2.4.19.13 “解碼器保護”中的第三個“實現說明”。

“跳過”始終覆蓋先前分割槽中最後分配的 DPA 到當前分割槽要分配的開始。分配永遠不會在分割槽的中間開始,並且分配始終以相反的順序解除分配(請參閱 cxl_dpa_free(),或來自強制按順序分配的自然 devm 展開順序)。

如果保證 cxlds->nr_partitions <= 2,則“跳過”將始終包含在單個分割槽中。鑑於 cxlds->nr_partitions 可能 > 2,這會導致“跳過”可能跨越“partition[0] 的尾部容量,partition[1] 的全部,...,partition[N-1] 的全部”以支援從 partition[N] 進行分配的情況。反過來,這與 cxlds->dpa_res 中的分割槽“struct resource”邊界互動,從而需要按分區劃分“跳過”請求。也就是說,這是使用“struct resource”樹來檢測範圍衝突,同時也在 cxlds->dpa_res 中跟蹤分割槽邊界的怪癖。

int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm, struct cxl_endpoint_dvsec_info *info)¶

為每個 HDM 暫存器集新增解碼器物件

引數

struct cxl_hdm *cxlhdm

要使用 HDM 功能填充的結構

struct cxl_endpoint_dvsec_info *info

快取的 DVSEC 範圍暫存器資訊

void cxl_coordinates_combine(struct access_coordinate *out, struct access_coordinate *c1, struct access_coordinate *c2)¶

組合兩個輸入座標

引數

struct access_coordinate *out

c1 和 c2 的組合的輸出座標

struct access_coordinate *c1

輸入座標

struct access_coordinate *c2

輸入座標

int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr, struct cxl_endpoint_decoder *cxled, struct xarray *usp_xa, bool *gp_is_root)¶

在一個 xarray 中收集所有端點頻寬

引數

struct cxl_region *cxlr

用於頻寬計算的 CXL 區域

struct cxl_endpoint_decoder *cxled

要開始的端點解碼器

struct xarray *usp_xa

(輸出)收集所有頻寬座標的 xarray,按上游裝置索引,資料為“struct cxl_perf_ctx”。

bool *gp_is_root

(輸出)祖父母是否為 cxl 根的布林值。

返回

成功則為 0,或 -errno

描述

收集聚合的端點頻寬,並將頻寬儲存在 xarray 中,該 xarray 由交換機的上游裝置或 RP 裝置索引。每個端點都包含來自端點 CDAT 的 DSLBIS、端點上游鏈路頻寬以及來自交換機 CDAT 的 SSLBIS(用於交換機上游埠到與端點關聯的下游埠)的最小頻寬。如果裝置直接連線到 RP,則不涉及 SSLBIS。

struct xarray *cxl_switch_gather_bandwidth(struct cxl_region *cxlr, struct xarray *input_xa, bool *gp_is_root)¶

在一個 xarray 中收集交換機級別的所有頻寬

引數

struct cxl_region *cxlr

正在操作的區域

struct xarray *input_xa

由交換機的上游裝置索引的 xarray,資料為“struct cxl_perf_ctx”

bool *gp_is_root

(輸出)祖父母是否為 cxl 根的布林值。

返回

每個父交換機或根埠的 resulting cxl_perf_ctx 的 xarray

或 ERR_PTR(-errno)

描述

迭代 xarray。獲取下游計算頻寬、上游鏈路頻寬和上游交換機(如果存在)的 SSLBIS 的最小值。對交換機上游裝置或 RP 裝置下的結果頻寬求和。如果存在多個交換機,則可以對該函式進行多次迭代。

struct xarray *cxl_rp_gather_bandwidth(struct xarray *xa)¶

處理根埠級別的頻寬收集

引數

struct xarray *xa

儲存 cxl_perf_ctx 的 xarray,該 cxl_perf_ctx 具有每個根埠裝置下方計算的頻寬。

返回

儲存每個主機橋的 cxl_perf_ctx 的 xarray 或 ERR_PTR(-errno)

struct xarray *cxl_hb_gather_bandwidth(struct xarray *xa)¶

處理主機橋級別的頻寬收集

引數

struct xarray *xa

儲存 cxl_perf_ctx 的 xarray,該 cxl_perf_ctx 具有每個主機橋下方計算的頻寬。

返回

儲存每個 ACPI0017 裝置的 cxl_perf_ctx 的 xarray 或 ERR_PTR(-errno)

void cxl_region_update_bandwidth(struct cxl_region *cxlr, struct xarray *input_xa)¶

更新區域的頻寬訪問座標

引數

struct cxl_region *cxlr

正在操作的區域

struct xarray *input_xa

Xarray 儲存每個 ACPI0017 例項的具有計算頻寬的 cxl_perf_ctx

void cxl_region_shared_upstream_bandwidth_update(struct cxl_region *cxlr)¶

重新計算區域的頻寬

引數

struct cxl_region *cxlr

要重新計算的 cxl 區域

描述

該函式從下到上遍歷拓撲並計算頻寬。它從端點開始,在交換機(如果有)處進行處理,在根埠級別進行處理,在主機橋級別進行處理,最後在區域進行聚合。

CXL 核心提供一組可由 CXL 感知驅動程式使用的介面。這些介面允許建立、修改和銷燬區域、記憶體裝置、埠和解碼器。CXL 感知驅動程式必須透過這些介面向 CXL 核心註冊,以便能夠參與跨裝置交錯協調。CXL 核心還建立和維護與 nvdimm 子系統的橋樑。

CXL 核心引入 sysfs 層次結構來控制由核心例項化的裝置。

struct cxl_port *devm_cxl_add_port(struct device *host, struct device *uport_dev, resource_size_t component_reg_phys, struct cxl_dport *parent_dport)¶

在 CXL 記憶體解碼層次結構中註冊 cxl_port

引數

struct device *host

devm 操作的主機裝置

struct device *uport_dev

實現此上游埠的“物理”裝置

resource_size_t component_reg_phys

(可選)用於可配置的 cxl_port 例項

struct cxl_dport *parent_dport

CXL 記憶體解碼層次結構中的下一跳

struct cxl_dport *devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev, int port_id, resource_size_t component_reg_phys)¶

將 VH 下游埠資料附加到 cxl_port

引數

struct cxl_port *port

引用此 dport 的 cxl_port

struct device *dport_dev

表示 dport 的韌體或 PCI 裝置

int port_id

解碼器目標列表中此 dport 的識別符號

resource_size_t component_reg_phys

CXL 元件暫存器的可選位置

描述

請注意,dports 會附加到埠主機(對於根埠)或埠本身(對於交換機埠)的 devm 釋出操作。

struct cxl_dport *devm_cxl_add_rch_dport(struct cxl_port *port, struct device *dport_dev, int port_id, resource_size_t rcrb)¶

將 RCH 下游埠資料附加到 cxl_port

引數

struct cxl_port *port

引用此 dport 的 cxl_port

struct device *dport_dev

表示 dport 的韌體或 PCI 裝置

int port_id

解碼器目標列表中此 dport 的識別符號

resource_size_t rcrb

根複合體暫存器塊的強制位置

描述

請參閱 CXL 3.0 9.11.8 連線到 RCH 的 CXL 裝置

int cxl_add_ep(struct cxl_dport *dport, struct device *ep_dev)¶

註冊端點對埠的興趣

引數

struct cxl_dport *dport

路由到 ep_dev 的 dport

struct device *ep_dev

表示端點的裝置

描述

中間 CXL 埠根據端點的到達進行掃描。當這些端點離開時,一旦所有關心該埠的端點都已移除,就可以銷燬該埠。

int cxl_decoder_init(struct cxl_port *port, struct cxl_decoder *cxld)¶

常見的解碼器設定/初始化

引數

struct cxl_port *port

此解碼器的擁有埠

struct cxl_decoder *cxld

要初始化的常見解碼器屬性

描述

一個埠可能包含一個或多個解碼器。這些解碼器中的每一個都啟用了 CXL.mem 利用的一些地址空間。預計解碼器在透過 cxl_decoder_add() 註冊之前由呼叫方配置

struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port, unsigned int nr_targets)¶

分配根級別解碼器

引數

struct cxl_port *port

此解碼器的擁有 CXL 根

unsigned int nr_targets

下游目標的靜態數量

返回

要透過 cxl_decoder_add() 註冊的新 cxl 解碼器。“CXL 根”解碼器是一種將 CXL 資源從頂層/靜態平臺韌體描述解碼到 CXL 標準解碼拓撲中的解碼器。

struct cxl_switch_decoder *cxl_switch_decoder_alloc(struct cxl_port *port, unsigned int nr_targets)¶

分配交換機級別解碼器

引數

struct cxl_port *port

此解碼器的擁有 CXL 交換機埠

unsigned int nr_targets

可動態定址的下游目標的最大數量

返回

要透過 cxl_decoder_add() 註冊的新 cxl 解碼器。“交換機”解碼器是可以由 PCIe 拓撲和 HDM 解碼器功能列舉的任何解碼器。這包括位於交換機上游埠/交換機下游埠和主機橋/根埠之間的解碼器。

struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port)¶

分配端點解碼器

引數

struct cxl_port *port

此解碼器的擁有埠

返回

要透過 cxl_decoder_add() 註冊的新 cxl 解碼器

int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map)¶

新增具有目標的解碼器

引數

struct cxl_decoder *cxld

由 cxl__decoder_alloc() 分配的 cxl 解碼器

int *target_map

此解碼器可以將記憶體流量定向到的下游埠的列表。這些數字應與 PCIe 鏈路功能結構中的埠號相對應。

描述

某些型別的解碼器可能沒有任何目標。這方面的主要示例是端點裝置。一個更令人尷尬的例子是主機橋,其根埠被熱新增(技術上可能,儘管不太可能)。

這是 cxl_decoder_add() 的鎖定變體。

上下文

程序上下文。期望擁有 cxld 的埠的裝置鎖被持有。

返回

如果解碼器未正確配置,則為負錯誤程式碼;否則

返回 0。

int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map)¶

新增具有目標的解碼器

引數

struct cxl_decoder *cxld

由 cxl__decoder_alloc() 分配的 cxl 解碼器

int *target_map

此解碼器可以將記憶體流量定向到的下游埠的列表。這些數字應與 PCIe 鏈路功能結構中的埠號相對應。

描述

這是 cxl_decoder_add_locked() 的未鎖定變體。請參閱 cxl_decoder_add_locked()。

上下文

處理上下文。獲取和釋放擁有 cxld 的埠的裝置鎖。

int __cxl_driver_register(struct cxl_driver *cxl_drv, struct module *owner, const char *modname)¶

為 cxl 匯流排註冊驅動程式

引數

struct cxl_driver *cxl_drv

要附加的 cxl 驅動程式結構

struct module *owner

擁有模組/驅動程式

const char *modname

父驅動程式的 KBUILD_MODNAME

int cxl_endpoint_get_perf_coordinates(struct cxl_port *port, struct access_coordinate *coord)¶

檢索儲存在 CXL 路徑的 dport 中的效能數字

引數

struct cxl_port *port

端點 cxl_port

struct access_coordinate *coord

輸出效能資料

返回

失敗時返回 errno,成功時返回 0。

Compute Express Link 協議分層在 PCIe 之上。CXL 核心為 CXL 互動提供了一組助手函式,這些互動透過 PCIe 發生。

int devm_cxl_port_enumerate_dports(struct cxl_port *port)¶

列舉上游埠的下游埠

引數

struct cxl_port *port

cxl_port,其 ->uport_dev 是要列舉的 dport 的上游

描述

返回列舉的 dport 的正數或負錯誤程式碼。

int cxl_hdm_decode_init(struct cxl_dev_state *cxlds, struct cxl_hdm *cxlhdm, struct cxl_endpoint_dvsec_info *info)¶

為端點設定 HDM 解碼

引數

struct cxl_dev_state *cxlds

裝置狀態

struct cxl_hdm *cxlhdm

對映的 HDM 解碼器功能

struct cxl_endpoint_dvsec_info *info

快取的 DVSEC 範圍暫存器資訊

描述

嘗試啟用端點的 HDM 解碼器功能

void read_cdat_data(struct cxl_port *port)¶

讀取此埠上的 CDAT 資料

引數

struct cxl_port *port

從中讀取資料的埠

描述

此呼叫將休眠等待來自 DOE 郵箱的響應。

void cxl_dport_init_ras_reporting(struct cxl_dport *dport, struct device *host)¶

在此 dport 上設定 CXL RAS 報告

引數

struct cxl_dport *dport

需要初始化的 cxl_dport

struct device *host

devm 操作的主機裝置

long cxl_pci_get_latency(struct pci_dev *pdev)¶

計算 PCIe 鏈路的鏈路延遲

引數

struct pci_dev *pdev

PCI 裝置

返回

計算出的延遲或 0(無延遲)

描述

CXL 記憶體裝置 SW 指南 v1.0 2.11.4 鏈路延遲計算 鏈路延遲 = 鏈路傳播延遲 + Flit 延遲 + Retimer 延遲 LinkProgationLatency 可以忽略不計,因此將使用 0 RetimerLatency 假定可以忽略不計,因此將使用 0 FlitLatency = FlitSize / LinkBandwidth FlitSize 由規範定義。CXL rev3.0 4.2.1。 68B flit 用於高達 32GT/s。 >32GT/s,使用 256B flit 大小。 FlitLatency 轉換為皮秒。

核心 CXL PMEM 基礎設施支援永續性記憶體配置,並充當與 LIBNVDIMM 子系統的橋樑。如果平臺韌體至少通告一個支援永續性記憶體的 CXL 視窗,則會在 CXL 裝置拓撲的根新增一個 CXL“橋”裝置。該根級別橋對應於 LIBNVDIMM “匯流排”裝置。然後,對於 CXL 裝置拓撲中的每個 cxl_memdev,都會新增一個橋裝置來託管 LIBNVDIMM dimm 物件。當這些橋註冊時,原生 LIBNVDIMM uapi 會轉換為 CXL 操作,例如,名稱空間標籤訪問命令。

struct cxl_nvdimm_bridge *cxl_find_nvdimm_bridge(struct cxl_port *port)¶

查詢相對於埠的橋裝置

引數

struct cxl_port *port

與 nvdimm-bridge 關聯的 root-cxl-port 的任何後代埠

struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, struct cxl_port *port)¶

新增 LIBNVDIMM 拓撲的根

引數

struct device *host

平臺韌體根裝置

struct cxl_port *port

CXL 拓撲根目錄的 CXL 埠

返回

可以託管 cxl_nvdimm 物件的橋裝置

int devm_cxl_add_nvdimm(struct cxl_port *parent_port, struct cxl_memdev *cxlmd)¶

在 cxl_memdev 和 nvdimm 之間新增橋樑

引數

struct cxl_port *parent_port

(要新增的)cxlmd 端點埠的父埠

struct cxl_memdev *cxlmd

將執行 LIBNVDIMM 操作的 cxl_memdev 例項

返回

成功時返回 0,失敗時返回負錯誤程式碼。

CXL 裝置功能由 PCI DVSEC(指定供應商特定)和/或平臺韌體提供的描述符列舉。 它們可以定義為一組,例如 CXL 第 8.1.12.2 節記憶體裝置 PCIe 功能和擴充套件功能授權的裝置和元件暫存器,或者它們可以是附加到橋接和端點裝置的單個功能。

提供用於列舉和對映這些離散功能的通用基礎設施。

void cxl_probe_component_regs(struct device *dev, void __iomem *base, struct cxl_component_reg_map *map)¶

檢測 CXL 元件暫存器塊

引數

struct device *dev

base 對映的主機裝置

void __iomem *base

包含 HDM 解碼器功能標頭的對映

struct cxl_component_reg_map *map

描述找到的暫存器塊資訊的對映物件

描述

請參閱 CXL 2.0 8.2.4 元件暫存器佈局和定義 請參閱 CXL 2.0 8.2.5.5 CXL 裝置暫存器介面

探測元件暫存器資訊並在對映物件中返回它。

void cxl_probe_device_regs(struct device *dev, void __iomem *base, struct cxl_device_reg_map *map)¶

檢測 CXL 裝置暫存器塊

引數

struct device *dev

base 對映的主機裝置

void __iomem *base

CXL 2.0 8.2.8 CXL 裝置暫存器介面的對映

struct cxl_device_reg_map *map

描述找到的暫存器塊資訊的對映物件

描述

探測裝置暫存器資訊並在對映物件中返回它。

int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type, struct cxl_register_map *map, unsigned int index)¶

按型別/索引查詢暫存器塊

引數

struct pci_dev *pdev

要列舉的 CXL PCI 裝置。

enum cxl_regloc_type type

暫存器塊指示器 id

struct cxl_register_map *map

列舉輸出,錯誤時被破壞

unsigned int index

暫存器定位器 DVSEC 中找到的所需 regblock 的特定例項的索引。

返回

如果暫存器塊已列舉,則為 0;否則為負錯誤程式碼

描述

CXL DVSEC 可能會指向一個或多個暫存器塊,按 type 和 index 搜尋它們。

int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type, struct cxl_register_map *map)¶

按型別查詢暫存器塊

引數

struct pci_dev *pdev

要列舉的 CXL PCI 裝置。

enum cxl_regloc_type type

暫存器塊指示器 id

struct cxl_register_map *map

列舉輸出,錯誤時被破壞

返回

如果暫存器塊已列舉,則為 0;否則為負錯誤程式碼

描述

CXL DVSEC 可能會指向一個或多個暫存器塊,按 type 搜尋它們。

int cxl_count_regblock(struct pci_dev *pdev, enum cxl_regloc_type type)¶

計算給定 regblock 型別的例項。

引數

struct pci_dev *pdev

要列舉的 CXL PCI 裝置。

enum cxl_regloc_type type

暫存器塊指示器 id

描述

某些 regblock 可能會重複。 計算有多少個例項。

返回

匹配 regblock 的非負計數,否則為負錯誤程式碼。

CXL 2.0 Type-3 記憶體裝置郵箱的核心實現。 該實現由 cxl_pci 驅動程式用於初始化裝置並實現 cxl_mem.h IOCTL UAPI。 它還實現了用於 LIBNVDIMM 的 cxl_pmem_ctl() 傳輸的後端。

int cxl_internal_send_cmd(struct cxl_mailbox *cxl_mbox, struct cxl_mbox_cmd *mbox_cmd)¶

核心內部介面,用於傳送郵箱命令

引數

struct cxl_mailbox *cxl_mbox

CXL 郵箱上下文

struct cxl_mbox_cmd *mbox_cmd

要執行的已初始化命令

上下文

任何上下文。

返回

  • %>=0 - 在 out 中返回的位元組數。

  • -E2BIG - 有效負載對於硬體來說太大。

  • -EBUSY - 無法獲得獨佔郵箱訪問許可權。

  • -EFAULT - 發生硬體錯誤。

  • -ENXIO - 命令已完成,但裝置報告了錯誤。

  • -EIO - 意外的輸出大小。

描述

郵箱命令可能會成功執行,但裝置本身報告了錯誤。 雖然這種區別對於來自使用者空間的命令可能很有用,但核心只能在兩者都成功時使用結果。

bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in)¶

檢查 in_payload 的內容。

引數

u16 opcode

郵箱命令操作碼。

void *payload_in

指向從使用者空間傳入的輸入有效負載的指標。

返回

  • true - payload_in 通過了 opcode 的檢查。

  • false - payload_in 包含無效或不支援的值。

描述

驅動程式可能會在將來自使用者空間的郵箱命令傳送到裝置之前檢查有效負載內容。 其目的是拒絕具有已知不安全的輸入有效負載的命令。 此檢查並非旨在取代使用者對郵箱命令引數的仔細選擇,也不保證使用者命令會成功或適當。

特定檢查由操作碼確定。

int cxl_validate_cmd_from_user(struct cxl_mbox_cmd *mbox_cmd, struct cxl_mailbox *cxl_mbox, const struct cxl_send_command *send_cmd)¶

檢查 CXL_MEM_SEND_COMMAND 的欄位。

引數

struct cxl_mbox_cmd *mbox_cmd

已清理和填充的 struct cxl_mbox_cmd。

struct cxl_mailbox *cxl_mbox

CXL 郵箱上下文

const struct cxl_send_command *send_cmd

從使用者空間複製的 struct cxl_send_command。

返回

  • 0 - out_cmd 準備好傳送。

  • -ENOTTY - 指定了無效命令。

  • -EINVAL - 使用了保留欄位或無效值。

  • -ENOMEM - 輸入或輸出緩衝區大小不正確。

  • -EPERM - 嘗試使用受保護的命令。

  • -EBUSY - 核心已宣告對此操作碼的獨佔訪問許可權

描述

此命令的結果是 mbox_cmd 中完全驗證的命令,可以安全地傳送到硬體。

int handle_mailbox_cmd_from_user(struct cxl_mailbox *cxl_mbox, struct cxl_mbox_cmd *mbox_cmd, u64 out_payload, s32 *size_out, u32 *retval)¶

為使用者空間分派郵箱命令。

引數

struct cxl_mailbox *cxl_mbox

操作的郵箱上下文。

struct cxl_mbox_cmd *mbox_cmd

經過驗證的郵箱命令。

u64 out_payload

指向使用者空間的輸出有效負載的指標。

s32 *size_out

(輸入)要複製出的最大有效負載大小。(輸出)硬體生成的有效負載大小。

u32 *retval

來自操作的硬體生成的返回程式碼。

返回

  • 0 - 郵箱事務成功。 這意味著郵箱

    協議已成功完成,而不是操作本身成功。

  • -ENOMEM - 無法分配反彈緩衝區。

  • -EFAULT - copy_to/from_user 發生了某些情況。

  • -EINTR - 郵箱獲取中斷。

  • -EXXX - 事務級別故障。

描述

代表使用者空間請求分派郵箱命令。 輸出有效負載已複製到使用者空間。

請參閱 cxl_send_cmd()。

void cxl_walk_cel(struct cxl_memdev_state *mds, size_t size, u8 *cel)¶

遍歷命令效果日誌。

引數

struct cxl_memdev_state *mds

操作的驅動程式資料

size_t size

命令效果日誌的長度。

u8 *cel

CEL

描述

迭代 CEL 中的每個條目,並確定驅動程式是否支援該命令。 如果是,則該命令已為裝置啟用,並且可以在以後使用。

int cxl_enumerate_cmds(struct cxl_memdev_state *mds)¶

列舉裝置的命令。

引數

struct cxl_memdev_state *mds

操作的驅動程式資料

描述

如果列舉成功完成,則返回 0。

CXL 裝置可選地支援某些命令。 此函式將確定硬體支援的命令集,並更新 mds 中的 enabled_cmds 點陣圖。

void cxl_mem_get_event_records(struct cxl_memdev_state *mds, u32 status)¶

從裝置獲取事件記錄

引數

struct cxl_memdev_state *mds

操作的驅動程式資料

u32 status

事件狀態暫存器值,用於標識哪些事件可用。

描述

檢索裝置上所有可用的事件記錄,將其報告為跟蹤事件,並清除它們。

請參閱 CXL rev 3.0 8.2.9.2.2 獲取事件記錄 請參閱 CXL rev 3.0 8.2.9.2.3 清除事件記錄

int cxl_mem_get_partition_info(struct cxl_memdev_state *mds)¶

獲取分割槽資訊

引數

struct cxl_memdev_state *mds

操作的驅動程式資料

描述

檢索指定裝置的當前分割槽資訊。 活動值是以位元組為單位的當前容量。 如果不為 0,“next”值是以位元組為單位的待定值,將在下次冷復位時生效。

請參閱 CXL 8.2.9.5.2.1 獲取分割槽資訊

返回

如果沒有錯誤,則返回 0;否則返回郵箱命令的結果。

int cxl_dev_state_identify(struct cxl_memdev_state *mds)¶

將 IDENTIFY 命令傳送到裝置。

引數

struct cxl_memdev_state *mds

操作的驅動程式資料

返回

如果 identify 已成功執行或介質未準備好,則返回 0。

描述

這會將 identify 命令分派到裝置,並在成功時填充要匯出到 sysfs 的結構。

int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd)¶

將清理命令傳送到裝置。

引數

struct cxl_memdev *cxlmd

操作的裝置

u16 cmd

特定的清理命令操作碼

返回

如果命令已成功執行,則返回 0,無論實際的安全操作是否在後臺完成,例如對於清理的情況。 錯誤返回值可能是郵箱命令的結果,如果不滿足安全要求或上下文無效,則為 -EINVAL;如果清理操作已經在進行中,則為 -EBUSY。

描述

請參閱 CXL 3.0 8.2.9.8.5.1 清理和 8.2.9.8.5.2 安全擦除。

CXL 功能:包括郵箱的 CXL 裝置支援允許列出、獲取和設定可選定義的功能的命令,例如記憶體備用或後封裝備用。 供應商可以為裝置定義自定義功能。

有關 API 詳細資訊,請參閱 devm_cxl_setup_features()。

CXL 區域¶

CXL 區域表示系統物理地址空間中對映的記憶體容量。 雖然 CXL 根解碼器標識潛在 CXL 記憶體範圍的邊界,但區域表示主機橋、交換機和拓撲中端點的 HDM 解碼器功能結構對映的活動容量。

區域配置具有排序約束。 UUID 可以隨時設定,但僅對永續性區域可見。 1. 交錯粒度 2. 交錯大小 3. 解碼器目標

struct cxl_decoder *cxl_port_pick_region_decoder(struct cxl_port *port, struct cxl_endpoint_decoder *cxled, struct cxl_region *cxlr)¶

為區域分配或查詢解碼器

引數

struct cxl_port *port

cxled 暗示的端點的祖先埠

struct cxl_endpoint_decoder *cxled

要由 port 對映或當前對映的端點解碼器

struct cxl_region *cxlr

要建立或驗證解碼 port 的區域

描述

在區域建立路徑中,cxl_port_pick_region_decoder() 是一個分配器,用於查詢空閒埠。 在區域組裝路徑中,它是呼叫平臺韌體選擇的解碼器以用於驗證目的。

結果記錄在 port 中的 'struct cxl_region_ref' 中。

int cxl_port_attach_region(struct cxl_port *port, struct cxl_region *cxlr, struct cxl_endpoint_decoder *cxled, int pos)¶

透過端點跟蹤區域對埠的興趣

引數

struct cxl_port *port

要新增新區域引用“struct cxl_region_ref”的埠

struct cxl_region *cxlr

要附加到 port 的區域

struct cxl_endpoint_decoder *cxled

用於建立或進一步固定區域引用的端點解碼器

int pos

cxled 在 cxlr 中的交錯位置

描述

附加事件是一個驗證 CXL 解碼設定約束和記錄程式設計 HDM 解碼器所需的元資料的機會,特別是解碼器目標列表。

步驟如下:

  • 驗證是否沒有其他具有更高 HPA 的區域已經與 port 關聯

  • 如果區域引用尚不存在,則建立一個

    • 此外,分配一個解碼器例項,該例項將在 port 上託管 cxlr

  • 透過端點固定區域引用

  • 說明需要多少 port 的目標列表條目來覆蓋所有新增的端點。

int cxl_calc_interleave_pos(struct cxl_endpoint_decoder *cxled)¶

計算區域中的端點位置

引數

struct cxl_endpoint_decoder *cxled

給定區域的端點解碼器成員

描述

端點位置是透過從端點到根解碼器的拓撲結構遍歷,並迭代應用此計算來計算的

position = position * parent_ways + parent_pos;

...其中 position 是從交換機和根解碼器目標列表推斷出來的。

返回

成功時 position >= 0

失敗時 -ENXIO

struct cxl_region *devm_cxl_add_region(struct cxl_root_decoder *cxlrd, int id, enum cxl_partition_mode mode, enum cxl_decoder_type type)¶

向解碼器新增區域

引數

struct cxl_root_decoder *cxlrd

根解碼器

int id

要建立的 memregion id,或失敗時 memregion_free()

enum cxl_partition_mode mode

此區域的端點解碼器的模式

enum cxl_decoder_type type

選擇這是擴充套件器還是加速器(type-2 或 type-3)

描述

這是區域初始化的第二步。區域存在於一個地址空間中,該地址空間由 cxlrd 對映。

返回

如果該區域已新增到 cxlrd,則為 0,否則返回負錯誤程式碼。該區域將被命名為“regionZ”,其中 Z 是唯一的區域編號。

int devm_cxl_add_pmem_region(struct cxl_region *cxlr)¶

新增 cxl_region 到 nd_region 的橋樑

引數

struct cxl_region *cxlr

此 pmem 區域橋裝置的上層 CXL 區域

返回

成功時返回 0,失敗時返回負錯誤程式碼。

外部介面¶

CXL IOCTL 介面¶

並非驅動程式支援的所有命令都可以在任何時候供使用者空間使用。使用者空間可以檢查 QUERY 命令的結果以確定即時命令集。或者,它可以發出命令並檢查是否失敗。

struct cxl_command_info¶

從查詢返回的命令資訊。

定義:

struct cxl_command_info {
    __u32 id;
    __u32 flags;
#define CXL_MEM_COMMAND_FLAG_MASK               GENMASK(1, 0);
#define CXL_MEM_COMMAND_FLAG_ENABLED            BIT(0);
#define CXL_MEM_COMMAND_FLAG_EXCLUSIVE          BIT(1);
    __u32 size_in;
    __u32 size_out;
};

成員

id

命令的 ID 號。

flags

指定命令列為的標誌。

CXL_MEM_COMMAND_FLAG_USER_ENABLED

給定的命令 ID 受驅動程式支援,並且受裝置上相關操作碼的支援。

CXL_MEM_COMMAND_FLAG_EXCLUSIVE

具有給定命令 ID 的請求將以 EBUSY 終止,因為核心主動擁有給定資源的管理。例如,當核心主動管理該空間時,無法寫入標籤儲存區域。

size_in

預期輸入大小,如果長度可變,則為 ~0。

size_out

預期輸出大小,如果長度可變,則為 ~0。

描述

表示驅動程式和硬體都支援的單個命令。這是作為查詢 ioctl 的陣列的一部分返回的。以下命令將採用可變長度的輸入並返回 0 位元組的輸出。

  • id = 10

  • flags = CXL_MEM_COMMAND_FLAG_ENABLED

  • size_in = ~0

  • size_out = 0

參見 struct cxl_mem_query_commands。

struct cxl_mem_query_commands¶

查詢支援的命令。

定義:

struct cxl_mem_query_commands {
    __u32 n_commands;
    __u32 rsvd;
    struct cxl_command_info __user commands[];
};

成員

n_commands

輸入/輸出引數。當 n_commands > 0 時,驅動程式將返回 min(num_support_commands, n_commands)。當 n_commands 為 0 時,驅動程式將返回支援的命令的總數。

rsvd

保留供將來使用。

commands

支援的命令的輸出陣列。此陣列必須由使用者空間分配,至少為 min(num_support_commands, n_commands)

描述

允許使用者空間查詢驅動程式和硬體都支援的可用命令。查詢中不會返回驅動程式或硬體不支援的命令。

例子

  • { .n_commands = 0 } // 獲取支援的命令數

  • { .n_commands = 15, .commands = buf } // 返回前 15 個(或更少)支援的命令

參見 struct cxl_command_info。

struct cxl_send_command¶

向記憶體裝置傳送命令。

定義:

struct cxl_send_command {
    __u32 id;
    __u32 flags;
    union {
        struct {
            __u16 opcode;
            __u16 rsvd;
        } raw;
        __u32 rsvd;
    };
    __u32 retval;
    struct {
        __u32 size;
        __u32 rsvd;
        __u64 payload;
    } in;
    struct {
        __u32 size;
        __u32 rsvd;
        __u64 payload;
    } out;
};

成員

id

要傳送到記憶體裝置的命令。這必須是查詢命令返回的命令之一。

flags

命令的標誌(輸入)。

{unnamed_union}

anonymous

raw

原始命令的特殊欄位

raw.opcode

使用 RAW 命令時傳遞給硬體的操作碼。

raw.rsvd

必須為零。

rsvd

必須為零。

retval

來自記憶體裝置的返回值(輸出)。

in

與輸入有效負載關聯的引數。

in.size

提供給裝置的有效負載的大小(輸入)。

in.rsvd

必須為零。

in.payload

指向有效負載輸入的記憶體的指標,有效負載是小端位元組序。

out

與輸出有效負載關聯的引數。

out.size

從裝置接收的有效負載的大小(輸入/輸出)。此欄位由使用者空間填寫,以告知驅動程式為輸出分配了多少空間。它由驅動程式填充,以使使用者空間知道實際的輸出有效負載有多大。

out.rsvd

必須為零。

out.payload

指向有效負載輸出的記憶體的指標,有效負載是小端位元組序。

描述

使用者空間向硬體傳送命令進行處理的機制。驅動程式將對命令大小進行基本驗證。在某些情況下,甚至可能會檢查有效負載。使用者空間需要為 size_out 分配足夠大的緩衝區,在某些情況下,size_out 的長度可能可變。

©The kernel development community. | Powered by Sphinx 5.3.0 & Alabaster 0.7.16 | Page source