InfiniBand 和远程 DMA (RDMA) 接口

简介和概述

待定

InfiniBand 核心接口

struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq, u8 nl_client, gfp_t gfp)

分配和初始化 netlink 消息请求

参数

__u32 nlmsg_seq

netlink 消息的序列号

u8 nl_client

netlink 客户端的索引

gfp_t gfp

指示应如何为请求分配内存

描述

如果成功,则返回新分配的 netlink 请求对象,否则返回 NULL

void iwpm_free_nlmsg_request(struct kref *kref)

释放 netlink 消息请求

参数

struct kref *kref

保存 netlink 消息请求的引用

struct iwpm_nlmsg_request *iwpm_find_nlmsg_request(__u32 echo_seq)

在请求列表中查找 netlink 消息请求

参数

__u32 echo_seq

要查找的 netlink 请求的序列号

描述

返回找到的 netlink 消息请求,如果未找到,则返回 NULL

int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request)

在服务 netlink 请求时阻止

参数

struct iwpm_nlmsg_request *nlmsg_request

要服务的 Netlink 消息请求

描述

在请求完成或过期后唤醒。如果请求完成且没有错误,则返回 0

int iwpm_get_nlmsg_seq(void)

获取要发送到端口映射器的 netlink 消息的序列号

参数

void

无参数

描述

返回 netlink 消息的序列号。

void iwpm_add_remote_info(struct iwpm_remote_info *reminfo)

将连接对等方的远程地址信息添加到远程信息哈希表

参数

struct iwpm_remote_info *reminfo

要添加的远程信息

u32 iwpm_check_registration(u8 nl_client, u32 reg)

检查客户端注册是否与给定的注册匹配

参数

u8 nl_client

netlink 客户端的索引

u32 reg

要比较的给定注册类型

描述

调用 iwpm_register_pid() 注册客户端。如果客户端注册与 reg 匹配,则返回 true,否则返回 false

void iwpm_set_registration(u8 nl_client, u32 reg)

设置客户端注册

参数

u8 nl_client

netlink 客户端的索引

u32 reg

要设置的注册类型

u32 iwpm_get_registration(u8 nl_client)

获取客户端注册

参数

u8 nl_client

netlink 客户端的索引

描述

返回客户端注册类型

int iwpm_send_mapinfo(u8 nl_client, int iwpm_pid)

将客户端的本地和映射的 IPv4/IPv6 地址信息发送到用户空间端口映射器

参数

u8 nl_client

netlink 客户端的索引

int iwpm_pid

用户空间端口映射器的 pid

描述

如果成功,则返回发送的映射信息记录数

int iwpm_mapinfo_available(void)

检查哈希表中是否有任何可用的映射信息记录

参数

void

无参数

描述

如果映射信息可用,则返回 1,否则返回 0

int iwpm_compare_sockaddr(struct sockaddr_storage *a_sockaddr, struct sockaddr_storage *b_sockaddr)

比较两个 sockaddr 存储结构体

参数

struct sockaddr_storage *a_sockaddr

要比较的第一个 sockaddr

struct sockaddr_storage *b_sockaddr

要比较的第二个 sockaddr

返回值

如果它们包含相同的 ip/tcp 地址信息,则返回 0,否则返回 1

int iwpm_validate_nlmsg_attr(struct nlattr *nltb[], int nla_count)

检查 NULL netlink 属性

参数

struct nlattr *nltb[]

保存每个 netlink 消息属性的地址

int nla_count

netlink 消息属性的数量

描述

如果任何 nla_count 属性为 NULL,则返回错误

struct sk_buff *iwpm_create_nlmsg(u32 nl_op, struct nlmsghdr **nlh, int nl_client)

分配 skb 并形成 netlink 消息

参数

u32 nl_op

Netlink 消息操作码

struct nlmsghdr **nlh

保存 skb 中 netlink 消息头的地址

int nl_client

netlink 客户端的索引

描述

返回新分配的 skb,如果 skb 的尾部空间不足以存储消息头和有效负载,则返回 NULL

int iwpm_parse_nlmsg(struct netlink_callback *cb, int policy_max, const struct nla_policy *nlmsg_policy, struct nlattr *nltb[], const char *msg_type)

验证并解析接收到的 netlink 消息

参数

struct netlink_callback *cb

Netlink 回调结构

int policy_max

期望的最大属性类型

const struct nla_policy *nlmsg_policy

验证策略

struct nlattr *nltb[]

用于存储 policy_max 解析元素的数组

const char *msg_type

Netlink 消息类型

描述

成功返回 0,或者返回负错误代码

void iwpm_print_sockaddr(struct sockaddr_storage *sockaddr, char *msg)

打印 IPv4/IPv6 地址和 TCP 端口

参数

struct sockaddr_storage *sockaddr

要打印的套接字地址

char *msg

要打印的消息

int iwpm_send_hello(u8 nl_client, int iwpm_pid, u16 abi_version)

向 iwpmd 发送 hello 响应

参数

u8 nl_client

netlink 客户端的索引

int iwpm_pid

用户空间端口映射器的 pid

u16 abi_version

内核的 abi_version

描述

成功返回 0,或者返回负错误代码

int ib_process_cq_direct(struct ib_cq *cq, int budget)

在调用者上下文中处理 CQ

参数

struct ib_cq *cq

要处理的 CQ

int budget

要轮询的 CQE 数量

描述

此函数用于处理所有未完成的 CQ 条目。它不会将 CQ 处理卸载到不同的上下文,也不会请求 HCA 发出完成中断。对非 IB_POLL_DIRECT 类型的 CQ 使用直接处理可能会触发并发处理。

注意

除非可以保证将要处理的完成数量很少,否则不要将 -1 作为 budget 传递。

struct ib_cq *__ib_alloc_cq(struct ib_device *dev, void *private, int nr_cqe, int comp_vector, enum ib_poll_context poll_ctx, const char *caller)

分配完成队列

参数

struct ib_device *dev

为其分配 CQ 的设备

void *private

驱动程序私有数据,可从 cq->cq_context 访问

int nr_cqe

要分配的 CQE 数量

int comp_vector

此 CQ 的 HCA 完成向量

enum ib_poll_context poll_ctx

从中轮询 CQ 的上下文。

const char *caller

模块所有者名称。

描述

这是为内核用户分配 CQ 的正确接口。使用此接口分配的 CQ 将自动从指定的上下文中轮询。ULP 必须使用 wr->wr_cqe 而不是 wr->wr_id 来使用此 CQ 抽象。

struct ib_cq *__ib_alloc_cq_any(struct ib_device *dev, void *private, int nr_cqe, enum ib_poll_context poll_ctx, const char *caller)

分配完成队列

参数

struct ib_device *dev

为其分配 CQ 的设备

void *private

驱动程序私有数据,可从 cq->cq_context 访问

int nr_cqe

要分配的 CQE 数量

enum ib_poll_context poll_ctx

用于轮询 CQ 的上下文

const char *caller

模块所有者名称

描述

尝试将 ULP 完成队列分散到每个设备的 中断向量上。使用了一种简单的尽力而为机制。

void ib_free_cq(struct ib_cq *cq)

释放一个完成队列

参数

struct ib_cq *cq

要释放的完成队列。

struct ib_cq *ib_cq_pool_get(struct ib_device *dev, unsigned int nr_cqe, int comp_vector_hint, enum ib_poll_context poll_ctx)

查找与给定 CPU 提示匹配(或对于通配符关联性最少使用)并且适合 nr_cqe 的最少使用的完成队列。

参数

struct ib_device *dev

RDMA 设备

unsigned int nr_cqe

需要的 cqe 条目的数量

int comp_vector_hint

完成向量提示(-1),让驱动程序根据内部计数器分配一个 comp 向量

enum ib_poll_context poll_ctx

cq 轮询上下文

描述

查找满足 comp_vector_hintnr_cqe 要求的 cq,并为我们声明其中的条目。 如果没有可用的 cq,则分配一个新的符合要求的 cq 并将其添加到设备池。IB_POLL_DIRECT 不能用于共享 cq,因此它不是 poll_ctx 的有效值。

void ib_cq_pool_put(struct ib_cq *cq, unsigned int nr_cqe)

返回从共享池中获取的 CQ。

参数

struct ib_cq *cq

要返回的 CQ。

unsigned int nr_cqe

用户已请求的最大 cqes 数量。

int ib_cm_listen(struct ib_cm_id *cm_id, __be64 service_id)

启动在指定的服务 ID 上侦听连接和服务 ID 解析请求。

参数

struct ib_cm_id *cm_id

与侦听请求关联的连接标识符。

__be64 service_id

与传入连接和服务 ID 解析请求匹配的服务标识符。服务 ID 应以网络字节顺序指定。如果设置为 IB_CM_ASSIGN_SERVICE_ID,则 CM 会为调用者分配一个服务 ID。

struct ib_cm_id *ib_cm_insert_listen(struct ib_device *device, ib_cm_handler cm_handler, __be64 service_id)

创建一个新的侦听 ib_cm_id 并在给定的服务 ID 上侦听。

参数

struct ib_device *device

与 cm_id 关联的设备。所有相关的通信都将与指定的设备关联。

ib_cm_handler cm_handler

调用以通知用户 CM 事件的回调。

__be64 service_id

与传入连接和服务 ID 解析请求匹配的服务标识符。服务 ID 应以网络字节顺序指定。如果设置为 IB_CM_ASSIGN_SERVICE_ID,则 CM 会为调用者分配一个服务 ID。

描述

如果存在在同一设备和服务 ID 上侦听的现有 ID,则返回它。

调用者应在完成侦听器 ID 后调用 ib_destroy_cm_id。

int rdma_rw_ctx_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u32 port_num, struct scatterlist *sg, u32 sg_cnt, u32 sg_offset, u64 remote_addr, u32 rkey, enum dma_data_direction dir)

初始化一个 RDMA 读取/写入上下文

参数

struct rdma_rw_ctx *ctx

要初始化的上下文

struct ib_qp *qp

要操作的队列对

u32 port_num

连接绑定的端口号

struct scatterlist *sg

要从/向其读取/写入的散列表

u32 sg_cnt

sg 中的条目数

u32 sg_offset

当前在 sg 中的字节偏移量

u64 remote_addr

要读取/写入的远程地址(相对于 rkey

u32 rkey

要操作的远程密钥

enum dma_data_direction dir

对于 RDMA 写入,为 DMA_TO_DEVICE;对于 RDMA 读取,为 DMA_FROM_DEVICE

描述

如果成功,则返回工作队列上需要的 WQE 数量,否则返回负错误代码。

int rdma_rw_ctx_signature_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u32 port_num, struct scatterlist *sg, u32 sg_cnt, struct scatterlist *prot_sg, u32 prot_sg_cnt, struct ib_sig_attrs *sig_attrs, u64 remote_addr, u32 rkey, enum dma_data_direction dir)

使用签名卸载初始化一个 RW 上下文

参数

struct rdma_rw_ctx *ctx

要初始化的上下文

struct ib_qp *qp

要操作的队列对

u32 port_num

连接绑定的端口号

struct scatterlist *sg

要从/向其读取/写入的散列表

u32 sg_cnt

sg 中的条目数

struct scatterlist *prot_sg

从/向其读取/写入保护信息的散列表

u32 prot_sg_cnt

prot_sg 中的条目数

struct ib_sig_attrs *sig_attrs

签名卸载算法

u64 remote_addr

要读取/写入的远程地址(相对于 rkey

u32 rkey

要操作的远程密钥

enum dma_data_direction dir

对于 RDMA 写入,为 DMA_TO_DEVICE;对于 RDMA 读取,为 DMA_FROM_DEVICE

描述

如果成功,则返回工作队列上需要的 WQE 数量,否则返回负错误代码。

struct ib_send_wr *rdma_rw_ctx_wrs(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u32 port_num, struct ib_cqe *cqe, struct ib_send_wr *chain_wr)

返回用于 RDMA 读取或写入操作的 WR 链

参数

struct rdma_rw_ctx *ctx

要操作的上下文

struct ib_qp *qp

要操作的队列对

u32 port_num

连接绑定的端口号

struct ib_cqe *cqe

最后一个 WR 的完成队列条目

struct ib_send_wr *chain_wr

要附加到已发布链的 WR

描述

返回由 ctx 描述的一组 RDMA 读取/写入操作的 WR 链,以及所需的任何内存注册操作。如果 chain_wr 非 NULL,它指向的 WR 将附加到已发布的 WR 链。如果未设置 chain_wr,则必须设置 cqe,以便调用者收到完成通知。

int rdma_rw_ctx_post(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u32 port_num, struct ib_cqe *cqe, struct ib_send_wr *chain_wr)

发布 RDMA 读取或 RDMA 写入操作

参数

struct rdma_rw_ctx *ctx

要操作的上下文

struct ib_qp *qp

要操作的队列对

u32 port_num

连接绑定的端口号

struct ib_cqe *cqe

最后一个 WR 的完成队列条目

struct ib_send_wr *chain_wr

要附加到已发布链的 WR

描述

发布由 ctx 描述的一组 RDMA 读取/写入操作,以及所需的任何内存注册操作。如果 chain_wr 非 NULL,它指向的 WR 将附加到已发布的 WR 链。如果未设置 chain_wr,则必须设置 cqe,以便调用者收到完成通知。

void rdma_rw_ctx_destroy(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u32 port_num, struct scatterlist *sg, u32 sg_cnt, enum dma_data_direction dir)

释放由 rdma_rw_ctx_init 分配的所有资源

参数

struct rdma_rw_ctx *ctx

要释放的上下文

struct ib_qp *qp

要操作的队列对

u32 port_num

连接绑定的端口号

struct scatterlist *sg

用于读取/写入的分散列表

u32 sg_cnt

sg 中的条目数

enum dma_data_direction dir

对于 RDMA 写入,为 DMA_TO_DEVICE;对于 RDMA 读取,为 DMA_FROM_DEVICE

void rdma_rw_ctx_destroy_signature(struct rdma_rw_ctx *ctx, struct ib_qp *qp, u32 port_num, struct scatterlist *sg, u32 sg_cnt, struct scatterlist *prot_sg, u32 prot_sg_cnt, enum dma_data_direction dir)

释放由 rdma_rw_ctx_signature_init 分配的所有资源

参数

struct rdma_rw_ctx *ctx

要释放的上下文

struct ib_qp *qp

要操作的队列对

u32 port_num

连接绑定的端口号

struct scatterlist *sg

用于读取/写入的分散列表

u32 sg_cnt

sg 中的条目数

struct scatterlist *prot_sg

用于 PI 读取/写入的分散列表

u32 prot_sg_cnt

prot_sg 中的条目数

enum dma_data_direction dir

对于 RDMA 写入,为 DMA_TO_DEVICE;对于 RDMA 读取,为 DMA_FROM_DEVICE

unsigned int rdma_rw_mr_factor(struct ib_device *device, u32 port_num, unsigned int maxpages)

返回有效负载所需的 MR 数

参数

struct ib_device *device

处理连接的设备

u32 port_num

连接绑定的端口号

unsigned int maxpages

每个 rdma_rw_ctx 的最大有效负载页面数

描述

返回设备移动 maxpayload 字节所需的 MR 数。返回的值在传输创建期间用于计算 max_rdma_ctxts 和传输的发送和发送完成队列的大小。

bool rdma_dev_access_netns(const struct ib_device *dev, const struct net *net)

返回是否可以从指定的网络命名空间访问 rdma 设备。

参数

const struct ib_device *dev

指向需要检查的 rdma 设备的指针

const struct net *net

指向要检查访问权限的网络命名空间的指针

描述

当 rdma 设备处于共享模式时,它会忽略网络命名空间。当 rdma 设备专用于某个网络命名空间时,将检查 rdma 设备网络命名空间是否与指定的命名空间匹配。

void ib_device_put(struct ib_device *device)

释放 IB 设备引用

参数

struct ib_device *device

要释放其引用的设备

描述

ib_device_put() 释放对 IB 设备的引用,以允许其取消注册并最终释放。

struct ib_device *ib_device_get_by_name(const char *name, enum rdma_driver_id driver_id)

按名称查找 IB 设备

参数

const char *name

要查找的名称

enum rdma_driver_id driver_id

必须匹配的驱动程序 ID (RDMA_DRIVER_UNKNOWN 匹配所有)

描述

按其名称查找并保留 ib_device。调用者必须在返回的指针上调用 ib_device_put()

struct ib_device *_ib_alloc_device(size_t size)

分配一个 IB 设备结构

参数

size_t size

要分配的结构的大小

描述

低级驱动程序应使用 ib_alloc_device() 来分配 struct ib_devicesize 是要分配的结构的大小,包括低级驱动程序使用的任何私有数据。必须使用 ib_dealloc_device() 来释放使用 ib_alloc_device() 分配的结构。

void ib_dealloc_device(struct ib_device *device)

释放一个 IB 设备结构

参数

struct ib_device *device

要释放的结构

描述

释放使用 ib_alloc_device() 分配的结构。

const struct ib_port_immutable *ib_port_immutable_read(struct ib_device *dev, unsigned int port)

读取 rdma 端口的不可变数据

参数

struct ib_device *dev

IB 设备

unsigned int port

要读取其不可变数据的端口号。索引从 1 开始,有效值直到 rdma_end_port()(包括该值)。

int ib_register_device(struct ib_device *device, const char *name, struct device *dma_device)

向 IB 核心注册一个 IB 设备

参数

struct ib_device *device

要注册的设备

const char *name

唯一的字符串设备名称。这可以包含一个“%”,这将导致将唯一的索引添加到传递的设备名称中。

struct device *dma_device

指向具有 DMA 功能的设备的指针。如果为 NULL,则将使用 IB 设备。在这种情况下,调用者应完全设置 ibdev 以进行 DMA。这通常意味着使用 dma_virt_ops。

描述

底层驱动程序使用 ib_register_device() 向 IB 核心注册其设备。所有注册的客户端都将收到为每个添加的设备的回调。必须使用 ib_alloc_device() 分配 device

如果驱动程序使用 ops.dealloc_driver 并异步调用任何 ib_unregister_device(),则设备指针可能会在此函数返回后立即被释放。

void ib_unregister_device(struct ib_device *ib_dev)

注销 IB 设备

参数

struct ib_device *ib_dev

要注销的设备

描述

注销 IB 设备。所有客户端都将收到删除回调。

调用者应仅调用此例程一次,并防止与注册发生竞争。通常,它应仅在驱动程序核心的 struct device_driver 及相关实现的删除回调中调用。

如果使用了 ops.dealloc_driver,则 ib_dev 将在此函数返回时被释放。

void ib_unregister_device_and_put(struct ib_device *ib_dev)

在持有 “get” 的同时注销设备

参数

struct ib_device *ib_dev

要注销的设备

描述

这与 ib_unregister_device() 相同,只不过它包含一个内部的 ib_device_put(),该函数应与调用者获得的 “get” 相匹配。

在持有 “get” 的同时,可以从多个线程并发调用此例程。当函数返回时,设备将完全注销。

使用此流程的驱动程序必须使用 driver_unregister 回调来清理其与设备关联的资源并释放它。

void ib_unregister_driver(enum rdma_driver_id driver_id)

注销驱动程序的所有 IB 设备

参数

enum rdma_driver_id driver_id

要注销的驱动程序

描述

这将为设备注销实现一个栅栏。只有当与 driver_id 关联的所有设备都完全完成其注销并从 ib_unregister_device*() 返回时,它才会返回。

如果设备尚未注销,它会继续并开始注销它们。

这不会阻止使用给定的 driver_id 创建新设备,这是调用者的责任。

void ib_unregister_device_queued(struct ib_device *ib_dev)

使用工作队列注销设备

参数

struct ib_device *ib_dev

要注销的设备

描述

这会使用 WQ 为设备调度异步注销。驱动程序应使用此方法来避免在执行注销时持有锁,例如持有 RTNL 锁。

使用此 API 的驱动程序必须在模块卸载之前使用 ib_unregister_driver,以确保所有计划的注销都已完成。

int ib_register_client(struct ib_client *client)

注册 IB 客户端

参数

struct ib_client *client

要注册的客户端

描述

IB 驱动程序的上层用户可以使用 ib_register_client() 注册 IB 设备添加和删除的回调。当添加 IB 设备时,将调用每个注册客户端的 add 方法(按照客户端注册的顺序),当删除设备时,将调用每个客户端的 remove 方法(按照客户端注册的相反顺序)。此外,当调用 ib_register_client() 时,客户端将收到为所有已注册设备添加的回调。

void ib_unregister_client(struct ib_client *client)

注销 IB 客户端

参数

struct ib_client *client

要注销的客户端

描述

上层用户使用 ib_unregister_client() 删除其客户端注册。当调用 ib_unregister_client() 时,客户端将收到为每个仍注册的 IB 设备删除的回调。

这是一个完整的栅栏,一旦它返回,将不会调用任何客户端回调,也不会在另一个线程中运行。

void ib_set_client_data(struct ib_device *device, struct ib_client *client, void *data)

设置 IB 客户端上下文

参数

struct ib_device *device

要设置上下文的设备

struct ib_client *client

要设置上下文的客户端

void *data

要设置的上下文

描述

ib_set_client_data() 设置客户端上下文数据,可以使用 ib_get_client_data() 检索。这只能在客户端注册到设备时调用,一旦 ib_client remove() 回调返回,就不能再调用此方法。

void ib_register_event_handler(struct ib_event_handler *event_handler)

注册 IB 事件处理程序

参数

struct ib_event_handler *event_handler

要注册的处理程序

描述

ib_register_event_handler() 注册一个事件处理程序,当发生异步 IB 事件时(如 InfiniBand 架构规范的第 11 章中所定义),将调用该处理程序。此回调发生在工作队列上下文中。

void ib_unregister_event_handler(struct ib_event_handler *event_handler)

注销事件处理程序

参数

struct ib_event_handler *event_handler

要注销的处理程序

描述

注销使用 ib_register_event_handler() 注册的事件处理程序。

int ib_query_port(struct ib_device *device, u32 port_num, struct ib_port_attr *port_attr)

查询 IB 端口属性

参数

struct ib_device *device

要查询的设备

u32 port_num

要查询的端口号

struct ib_port_attr *port_attr

端口属性

描述

ib_query_port() 通过 port_attr 指针返回端口的属性。

int ib_device_set_netdev(struct ib_device *ib_dev, struct net_device *ndev, u32 port)

将 ib_dev 与底层 net_device 关联

参数

struct ib_device *ib_dev

要修改的设备

struct net_device *ndev

要关联的 net_device,可以为 NULL

u32 port

net_device 连接到的 IB 端口

描述

驱动程序应使用此方法将 ib_device 链接到 netdev,以便 netdev 出现在 ib_enum_roce_netdev 等接口中。任何端口只能关联一个 netdev。

调用者必须确保给定的 ndev 未被注销或正在注销,并且当 ndev 发送 NETDEV_UNREGISTER 事件时,ib_device 已被注销,或者调用了 ib_device_set_netdev() 并传入 NULL。

struct ib_device *ib_device_get_by_netdev(struct net_device *ndev, enum rdma_driver_id driver_id)

查找与 netdev 关联的 IB 设备

参数

struct net_device *ndev

要定位的 netdev

enum rdma_driver_id driver_id

必须匹配的驱动程序 ID (RDMA_DRIVER_UNKNOWN 匹配所有)

描述

查找并持有通过 ib_device_set_netdev() 与 netdev 关联的 ib_device。 调用者必须对返回的指针调用 ib_device_put()

int ib_query_pkey(struct ib_device *device, u32 port_num, u16 index, u16 *pkey)

获取 P_Key 表条目

参数

struct ib_device *device

要查询的设备

u32 port_num

要查询的端口号

u16 index

要查询的 P_Key 表索引

u16 *pkey

返回的 P_Key

描述

ib_query_pkey() 获取指定的 P_Key 表条目。

int ib_modify_device(struct ib_device *device, int device_modify_mask, struct ib_device_modify *device_modify)

更改 IB 设备属性

参数

struct ib_device *device

要修改的设备

int device_modify_mask

要更改的属性的掩码

struct ib_device_modify *device_modify

新的属性值

描述

ib_modify_device() 更改设备的属性,由 device_modify_maskdevice_modify 结构指定。

int ib_modify_port(struct ib_device *device, u32 port_num, int port_modify_mask, struct ib_port_modify *port_modify)

修改指定端口的属性。

参数

struct ib_device *device

要修改的设备。

u32 port_num

要修改的端口号。

int port_modify_mask

用于指定要更改的端口属性的掩码。

struct ib_port_modify *port_modify

端口的新属性值。

描述

ib_modify_port() 更改端口的属性,由 port_modify_maskport_modify 结构指定。

int ib_find_gid(struct ib_device *device, union ib_gid *gid, u32 *port_num, u16 *index)

返回指定 GID 值出现的端口号和 GID 表索引。它只搜索 IB 链路层。

参数

struct ib_device *device

要查询的设备。

union ib_gid *gid

要搜索的 GID 值。

u32 *port_num

找到 GID 值的设备的端口号。

u16 *index

找到 GID 的 GID 表索引。此参数可以为 NULL。

int ib_find_pkey(struct ib_device *device, u32 port_num, u16 pkey, u16 *index)

返回指定 PKey 值出现的 PKey 表索引。

参数

struct ib_device *device

要查询的设备。

u32 port_num

要搜索 PKey 的设备的端口号。

u16 pkey

要搜索的 PKey 值。

u16 *index

找到 PKey 的 PKey 表索引。

struct net_device *ib_get_net_dev_by_params(struct ib_device *dev, u32 port, u16 pkey, const union ib_gid *gid, const struct sockaddr *addr)

为接收到的 CM 请求返回合适的 net_dev。

参数

struct ib_device *dev

接收请求的 RDMA 设备。

u32 port

RDMA 设备上的端口号。

u16 pkey

请求到达时使用的 Pkey。

const union ib_gid *gid

net_dev 用于通信的 GID。

const struct sockaddr *addr

包含请求指定的作为其目标的 IP 地址。

struct ib_pd *__ib_alloc_pd(struct ib_device *device, unsigned int flags, const char *caller)

分配一个未使用的保护域。

参数

struct ib_device *device

要在其上分配保护域的设备。

unsigned int flags

保护域标志

const char *caller

调用者的构建时模块名称

描述

保护域对象提供 QP、共享接收队列、地址句柄、内存区域和内存窗口之间的关联。

每个 PD 都有一个 local_dma_lkey,可以用作本地内存操作的 lkey 值。

int ib_dealloc_pd_user(struct ib_pd *pd, struct ib_udata *udata)

释放保护域。

参数

struct ib_pd *pd

要释放的保护域。

struct ib_udata *udata

有效的用户数据或内核对象的 NULL

描述

如果在 pd 中仍存在任何资源,则调用此函数会出错。调用者负责同步销毁它们,并保证不会发生新的分配。

void rdma_copy_ah_attr(struct rdma_ah_attr *dest, const struct rdma_ah_attr *src)

将 rdma ah 属性从源复制到目标。

参数

struct rdma_ah_attr *dest

指向目标 ah_attr 的指针。假定目标指针的内容无效,并且属性被覆盖。

const struct rdma_ah_attr *src

指向源 ah_attr 的指针。

void rdma_replace_ah_attr(struct rdma_ah_attr *old, const struct rdma_ah_attr *new)

用新的 ah_attr 替换有效的 ah_attr。

参数

struct rdma_ah_attr *old

指向需要替换的现有 ah_attr 的指针。假定 old 有效或为零

const struct rdma_ah_attr *new

指向新的 ah_attr 的指针。

描述

rdma_replace_ah_attr() 首先释放 old ah_attr 中的任何引用(如果 old ah_attr 有效);之后,它复制新属性并保留对被替换的 ah_attr 的引用。

void rdma_move_ah_attr(struct rdma_ah_attr *dest, struct rdma_ah_attr *src)

将源指向的 ah_attr 移动到目标。

参数

struct rdma_ah_attr *dest

指向要复制到的目标 ah_attr 的指针。假设 dest 有效或为零

struct rdma_ah_attr *src

指向新的 ah_attr 的指针。

描述

rdma_move_ah_attr() 首先释放目标 ah_attr 中的任何引用(如果有效)。这也将内部引用的所有权从 src 转移到 dest,使 src 在此过程中无效。不采用 src ah_attr 的新引用。

struct ib_ah *rdma_create_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, u32 flags)

为给定的地址向量创建地址句柄。

参数

struct ib_pd *pd

与地址句柄关联的保护域。

struct rdma_ah_attr *ah_attr

地址向量的属性。

u32 flags

创建地址句柄标志(请参阅枚举 rdma_create_ah_flags)。

描述

成功时返回 0,错误时返回相应的错误代码。地址句柄用于引用所有 UD QP 发布发送中的本地或全局目标。

struct ib_ah *rdma_create_user_ah(struct ib_pd *pd, struct rdma_ah_attr *ah_attr, struct ib_udata *udata)

为给定的地址向量创建地址句柄。它解析 RoCE 类型的 ah 属性的目标 MAC 地址。

参数

struct ib_pd *pd

与地址句柄关联的保护域。

struct rdma_ah_attr *ah_attr

地址向量的属性。

struct ib_udata *udata

指向提供程序驱动程序所需的用户输入输出缓冲区信息的指针。

描述

成功时返回 0,错误时返回相应的错误代码。地址句柄用于引用所有 UD QP 发布发送中的本地或全局目标。

void rdma_move_grh_sgid_attr(struct rdma_ah_attr *attr, union ib_gid *dgid, u32 flow_label, u8 hop_limit, u8 traffic_class, const struct ib_gid_attr *sgid_attr)

设置 GRH 的 sgid 属性,并取得该引用的所有权

参数

struct rdma_ah_attr *attr

指向 AH 属性结构的指针

union ib_gid *dgid

目标 GID

u32 flow_label

流标签

u8 hop_limit

跳数限制

u8 traffic_class

流量类别

const struct ib_gid_attr *sgid_attr

指向 SGID 属性的指针

描述

此函数取得 sgid_attr 引用的所有权。调用者必须确保在调用此函数后销毁 rdma_ah_attr 之前调用rdma_destroy_ah_attr()

void rdma_destroy_ah_attr(struct rdma_ah_attr *ah_attr)

释放对 ah 属性的 SGID 属性的引用。

参数

struct rdma_ah_attr *ah_attr

指向 ah 属性的指针

描述

如果 ah 属性的 SGID 属性非 NULL,则释放对其的引用。可以安全地多次调用此函数,并且可以安全地在零初始化的 ah_attr 上调用此函数。

struct ib_srq *ib_create_srq_user(struct ib_pd *pd, struct ib_srq_init_attr *srq_init_attr, struct ib_usrq_object *uobject, struct ib_udata *udata)

创建与指定保护域关联的 SRQ。

参数

struct ib_pd *pd

与 SRQ 关联的保护域。

struct ib_srq_init_attr *srq_init_attr

创建 SRQ 所需的初始属性列表。如果 SRQ 创建成功,则属性将更新为已创建 SRQ 的实际功能。

struct ib_usrq_object *uobject

如果这不是内核 SRQ,则为 uobject 指针

struct ib_udata *udata

如果这不是内核 SRQ,则为 udata 指针

描述

读取 srq_attr->max_wr 和 srq_attr->max_sge 以确定请求的 SRQ 大小,并在返回时设置为实际分配的值。如果 ib_create_srq() 成功,则 max_wr 和 max_sge 将始终至少与请求的值一样大。

struct ib_qp *ib_create_qp_user(struct ib_device *dev, struct ib_pd *pd, struct ib_qp_init_attr *attr, struct ib_udata *udata, struct ib_uqp_object *uobj, const char *caller)

创建与指定保护域关联的 QP。

参数

struct ib_device *dev

IB 设备

struct ib_pd *pd

与 QP 关联的保护域。

struct ib_qp_init_attr *attr

创建 QP 所需的初始属性列表。如果 QP 创建成功,则属性将更新为已创建 QP 的实际功能。

struct ib_udata *udata

用户数据

struct ib_uqp_object *uobj

uverbs 对象

const char *caller

调用者的构建时模块名称

int ib_modify_qp_with_udata(struct ib_qp *ib_qp, struct ib_qp_attr *attr, int attr_mask, struct ib_udata *udata)

修改指定 QP 的属性。

参数

struct ib_qp *ib_qp

要修改的 QP。

struct ib_qp_attr *attr

在输入时,指定要修改的 QP 属性。在输出时,返回选定 QP 属性的当前值。

int attr_mask

一个位掩码,用于指定正在修改 QP 的哪些属性。

struct ib_udata *udata

指向正在修改的用户输入输出缓冲区信息的指针。成功时返回 0,错误时返回相应的错误代码。

struct ib_mr *ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, u32 max_num_sg)

分配内存区域

参数

struct ib_pd *pd

与该区域关联的保护域

enum ib_mr_type mr_type

内存区域类型

u32 max_num_sg

可用于注册的最大 sg 条目数。

备注

内存注册页面/sg 列表不得超过 max_num_sg。对于 mr_type IB_MR_TYPE_MEM_REG,总长度不能超过 max_num_sg * used_page_size。

struct ib_mr *ib_alloc_mr_integrity(struct ib_pd *pd, u32 max_num_data_sg, u32 max_num_meta_sg)

分配完整性内存区域

参数

struct ib_pd *pd

与该区域关联的保护域

u32 max_num_data_sg

可用于注册的最大数据 sg 条目数

u32 max_num_meta_sg

可用于注册的最大元数据 sg 条目数

备注

内存注册页面/sg 列表不得超过 max_num_sg,完整性页面/sg 列表不得超过 max_num_meta_sg。

struct ib_xrcd *ib_alloc_xrcd_user(struct ib_device *device, struct inode *inode, struct ib_udata *udata)

分配 XRC 域。

参数

struct ib_device *device

要在其上分配 XRC 域的设备。

struct inode *inode

用于连接 XRCD 的 inode

struct ib_udata *udata

有效的用户数据或内核对象的 NULL

int ib_dealloc_xrcd_user(struct ib_xrcd *xrcd, struct ib_udata *udata)

释放 XRC 域。

参数

struct ib_xrcd *xrcd

要释放的 XRC 域。

struct ib_udata *udata

有效的用户数据或内核对象的 NULL

struct ib_wq *ib_create_wq(struct ib_pd *pd, struct ib_wq_init_attr *wq_attr)

创建与指定保护域关联的 WQ。

参数

struct ib_pd *pd

与 WQ 关联的保护域。

struct ib_wq_init_attr *wq_attr

创建 WQ 所需的初始属性列表。如果 WQ 创建成功,则属性将更新为已创建 WQ 的实际功能。

描述

wq_attr->max_wr 和 wq_attr->max_sge 确定 WQ 的请求大小,并在返回时设置为实际分配的值。如果 ib_create_wq() 成功,则 max_wr 和 max_sge 将始终至少与请求的值一样大。

int ib_destroy_wq_user(struct ib_wq *wq, struct ib_udata *udata)

销毁指定的用户 WQ。

参数

struct ib_wq *wq

要销毁的 WQ。

struct ib_udata *udata

有效的用户数据

int ib_map_mr_sg_pi(struct ib_mr *mr, struct scatterlist *data_sg, int data_sg_nents, unsigned int *data_sg_offset, struct scatterlist *meta_sg, int meta_sg_nents, unsigned int *meta_sg_offset, unsigned int page_size)

映射用于 PI(保护信息)的 DMA 映射的 SG 列表,并设置适当的内存区域以进行注册。

参数

struct ib_mr *mr

内存区域

struct scatterlist *data_sg

用于数据的 DMA 映射的散列表

int data_sg_nents

data_sg 中的条目数

unsigned int *data_sg_offset

data_sg 中的字节偏移量

struct scatterlist *meta_sg

用于元数据的 DMA 映射的散列表

int meta_sg_nents

meta_sg 中的条目数

unsigned int *meta_sg_offset

meta_sg 中的字节偏移量

unsigned int page_size

页面向量所需的页面大小

描述

约束条件:- 必须使用 IB_MR_TYPE_INTEGRITY 类型分配 MR。

此操作成功完成后,内存区域即可进行注册。

返回值

成功时返回 0。

int ib_map_mr_sg(struct ib_mr *mr, struct scatterlist *sg, int sg_nents, unsigned int *sg_offset, unsigned int page_size)

映射 DMA 映射的 SG 列表的最大前缀并将其设置为内存区域。

参数

struct ib_mr *mr

内存区域

struct scatterlist *sg

DMA 映射的散列表

int sg_nents

sg 中的条目数

unsigned int *sg_offset

sg 中的字节偏移量

unsigned int page_size

页面向量所需的页面大小

描述

约束条件

  • 允许第一个 sg 元素具有偏移量。

  • 每个 sg 元素都必须与 page_size 对齐,或者与前一个元素虚拟连续。如果 sg 元素具有非连续偏移量,则映射前缀将不包括它。

  • 允许最后一个 sg 元素的长度小于 page_size。

  • 如果 sg_nents 的总字节长度超过 mr max_num_sge * page_size,则仅映射 max_num_sg 个条目。

  • 如果 MR 是使用 IB_MR_TYPE_SG_GAPS 类型分配的,则这些约束都不成立,并且将忽略 page_size 参数。

返回映射到内存区域的 sg 元素的数量。

此操作成功完成后,内存区域即可进行注册。

int ib_sg_to_pages(struct ib_mr *mr, struct scatterlist *sgl, int sg_nents, unsigned int *sg_offset_p, int (*set_page)(struct ib_mr*, u64))

将 sg 列表的最大前缀转换为页面向量

参数

struct ib_mr *mr

内存区域

struct scatterlist *sgl

DMA 映射的散列表

int sg_nents

sg 中的条目数

unsigned int *sg_offset_p

输入

sg 中的起始字节偏移量

输出

sg 的元素 n 的字节偏移量,其中 n 是此函数的返回值,该元素 n 是第一个尚未处理的字节。

int (*set_page)(struct ib_mr *, u64)

驱动程序页面分配函数指针

描述

核心服务帮助驱动程序将给定 sg 列表的最大前缀转换为页面向量。转换后的 sg 列表前缀是满足 ib_map_mr_sg 要求的那个前缀。

返回分配给页面向量的 sg 元素的数量。

void ib_drain_sq(struct ib_qp *qp)

阻塞直到应用程序消耗完所有 SQ CQE。

参数

struct ib_qp *qp

要排空的队列对

描述

如果设备具有特定于提供程序的排空函数,则调用该函数。否则,调用通用排空函数 __ib_drain_sq()。

调用者必须

确保 CQ 和 SQ 中有足够的空间用于排空工作请求和完成。

使用 ib_alloc_cq() 分配 CQ。

确保没有其他上下文同时发布 WR。否则,无法保证排空。

void ib_drain_rq(struct ib_qp *qp)

阻塞直到应用程序消耗完所有 RQ CQE。

参数

struct ib_qp *qp

要排空的队列对

描述

如果设备具有特定于提供程序的排空函数,则调用该函数。否则,调用通用排空函数 __ib_drain_rq()。

调用者必须

确保 CQ 和 RQ 中有足够的空间用于排空工作请求和完成。

使用 ib_alloc_cq() 分配 CQ。

确保没有其他上下文同时发布 WR。否则,无法保证排空。

void ib_drain_qp(struct ib_qp *qp)

阻塞直到应用程序在 RQ 和 SQ 上消耗完所有 CQE。

参数

struct ib_qp *qp

要排空的队列对

描述

调用者必须

确保 CQ、SQ 和 RQ 中有足够的空间用于排空工作请求和完成。

使用 ib_alloc_cq() 分配 CQ。

确保没有其他上下文同时发布 WR。否则,无法保证排空。

struct rdma_hw_stats *rdma_alloc_hw_stats_struct(const struct rdma_stat_desc *descs, int num_counters, unsigned long lifespan)

用于为驱动程序分配动态结构的辅助函数。

参数

const struct rdma_stat_desc *descs

静态描述符数组

int num_counters

数组中元素的数量

unsigned long lifespan

更新之间的毫秒数

void rdma_free_hw_stats_struct(struct rdma_hw_stats *stats)

用于释放 rdma_hw_stats 的辅助函数

参数

struct rdma_hw_stats *stats

要释放的统计信息

void ib_pack(const struct ib_field *desc, int desc_len, void *structure, void *buf)

将结构体打包到缓冲区中

参数

const struct ib_field *desc

结构体字段描述数组

int desc_len

desc 中的条目数量

void *structure

要打包的结构体

void *buf

要打包到的缓冲区

描述

ib_pack() 根据 desc 中的字段数组,将结构体字段列表打包到缓冲区中。

void ib_unpack(const struct ib_field *desc, int desc_len, void *buf, void *structure)

将缓冲区解包到结构体中

参数

const struct ib_field *desc

结构体字段描述数组

int desc_len

desc 中的条目数量

void *buf

要解包的缓冲区

void *structure

要解包到的结构体

描述

ib_pack() 根据 desc 中的字段数组,将缓冲区中的结构体字段列表解包到结构体中。

void ib_sa_cancel_query(int id, struct ib_sa_query *query)

尝试取消 SA 查询

参数

int id

要取消的查询 ID

struct ib_sa_query *query

要取消的查询指针

描述

尝试取消 SA 查询。如果 id 和 query 不匹配,或者查询已经完成,则不执行任何操作。否则,查询将被取消,并以 -EINTR 的状态完成。

int ib_init_ah_attr_from_path(struct ib_device *device, u32 port_num, struct sa_path_rec *rec, struct rdma_ah_attr *ah_attr, const struct ib_gid_attr *gid_attr)

基于 SA 路径记录初始化地址句柄属性。

参数

struct ib_device *device

与 ah 属性初始化相关的设备。

u32 port_num

指定设备上的端口。

struct sa_path_rec *rec

用于 ah 属性初始化的路径记录条目。

struct rdma_ah_attr *ah_attr

要从路径记录初始化的地址句柄属性。

const struct ib_gid_attr *gid_attr

在初始化期间要考虑的 SGID 属性。

描述

ib_init_ah_attr_from_path() 返回成功时,(a) 对于 IB 链路层,如果 IB 链路层存在 GRH,则可以选择包含对 SGID 属性的引用。(b) 对于 RoCE 链路层,它包含对 SGID 属性的引用。用户必须调用 rdma_destroy_ah_attr() 来释放对使用 ib_init_ah_attr_from_path() 初始化的 SGID 属性的引用。

int ib_sa_path_rec_get(struct ib_sa_client *client, struct ib_device *device, u32 port_num, struct sa_path_rec *rec, ib_sa_comp_mask comp_mask, unsigned long timeout_ms, gfp_t gfp_mask, void (*callback)(int status, struct sa_path_rec *resp, unsigned int num_paths, void *context), void *context, struct ib_sa_query **sa_query)

启动路径获取查询

参数

struct ib_sa_client *client

SA 客户端

struct ib_device *device

在其上发送查询的设备

u32 port_num

在其上发送查询的端口号

struct sa_path_rec *rec

在查询中发送的路径记录

ib_sa_comp_mask comp_mask

在查询中发送的组件掩码

unsigned long timeout_ms

等待响应的时间

gfp_t gfp_mask

用于内部分配的 GFP 掩码

void (*callback)(int status, struct sa_path_rec *resp, unsigned int num_paths, void *context)

查询完成、超时或被取消时调用的函数

void *context

传递给回调的不透明用户上下文

struct ib_sa_query **sa_query

查询上下文,用于取消查询

描述

向 SA 发送路径记录获取查询以查找路径。查询完成(或失败)时将调用回调函数;状态为 0 表示成功响应,-EINTR 表示查询被取消,-ETIMEDOUT 表示查询超时,或 -EIO 表示发送查询时发生错误。回调的 resp 参数仅在状态为 0 时有效。

如果 ib_sa_path_rec_get() 的返回值是负数,则表示错误代码。否则,它是可用于取消查询的查询 ID。

int ib_ud_header_init(int payload_bytes, int lrh_present, int eth_present, int vlan_present, int grh_present, int ip_version, int udp_present, int immediate_present, struct ib_ud_header *header)

初始化 UD 头部结构

参数

int payload_bytes

数据包有效负载的长度

int lrh_present

指定是否包含 LRH

int eth_present

指定是否包含 Eth 头部

int vlan_present

数据包是否为 VLAN 标记

int grh_present

GRH 标志(如果非零,将包含 GRH)

int ip_version

如果非零,将包含 IP 头部,V4 或 V6

int udp_present

如果非零,将包含 UDP 头部

int immediate_present

指定是否包含立即数据

struct ib_ud_header *header

要初始化的结构体

int ib_ud_header_pack(struct ib_ud_header *header, void *buf)

将 UD 头部结构体打包成线格式

参数

struct ib_ud_header *header

UD 头部结构体

void *buf

要打包到的缓冲区

描述

ib_ud_header_pack() 将 UD 头部结构体 header 打包成线格式,放入缓冲区 buf 中。

int ib_ud_header_unpack(void *buf, struct ib_ud_header *header)

从线格式解包 UD 头部结构体

参数

void *buf

要打包到的缓冲区

struct ib_ud_header *header

UD 头部结构体

描述

ib_ud_header_pack() 从缓冲区 buf 中,将线格式的 UD 头部结构体解包到 header 中。

unsigned long ib_umem_find_best_pgsz(struct ib_umem *umem, unsigned long pgsz_bitmap, unsigned long virt)

为这个 MR 查找要使用的最佳硬件页面大小

参数

struct ib_umem *umem

umem 结构体

unsigned long pgsz_bitmap

硬件支持的页面大小的位图

unsigned long virt

IOVA

描述

这个辅助函数用于支持多种页面大小的硬件,但一个 MR 中只能使用一种页面大小的情况。

如果 umem 需要映射驱动程序不支持的页面大小,则返回 0。始终支持 PAGE_SIZE 或更小的驱动程序永远不会看到 0 的结果。

struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr, size_t size, int access)

锁定并 DMA 映射用户空间内存。

参数

struct ib_device *device

要连接 UMEM 的 IB 设备

unsigned long addr

用户空间起始虚拟地址

size_t size

要锁定的区域长度

int access

用于锁定内存的 IB_ACCESS_xxx 标志

void ib_umem_release(struct ib_umem *umem)

释放使用 ib_umem_get 锁定的内存

参数

struct ib_umem *umem

要释放的 umem 结构体

struct ib_umem_odp *ib_umem_odp_alloc_implicit(struct ib_device *device, int access)

分配一个父级隐式 ODP umem

参数

struct ib_device *device

要创建 UMEM 的 IB 设备

int access

ib_reg_mr 访问标志

描述

隐式 ODP umem 没有 VA 范围,也没有任何页面列表。它们的存在只是为了保存 per_mm 引用,以帮助驱动程序创建子 umem。

struct ib_umem_odp *ib_umem_odp_alloc_child(struct ib_umem_odp *root, unsigned long addr, size_t size, const struct mmu_interval_notifier_ops *ops)

在隐式父 ODP umem 下分配子 ODP umem

参数

struct ib_umem_odp *root

包含子 umem 的父 umem。这必须使用 ib_alloc_implicit_odp_umem() 分配

unsigned long addr

起始用户空间 VA

size_t size

用户空间 VA 的长度

const struct mmu_interval_notifier_ops *ops

MMU 区间操作,当前仅 invalidate

struct ib_umem_odp *ib_umem_odp_get(struct ib_device *device, unsigned long addr, size_t size, int access, const struct mmu_interval_notifier_ops *ops)

为用户空间 va 创建 umem_odp

参数

struct ib_device *device

用于获取 UMEM 的 IB 设备结构体

unsigned long addr

用户空间起始虚拟地址

size_t size

要锁定的区域长度

int access

用于锁定内存的 IB_ACCESS_xxx 标志

const struct mmu_interval_notifier_ops *ops

MMU 区间操作,当前仅 invalidate

描述

当访问标志指示 ODP 内存时,驱动程序应使用它。它避免了锁定,而是存储 mm 以便将来结合 MMU 通知器进行页面错误处理。

int ib_umem_odp_map_dma_and_lock(struct ib_umem_odp *umem_odp, u64 user_virt, u64 bcnt, u64 access_mask, bool fault)

在 ODP MR 中映射 DMA 用户空间内存并锁定它。

参数

struct ib_umem_odp *umem_odp

要映射和固定的 umem

u64 user_virt

我们需要从中进行映射的地址。

u64 bcnt

要固定和映射的最小字节数。由于对齐,映射可能会更大,并且在固定或映射页面时发生错误的情况下也可能会更小。实际映射的页面在返回值中返回。

u64 access_mask

给定范围的请求访问权限的位掩码。

bool fault

给定范围是否需要缺页

描述

将参数中传递的范围映射到 DMA 地址。映射页面的 DMA 地址在 umem_odp->dma_list 中更新。成功后,ODP MR 将被锁定,以允许调用者完成其设备页表更新。

成功时返回映射的页数,失败时返回负错误代码。

RDMA Verbs 传输库

int rvt_fast_reg_mr(struct rvt_qp *qp, struct ib_mr *ibmr, u32 key, int access)

快速注册物理 MR

参数

struct rvt_qp *qp

工作请求来自的队列对

struct ib_mr *ibmr

要注册的内存区域

u32 key

此内存区域的更新键

int access

此内存区域的访问标志

描述

成功时返回 0。

int rvt_invalidate_rkey(struct rvt_qp *qp, u32 rkey)

使 MR rkey 无效

参数

struct rvt_qp *qp

与失效操作关联的队列对

u32 rkey

要失效的 rkey

描述

成功时返回 0。

int rvt_lkey_ok(struct rvt_lkey_table *rkt, struct rvt_pd *pd, struct rvt_sge *isge, struct rvt_sge *last_sge, struct ib_sge *sge, int acc)

检查 IB SGE 的有效性并初始化

参数

struct rvt_lkey_table *rkt

包含要检查 SGE 的 lkey 的表

struct rvt_pd *pd

保护域

struct rvt_sge *isge

传出的内部 SGE

struct rvt_sge *last_sge

写入的最后一个传出的 SGE

struct ib_sge *sge

要检查的 SGE

int acc

访问标志

描述

检查 IB SGE 的有效性并初始化我们的内部版本。

当存储新的 sge 时,增加引用计数。

返回值

如果已压缩则为 0,如果已添加则为 1,否则返回 -errno。

int rvt_rkey_ok(struct rvt_qp *qp, struct rvt_sge *sge, u32 len, u64 vaddr, u32 rkey, int acc)

检查 IB 虚拟地址、长度和 RKEY

参数

struct rvt_qp *qp

用于验证的 qp

struct rvt_sge *sge

SGE 状态

u32 len

数据长度

u64 vaddr

放置数据的虚拟地址

u32 rkey

要检查的 rkey

int acc

访问标志

返回值

如果成功则为 1,否则为 0。

描述

成功时增加引用计数

__be32 rvt_compute_aeth(struct rvt_qp *qp)

计算 AETH(综合症 + MSN)

参数

struct rvt_qp *qp

计算 AETH 的队列对

描述

返回 AETH。

void rvt_get_credit(struct rvt_qp *qp, u32 aeth)

刷新 QP 的发送工作队列

参数

struct rvt_qp *qp

要刷新其发送工作队列的 qp

u32 aeth

确认扩展传输标头

描述

应持有 QP s_lock。

u32 rvt_restart_sge(struct rvt_sge_state *ss, struct rvt_swqe *wqe, u32 len)

为 wqe 倒回 sge 状态

参数

struct rvt_sge_state *ss

sge 状态指针

struct rvt_swqe *wqe

要倒回的 wqe

u32 len

从 wqe 开始的数据长度(以字节为单位)

描述

返回剩余的数据长度。

int rvt_check_ah(struct ib_device *ibdev, struct rdma_ah_attr *ah_attr)

验证 AH 的属性

参数

struct ib_device *ibdev

ib 设备

struct rdma_ah_attr *ah_attr

AH 的属性

描述

如果驱动程序支持更详细的 check_ah 函数回调,则调用它,否则只检查基本信息。

返回值

成功时返回 0

struct rvt_dev_info *rvt_alloc_device(size_t size, int nports)

分配 rdi

参数

size_t size

要分配的结构的大小

int nports

要为其分配数组槽的端口数

描述

使用 IB 核心设备分配来为 rdi 分配空间,该空间被假定在 ib_device 内部。驱动程序所需的任何额外空间都应包含在大小中。

我们还根据端口数分配一个端口数组。

返回值

指向已分配 rdi 的指针

void rvt_dealloc_device(struct rvt_dev_info *rdi)

取消分配 rdi

参数

struct rvt_dev_info *rdi

要释放的结构

描述

释放使用 rvt_alloc_device() 分配的结构。

int rvt_register_device(struct rvt_dev_info *rdi)

注册一个驱动程序

参数

struct rvt_dev_info *rdi

所有 rdmavt 操作的主要设备结构

描述

驱动程序负责分配 rdi 并填写适当的信息。

返回值

成功时返回 0,否则返回错误码。

void rvt_unregister_device(struct rvt_dev_info *rdi)

移除一个驱动程序

参数

struct rvt_dev_info *rdi

rvt 设备结构

int rvt_init_port(struct rvt_dev_info *rdi, struct rvt_ibport *port, int port_index, u16 *pkey_table)

初始化驱动程序端口的内部数据

参数

struct rvt_dev_info *rdi

rvt_dev_info 结构体

struct rvt_ibport *port

rvt 端口

int port_index

基于 0 的端口索引,与 IB 核心端口号不同

u16 *pkey_table

端口的 pkey_table

描述

跟踪端口列表。无需分离端口。它们会一直存在,直到驱动程序消失。

返回值

始终为 0

bool rvt_cq_enter(struct rvt_cq *cq, struct ib_wc *entry, bool solicited)

向完成队列添加新条目

参数

struct rvt_cq *cq

完成队列

struct ib_wc *entry

要添加的工作完成条目

bool solicited

如果 entry 是请求的,则为 true

描述

这可以在持有 qp->s_lock 的情况下调用。

返回值

成功返回 true,如果 cq 已满,则返回 false。

int rvt_error_qp(struct rvt_qp *qp, enum ib_wc_status err)

将 QP 置于错误状态

参数

struct rvt_qp *qp

要置于错误状态的 QP

enum ib_wc_status err

如果 RWQE 处于活动状态,则要发送的接收完成错误信号

描述

刷新发送和接收工作队列。

返回值

如果应该生成最后一个 WQE 事件,则为 true。应该持有 QP 的 r_lock 和 s_lock,并禁用中断。如果我们已经处于错误状态,则直接返回。

int rvt_get_rwqe(struct rvt_qp *qp, bool wr_id_only)

将下一个 RWQE 复制到 QP 的 RWQE 中

参数

struct rvt_qp *qp

QP

bool wr_id_only

仅更新 qp->r_wr_id,而不是 qp->r_sge

描述

如果存在本地错误,则返回 -1;如果没有 RWQE 可用,则返回 0;否则返回 1。

可以从中断级别调用。

void rvt_comm_est(struct rvt_qp *qp)

处理已建立 QP 的陷阱

参数

struct rvt_qp *qp

QP

void rvt_add_rnr_timer(struct rvt_qp *qp, u32 aeth)

在 QP 上添加/启动一个 rnr 计时器

参数

struct rvt_qp *qp

QP

u32 aeth

RNR 超时的 aeth,用于环回的模拟 aeth

void rvt_stop_rc_timers(struct rvt_qp *qp)

停止所有计时器

参数

struct rvt_qp *qp

QP 停止所有挂起的计时器

void rvt_del_timers_sync(struct rvt_qp *qp)

等待任何超时例程退出

参数

struct rvt_qp *qp

QP

struct rvt_qp_iter *rvt_qp_iter_init(struct rvt_dev_info *rdi, u64 v, void (*cb)(struct rvt_qp *qp, u64 v))

用于 QP 迭代的初始化

参数

struct rvt_dev_info *rdi

rvt 设备信息

u64 v

u64 值

void (*cb)(struct rvt_qp *qp, u64 v)

用户定义的回调

描述

这会返回一个适合在系统中迭代 QP 的迭代器。

cb 是用户定义的回调,v 是一个 64 位值,传递给 cb 并用于其中的处理。一个示例用例是根据不属于 rvt_qp 的条件更改 QP 处理。

需要内存分配成功的用例必须预先分配适当的内存。

返回值

指向 rvt_qp_iter 的指针,如果失败则为 NULL

int rvt_qp_iter_next(struct rvt_qp_iter *iter)

返回 iter 中的下一个 QP

参数

struct rvt_qp_iter *iter

迭代器

描述

细粒度的 QP 迭代器,适合与 debugfs seq_file 机制一起使用。

当返回值为 0 时,使用当前 QP 更新 iter->qp。

返回值

0 - iter->qp 有效 1 - 没有更多 QP

void rvt_qp_iter(struct rvt_dev_info *rdi, u64 v, void (*cb)(struct rvt_qp *qp, u64 v))

迭代所有 QP

参数

struct rvt_dev_info *rdi

rvt 设备信息

u64 v

一个 64 位值

void (*cb)(struct rvt_qp *qp, u64 v)

一个回调

描述

这提供了一种迭代所有 QP 的方法。

cb 是用户定义的回调函数,v 是一个 64 位的值,传递给回调函数并在其中处理。一个典型的用例是根据非 rvt_qp 的标准来更改 QP 处理。

代码有一个内部迭代器来简化非 seq_file 用例。

void rvt_copy_sge(struct rvt_qp *qp, struct rvt_sge_state *ss, void *data, u32 length, bool release, bool copy_last)

将数据复制到 SGE 内存

参数

struct rvt_qp *qp

关联的 QP

struct rvt_sge_state *ss

SGE 状态

void *data

要复制的数据

u32 length

数据的长度

bool release

释放 MR 的布尔值

bool copy_last

单独复制最后 8 个字节

void rvt_ruc_loopback(struct rvt_qp *sqp)

处理 UC 和 RC 回环请求

参数

struct rvt_qp *sqp

发送 QP

描述

这是从 rvt_do_send() 调用的,用于转发寻址到同一 HFI 的 WQE。请注意,尽管由于发送引擎,我们是单线程的,但我们仍然必须防止 post_send()。我们不必担心接收中断,因为这是一个连接的协议,所有数据包都将通过这里。

struct rvt_mcast *rvt_mcast_find(struct rvt_ibport *ibp, union ib_gid *mgid, u16 lid)

在全局表中搜索给定的多播 GID/LID

参数

struct rvt_ibport *ibp

IB 端口结构

union ib_gid *mgid

要搜索的多播 GID

u16 lid

多播地址的多播 LID 部分(主机字节序)

注意

具有多个 MGID 的 1 个 MLID 是有效的。具有多个 MLID 的 1 个 MGID 是无效的。

描述

如果找到,调用者负责递减引用计数。

返回值

如果未找到,则为 NULL。

上层协议

RDMA 的 iSCSI 扩展 (iSER)

struct iser_data_buf

iSER 数据缓冲区

定义:

struct iser_data_buf {
    struct scatterlist *sg;
    int size;
    unsigned long      data_len;
    int dma_nents;
};

成员

sg

指向 sg 列表的指针

size

此 sg 的条目数

data_len

缓冲区字节总长度

dma_nents

由 dma_map_sg 返回

struct iser_mem_reg

iSER 内存注册信息

定义:

struct iser_mem_reg {
    struct ib_sge sge;
    u32 rkey;
    struct iser_fr_desc *desc;
};

成员

sge

内存区域 sg 元素

rkey

内存区域远程密钥

desc

指向快速注册上下文的指针

struct iser_tx_desc

iSER TX 描述符

定义:

struct iser_tx_desc {
    struct iser_ctrl             iser_header;
    struct iscsi_hdr             iscsi_header;
    enum iser_desc_type        type;
    u64 dma_addr;
    struct ib_sge                tx_sg[2];
    int num_sge;
    struct ib_cqe                cqe;
    bool mapped;
    struct ib_reg_wr             reg_wr;
    struct ib_send_wr            send_wr;
    struct ib_send_wr            inv_wr;
};

成员

iser_header

iser 标头

iscsi_header

iscsi 标头

type

命令/控制/数据输出

dma_addr

标头缓冲区 dma 地址

tx_sg

sg[0] 指向 iser/iscsi 标头,sg[1] 可选地指向立即数据、未请求的数据输出或控制

num_sge

此 TX 任务上使用的 sge 数量

cqe

完成处理程序

mapped

任务标头是否已映射

reg_wr

注册 WR

send_wr

发送 WR

inv_wr

无效 WR

struct iser_rx_desc

iSER RX 描述符

定义:

struct iser_rx_desc {
    struct iser_ctrl             iser_header;
    struct iscsi_hdr             iscsi_header;
    char data[ISER_RECV_DATA_SEG_LEN];
    u64 dma_addr;
    struct ib_sge                rx_sg;
    struct ib_cqe                cqe;
    char pad[ISER_RX_PAD_SIZE];
};

成员

iser_header

iser 标头

iscsi_header

iscsi 标头

data

接收到的数据段

dma_addr

接收缓冲区 dma 地址

rx_sg

接收缓冲区的 ib_sge

cqe

完成处理程序

pad

用于感知数据 TODO:修改为支持的最大感知长度

struct iser_login_desc

iSER 登录描述符

定义:

struct iser_login_desc {
    void *req;
    void *rsp;
    u64 req_dma;
    u64 rsp_dma;
    struct ib_sge                sge;
    struct ib_cqe                cqe;
};

成员

req

指向登录请求缓冲区的指针

rsp

指向登录响应缓冲区的指针

req_dma

登录请求缓冲区的 DMA 地址

rsp_dma

登录响应缓冲区的 DMA 地址

sge

用于登录后接收的 IB sge

cqe

完成处理程序

struct iser_device

iSER 设备句柄

定义:

struct iser_device {
    struct ib_device             *ib_device;
    struct ib_pd                 *pd;
    struct ib_event_handler      event_handler;
    struct list_head             ig_list;
    int refcount;
};

成员

ib_device

RDMA 设备

pd

此设备的保护域

event_handler

IB 事件处理例程

ig_list

设备列表中的条目

refcount

引用计数器,由打开的 iser 连接控制

struct iser_reg_resources

快速注册资源

定义:

struct iser_reg_resources {
    struct ib_mr                     *mr;
    struct ib_mr                     *sig_mr;
};

成员

mr

内存区域

sig_mr

签名内存区域

struct iser_fr_desc

快速注册描述符

定义:

struct iser_fr_desc {
    struct list_head                  list;
    struct iser_reg_resources         rsc;
    bool sig_protected;
    struct list_head                  all_list;
};

成员

list

连接 fastreg 池中的条目

rsc

数据缓冲区注册资源

sig_protected

区域是否受保护的指示符

all_list

第一个和最后一个列表成员

struct iser_fr_pool

连接快速注册池

定义:

struct iser_fr_pool {
    struct list_head        list;
    spinlock_t lock;
    int size;
    struct list_head        all_list;
};

成员

list

fastreg 描述符列表

lock

保护 fastreg 池

size

池的大小

all_list

第一个和最后一个列表成员

struct ib_conn

Infiniband 相关对象

定义:

struct ib_conn {
    struct rdma_cm_id           *cma_id;
    struct ib_qp                *qp;
    struct ib_cq                *cq;
    u32 cq_size;
    struct iser_device          *device;
    struct iser_fr_pool          fr_pool;
    bool pi_support;
    struct ib_cqe                reg_cqe;
};

成员

cma_id

rdma_cm 连接管理器句柄

qp

连接队列对

cq

连接完成队列

cq_size

最大未完成完成的数量

device

iser 设备的引用

fr_pool

连接快速注册池

pi_support

指示设备 T10-PI 支持

reg_cqe

完成处理程序

struct iser_conn

iSER 连接上下文

定义:

struct iser_conn {
    struct ib_conn               ib_conn;
    struct iscsi_conn            *iscsi_conn;
    struct iscsi_endpoint        *ep;
    enum iser_conn_state         state;
    unsigned qp_max_recv_dtos;
    u16 max_cmds;
    char name[ISER_OBJECT_NAME_SIZE];
    struct work_struct           release_work;
    struct mutex                 state_mutex;
    struct completion            stop_completion;
    struct completion            ib_completion;
    struct completion            up_completion;
    struct list_head             conn_list;
    struct iser_login_desc       login_desc;
    struct iser_rx_desc          *rx_descs;
    u32 num_rx_descs;
    unsigned short               scsi_sg_tablesize;
    unsigned short               pages_per_mr;
    bool snd_w_inv;
};

成员

ib_conn

连接 RDMA 资源

iscsi_conn

指向匹配 iscsi 连接的链接

ep

传输句柄

state

连接逻辑状态

qp_max_recv_dtos

最大数据输出数,对应于最大后接收数

max_cmds

此连接允许的最大命令数

name

连接对等门户

release_work

用于释放作业的延迟工作

state_mutex

保护 iser 连接状态

stop_completion

conn_stop 完成

ib_completion

RDMA 清理完成

up_completion

连接建立完成(状态为 ISER_CONN_UP)

conn_list

ig 连接列表中的条目

login_desc

登录描述符

rx_descs

rx 缓冲区数组(循环缓冲区)

num_rx_descs

rx 描述符的数量

scsi_sg_tablesize

scsi 主机 sg_tablesize

pages_per_mr

可用于注册的最大页数

snd_w_inv

连接使用远程无效

struct iscsi_iser_task

iser 任务上下文

定义:

struct iscsi_iser_task {
    struct iser_tx_desc          desc;
    struct iser_conn             *iser_conn;
    enum iser_task_status        status;
    struct scsi_cmnd             *sc;
    int command_sent;
    int dir[ISER_DIRS_NUM];
    struct iser_mem_reg          rdma_reg[ISER_DIRS_NUM];
    struct iser_data_buf         data[ISER_DIRS_NUM];
    struct iser_data_buf         prot[ISER_DIRS_NUM];
};

成员

desc

TX 描述符

iser_conn

链接到 iser 连接

status

当前任务状态

sc

链接到 scsi 命令

command_sent

指示是否已发送命令

dir

iser 数据方向

rdma_reg

任务 rdma 注册描述

data

iser 数据缓冲区描述

prot

iser 保护缓冲区描述

struct iser_global

iSER 全局上下文

定义:

struct iser_global {
    struct mutex      device_list_mutex;
    struct list_head  device_list;
    struct mutex      connlist_mutex;
    struct list_head  connlist;
    struct kmem_cache *desc_cache;
};

成员

device_list_mutex

保护 device_list

device_list

iSER 设备全局列表

connlist_mutex

保护 connlist

connlist

iSER 连接全局列表

desc_cache

用于 tx dataout 的 kmem 缓存

int iscsi_iser_pdu_alloc(struct iscsi_task *task, uint8_t opcode)

分配一个 iscsi-iser PDU

参数

struct iscsi_task *task

iSCSI 任务

uint8_t opcode

iSCSI 命令操作码

描述

注意:此例程不会失败,只会分配 iSCSI 任务

hdr 和最大 hdr 大小。

int iser_initialize_task_headers(struct iscsi_task *task, struct iser_tx_desc *tx_desc)

初始化任务头

参数

struct iscsi_task *task

iSCSI 任务

struct iser_tx_desc *tx_desc

iSER tx 描述符

备注

此例程可能会与用于 SCSI 错误处理 TMF 的 iSER 拆卸流程竞争。因此,对于 TMF,我们应该获取状态互斥锁,以避免取消引用可能已终止的 IB 设备。

int iscsi_iser_task_init(struct iscsi_task *task)

初始化 iSCSI-iSER 任务

参数

struct iscsi_task *task

iSCSI 任务

描述

为 SCSI 命令或管理命令初始化任务。

返回值

成功时返回零,失败时返回 -ENOMEM

初始化任务头(DMA 映射错误)。

int iscsi_iser_mtask_xmit(struct iscsi_conn *conn, struct iscsi_task *task)

发送管理(即时)任务

参数

struct iscsi_conn *conn

iSCSI 连接

struct iscsi_task *task

任务管理任务

备注

该函数可以返回 -EAGAIN,在这种情况下,调用方必须稍后再次调用它或恢复。'0' 返回代码表示成功发送。

int iscsi_iser_task_xmit(struct iscsi_task *task)

发送 iSCSI-iSER 任务

参数

struct iscsi_task *task

iSCSI 任务

返回值

成功时为零,失败时为 $error。

void iscsi_iser_cleanup_task(struct iscsi_task *task)

清理 iSCSI-iSER 任务

参数

struct iscsi_task *task

iSCSI 任务

备注

如果 RDMA 设备已为 NULL(可能已在

DEVICE_REMOVAL CM 事件中删除),它将退出而不进行 DMA 取消映射。

u8 iscsi_iser_check_protection(struct iscsi_task *task, sector_t *sector)

检查任务的保护信息状态。

参数

struct iscsi_task *task

iSCSI 任务

sector_t *sector

错误扇区(如果存在)(输出)

返回值

如果没有发生数据完整性错误,则为零

0x1:保护块中发生数据完整性错误 0x2:引用标记中发生数据完整性错误 0x3:应用程序标记中发生数据完整性错误

此外,会标记错误扇区。

struct iscsi_cls_conn *iscsi_iser_conn_create(struct iscsi_cls_session *cls_session, uint32_t conn_idx)

创建新的 iSCSI-iSER 连接

参数

struct iscsi_cls_session *cls_session

iSCSI 类连接

uint32_t conn_idx

会话内的连接索引(用于 MCS)

返回值

如果 iscsi_conn_setup 成功,则为 iscsi_cls_conn,否则为 NULL。

否则。

int iscsi_iser_conn_bind(struct iscsi_cls_session *cls_session, struct iscsi_cls_conn *cls_conn, uint64_t transport_eph, int is_leading)

绑定 iSCSI 和 iSER 连接结构

参数

struct iscsi_cls_session *cls_session

iSCSI 类会话

struct iscsi_cls_conn *cls_conn

iSCSI 类连接

uint64_t transport_eph

传输端点句柄

int is_leading

指示这是否是会话主导连接 (MCS)

返回值

成功时为零,如果 iscsi_conn_bind 失败,则为 $error,并且

如果端点不再存在或者 iSER 连接状态不是 UP(已开始拆卸),则为 -EINVAL。

int iscsi_iser_conn_start(struct iscsi_cls_conn *cls_conn)

启动 iSCSI-iSER 连接

参数

struct iscsi_cls_conn *cls_conn

iSCSI 类连接

备注

此处 iSER 初始化(或重新初始化)stop_completion,因为

从这一点开始,iSCSI 必须在会话/连接拆卸中调用 conn_stop,因此 iSER 传输必须等待它。

void iscsi_iser_conn_stop(struct iscsi_cls_conn *cls_conn, int flag)

停止 iSCSI-iSER 连接

参数

struct iscsi_cls_conn *cls_conn

iSCSI 类连接

int flag

指示是否恢复或终止(按原样传递)

备注

调用 iscsi_conn_stop 理论上可能会与

DEVICE_REMOVAL 事件竞争并取消引用先前释放的 RDMA 设备句柄,因此我们在 iSER 状态锁下调用它以防止此类竞争。

void iscsi_iser_session_destroy(struct iscsi_cls_session *cls_session)

销毁 iSCSI-iSER 会话

参数

struct iscsi_cls_session *cls_session

iSCSI 类会话

描述

删除并释放 iSCSI 主机。

struct iscsi_cls_session *iscsi_iser_session_create(struct iscsi_endpoint *ep, uint16_t cmds_max, uint16_t qdepth, uint32_t initial_cmdsn)

创建 iSCSI-iSER 会话

参数

struct iscsi_endpoint *ep

iSCSI 端点句柄

uint16_t cmds_max

此会话中的最大命令数

uint16_t qdepth

会话命令队列深度

uint32_t initial_cmdsn

启动器命令序列号

描述

分配并添加 SCSI 主机,如果存在则公开 DIF 支持,并设置 iSCSI 会话。

struct iscsi_endpoint *iscsi_iser_ep_connect(struct Scsi_Host *shost, struct sockaddr *dst_addr, int non_blocking)

启动 iSER 连接建立

参数

struct Scsi_Host *shost

scsi_host

struct sockaddr *dst_addr

目标地址

int non_blocking

指示例程是否可以阻塞

描述

分配一个 iscsi 端点、一个 iser_conn 结构并将它们绑定。之后,通过 rdma_cm 启动 RDMA 连接建立。我们不分配嵌入在 iscsi_endpoint 中的 iser_conn,因为在拆除时,端点将在 ep_disconnect 时销毁,而 iser_conn 将异步清理其资源。

返回值

iscsi 层创建的 iscsi_endpoint 或 ERR_PTR(error)

如果失败。

int iscsi_iser_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)

轮询以完成 iser 连接建立

参数

struct iscsi_endpoint *ep

iscsi 端点(在 ep_connect 时创建)

int timeout_ms

允许的轮询超时时间(毫秒)。

描述

此例程归结为等待 up_completion 发出 cma_id 获取 CONNECTED 事件的信号。

返回值

如果连接建立成功则为 1,如果超时过期则为 0

(libiscsi 将重试)或者如果被信号中断,或者更可能是 iser 连接状态在等待期间转换为 TEMINATING 或 DOWN,则为 -1。

void iscsi_iser_ep_disconnect(struct iscsi_endpoint *ep)

启动连接拆除过程

参数

struct iscsi_endpoint *ep

iscsi 端点句柄

描述

此例程不会被 iser 和 RDMA 终止过程的完成所阻塞,因为我们为 iser/RDMA 销毁和清理排队了一个延迟工作,或者实际上在我们没有通过 iscsi 连接绑定/启动阶段的情况下立即调用它,因此它是安全的。

int iser_send_command(struct iscsi_conn *conn, struct iscsi_task *task)

发送命令 PDU

参数

struct iscsi_conn *conn

指向匹配 iscsi 连接的链接

struct iscsi_task *task

SCSI 命令任务

int iser_send_data_out(struct iscsi_conn *conn, struct iscsi_task *task, struct iscsi_data *hdr)

发送数据输出 PDU

参数

struct iscsi_conn *conn

指向匹配 iscsi 连接的链接

struct iscsi_task *task

SCSI 命令任务

struct iscsi_data *hdr

指向 LLD 的 iSCSI 消息头的指针

int iser_alloc_fastreg_pool(struct ib_conn *ib_conn, unsigned cmds_max, unsigned int size)

创建用于快速注册工作请求的 fast_reg 描述符池。

参数

struct ib_conn *ib_conn

连接 RDMA 资源

unsigned cmds_max

此连接的最大 SCSI 命令数

unsigned int size

每个映射请求的最大页数

返回值

成功时为 0,失败时为 errno 代码

void iser_free_fastreg_pool(struct ib_conn *ib_conn)

释放 fast_reg 描述符池

参数

struct ib_conn *ib_conn

连接 RDMA 资源

void iser_free_ib_conn_res(struct iser_conn *iser_conn, bool destroy)

释放 IB 相关资源

参数

struct iser_conn *iser_conn

iser 连接结构体

bool destroy

指示符,指示我们是否需要尝试释放 iser 设备和内存区域池(只有 iscsi 关闭和 DEVICE_REMOVAL 会使用它)。

描述

此例程是在持有 iser 状态互斥锁的情况下调用的,因此 cm_id 的移除不在此处。多次调用是安全的。

void iser_conn_release(struct iser_conn *iser_conn)

释放所有 conn 对象并释放 conn 描述符

参数

struct iser_conn *iser_conn

iSER 连接上下文

int iser_conn_terminate(struct iser_conn *iser_conn)

触发断开连接过程的开始,并等待它们完成

参数

struct iser_conn *iser_conn

iSER 连接上下文

描述

使用持有的状态互斥锁调用

int iser_post_send(struct ib_conn *ib_conn, struct iser_tx_desc *tx_desc)

启动发送 DTO 操作

参数

struct ib_conn *ib_conn

连接 RDMA 资源

struct iser_tx_desc *tx_desc

iSER TX 描述符

返回值

成功时为 0,失败时为 -1

Omni-Path (OPA) 虚拟网卡支持

struct opa_vnic_ctrl_port

OPA 虚拟网卡控制端口

定义:

struct opa_vnic_ctrl_port {
    struct ib_device           *ibdev;
    struct opa_vnic_ctrl_ops   *ops;
    u8 num_ports;
};

成员

ibdev

指向 ib 设备的指针

ops

opa vnic 控制操作

num_ports

opa 端口数

struct opa_vnic_adapter

OPA VNIC netdev 私有数据结构

定义:

struct opa_vnic_adapter {
    struct net_device             *netdev;
    struct ib_device              *ibdev;
    struct opa_vnic_ctrl_port     *cport;
    const struct net_device_ops   *rn_ops;
    u8 port_num;
    u8 vport_num;
    struct mutex lock;
    struct __opa_veswport_info  info;
    u8 vema_mac_addr[ETH_ALEN];
    u32 umac_hash;
    u32 mmac_hash;
    struct hlist_head  __rcu   *mactbl;
    struct mutex mactbl_lock;
    spinlock_t stats_lock;
    u8 flow_tbl[OPA_VNIC_FLOW_TBL_SIZE];
    unsigned long trap_timeout;
    u8 trap_count;
};

成员

netdev

指向关联的 netdev 的指针

ibdev

ib 设备

cport

指向 opa vnic 控制端口的指针

rn_ops

rdma netdev 的 net_device_ops

port_num

OPA 端口号

vport_num

vesw 端口号

lock

适配器锁

info

虚拟以太网交换机端口信息

vema_mac_addr

由 vema 配置的 MAC 地址

umac_hash

单播 MAC 列表哈希

mmac_hash

多播 MAC 列表哈希

mactbl

MAC 条目的哈希表

mactbl_lock

MAC 表锁

stats_lock

统计锁

flow_tbl

到默认端口重定向表的流

trap_timeout

陷阱超时

trap_count

在超时期间允许的陷阱数

struct opa_vnic_mac_tbl_node

OPA VNIC MAC 表节点

定义:

struct opa_vnic_mac_tbl_node {
    struct hlist_node                    hlist;
    u16 index;
    struct __opa_vnic_mactable_entry     entry;
};

成员

hlist

哈希列表句柄

index

MAC 表中条目的索引

entry

表中的条目

struct opa_vesw_info

OPA vnic 交换机信息

定义:

struct opa_vesw_info {
    __be16 fabric_id;
    __be16 vesw_id;
    u8 rsvd0[6];
    __be16 def_port_mask;
    u8 rsvd1[2];
    __be16 pkey;
    u8 rsvd2[4];
    __be32 u_mcast_dlid;
    __be32 u_ucast_dlid[OPA_VESW_MAX_NUM_DEF_PORT];
    __be32 rc;
    u8 rsvd3[56];
    __be16 eth_mtu;
    u8 rsvd4[2];
};

成员

fabric_id

10 位 Fabric ID

vesw_id

12 位虚拟以太网交换机 ID

rsvd0

保留字节

def_port_mask

默认端口的位掩码

rsvd1

保留字节

pkey

分区密钥

rsvd2

保留字节

u_mcast_dlid

未知组播 DLID

u_ucast_dlid

未知单播 DLID 数组

rc

路由控制

rsvd3

保留字节

eth_mtu

以太网 MTU

rsvd4

保留字节

struct opa_per_veswport_info

OPA vnic 每个端口的信息

定义:

struct opa_per_veswport_info {
    __be32 port_num;
    u8 eth_link_status;
    u8 rsvd0[3];
    u8 base_mac_addr[ETH_ALEN];
    u8 config_state;
    u8 oper_state;
    __be16 max_mac_tbl_ent;
    __be16 max_smac_ent;
    __be32 mac_tbl_digest;
    u8 rsvd1[4];
    __be32 encap_slid;
    u8 pcp_to_sc_uc[OPA_VNIC_MAX_NUM_PCP];
    u8 pcp_to_vl_uc[OPA_VNIC_MAX_NUM_PCP];
    u8 pcp_to_sc_mc[OPA_VNIC_MAX_NUM_PCP];
    u8 pcp_to_vl_mc[OPA_VNIC_MAX_NUM_PCP];
    u8 non_vlan_sc_uc;
    u8 non_vlan_vl_uc;
    u8 non_vlan_sc_mc;
    u8 non_vlan_vl_mc;
    u8 rsvd2[48];
    __be16 uc_macs_gen_count;
    __be16 mc_macs_gen_count;
    u8 rsvd3[8];
};

成员

port_num

端口号

eth_link_status

当前的以太网链路状态

rsvd0

保留字节

base_mac_addr

基本 MAC 地址

config_state

已配置的端口状态

oper_state

操作端口状态

max_mac_tbl_ent

最大 MAC 表条目数

max_smac_ent

MAC 表中的最大 SMAC 条目数

mac_tbl_digest

MAC 表摘要

rsvd1

保留字节

encap_slid

端口的基本 SLID

pcp_to_sc_uc

单播以太网数据包的按 PCP 索引的 SC

pcp_to_vl_uc

单播以太网数据包的按 PCP 索引的 VL

pcp_to_sc_mc

组播以太网数据包的按 PCP 索引的 SC

pcp_to_vl_mc

组播以太网数据包的按 PCP 索引的 VL

non_vlan_sc_uc

非 VLAN 单播以太网数据包的 SC

non_vlan_vl_uc

非 VLAN 单播以太网数据包的 VL

non_vlan_sc_mc

非 VLAN 组播以太网数据包的 SC

non_vlan_vl_mc

非 VLAN 组播以太网数据包的 VL

rsvd2

保留字节

uc_macs_gen_count

单播 MAC 列表的生成计数

mc_macs_gen_count

组播 MAC 列表的生成计数

rsvd3

保留字节

struct opa_veswport_info

OPA vnic 端口信息

定义:

struct opa_veswport_info {
    struct opa_vesw_info          vesw;
    struct opa_per_veswport_info  vport;
};

成员

vesw

OPA vnic 交换机信息

vport

OPA vnic 每个端口的信息

描述

在主机上,每个虚拟以太网端口都属于不同的虚拟以太网交换机。

struct opa_veswport_mactable_entry

转发表中的单个条目

定义:

struct opa_veswport_mactable_entry {
    u8 mac_addr[ETH_ALEN];
    u8 mac_addr_mask[ETH_ALEN];
    __be32 dlid_sd;
};

成员

mac_addr

MAC 地址

mac_addr_mask

MAC 地址位掩码

dlid_sd

匹配的 DLID 和边数据

描述

在主机上,每个虚拟以太网端口都有一个转发表。这些表用于将 MAC 映射到 LID 和其他数据。有关更多详细信息,请参阅结构 opa_veswport_mactable_entries。这是单个 mactable 条目的结构

struct opa_veswport_mactable

转发表数组

定义:

struct opa_veswport_mactable {
    __be16 offset;
    __be16 num_entries;
    __be32 mac_tbl_digest;
    struct opa_veswport_mactable_entry  tbl_entries[];
};

成员

offset

MAC 表起始偏移量

num_entries

要获取或设置的条目数

mac_tbl_digest

MAC 表摘要

tbl_entries

表条目数组

描述

EM 在 MAD 中发送此结构,指示此条目要加载到的转发表的起始偏移量以及此 MAD 实例包含的条目数。mac_tbl_digest 已添加到此 MAD 结构中。它将由 EM 设置,EM 将使用它来检查此值与 EM 在删除或卸载 VNIC 端口的情况下维护的值之间是否存在任何差异。VNIC 的新实例始终具有零值。此值作为 vnic 适配器结构的一部分存储,并且将由 mactable 条目和 veswport 信息的 GET 和 SET 例程访问。

struct opa_veswport_summary_counters

汇总计数器

定义:

struct opa_veswport_summary_counters {
    __be16 vp_instance;
    __be16 vesw_id;
    __be32 veswport_num;
    __be64 tx_errors;
    __be64 rx_errors;
    __be64 tx_packets;
    __be64 rx_packets;
    __be64 tx_bytes;
    __be64 rx_bytes;
    __be64 tx_unicast;
    __be64 tx_mcastbcast;
    __be64 tx_untagged;
    __be64 tx_vlan;
    __be64 tx_64_size;
    __be64 tx_65_127;
    __be64 tx_128_255;
    __be64 tx_256_511;
    __be64 tx_512_1023;
    __be64 tx_1024_1518;
    __be64 tx_1519_max;
    __be64 rx_unicast;
    __be64 rx_mcastbcast;
    __be64 rx_untagged;
    __be64 rx_vlan;
    __be64 rx_64_size;
    __be64 rx_65_127;
    __be64 rx_128_255;
    __be64 rx_256_511;
    __be64 rx_512_1023;
    __be64 rx_1024_1518;
    __be64 rx_1519_max;
    __be64 reserved[16];
};

成员

vp_instance

OPA 端口上的 vport 实例

vesw_id

虚拟以太网交换机 ID

veswport_num

虚拟以太网交换机端口号

tx_errors

传输错误

rx_errors

接收错误

tx_packets

传输的数据包

rx_packets

接收的数据包

tx_bytes

传输的字节数

rx_bytes

接收的字节数

tx_unicast

传输的单播数据包

tx_mcastbcast

传输的组播/广播数据包

tx_untagged

传输的非 VLAN 数据包

tx_vlan

传输的 VLAN 数据包

tx_64_size

传输的数据包长度为 64 字节

tx_65_127

传输的数据包长度为 >=65 且 < 127 字节

tx_128_255

传输的数据包长度为 >=128 且 < 255 字节

tx_256_511

传输的数据包长度为 >=256 且 < 511 字节

tx_512_1023

传输的数据包长度为 >=512 且 < 1023 字节

tx_1024_1518

传输的数据包长度为 >=1024 且 < 1518 字节

tx_1519_max

传输的数据包长度 >= 1519 字节

rx_unicast

接收的单播数据包

rx_mcastbcast

接收的组播/广播数据包

rx_untagged

接收的非 VLAN 数据包

rx_vlan

接收的 VLAN 数据包

rx_64_size

接收的数据包长度为 64 字节

rx_65_127

接收的数据包长度为 >=65 且 < 127 字节

rx_128_255

接收的数据包长度为 >=128 且 < 255 字节

rx_256_511

接收的数据包长度为 >=256 且 < 511 字节

rx_512_1023

接收的数据包长度为 >=512 且 < 1023 字节

rx_1024_1518

接收的数据包长度为 >=1024 且 < 1518 字节

rx_1519_max

接收的数据包长度 >= 1519 字节

reserved

保留字节

描述

以上所有都是相应条件的计数器。

struct opa_veswport_error_counters

错误计数器

定义:

struct opa_veswport_error_counters {
    __be16 vp_instance;
    __be16 vesw_id;
    __be32 veswport_num;
    __be64 tx_errors;
    __be64 rx_errors;
    __be64 rsvd0;
    __be64 tx_smac_filt;
    __be64 rsvd1;
    __be64 rsvd2;
    __be64 rsvd3;
    __be64 tx_dlid_zero;
    __be64 rsvd4;
    __be64 tx_logic;
    __be64 rsvd5;
    __be64 tx_drop_state;
    __be64 rx_bad_veswid;
    __be64 rsvd6;
    __be64 rx_runt;
    __be64 rx_oversize;
    __be64 rsvd7;
    __be64 rx_eth_down;
    __be64 rx_drop_state;
    __be64 rx_logic;
    __be64 rsvd8;
    __be64 rsvd9[16];
};

成员

vp_instance

OPA 端口上的 vport 实例

vesw_id

虚拟以太网交换机 ID

veswport_num

虚拟以太网交换机端口号

tx_errors

传输错误

rx_errors

接收错误

rsvd0

保留字节

tx_smac_filt

SMAC 筛选错误

rsvd1

保留字节

rsvd2

保留字节

rsvd3

保留字节

tx_dlid_zero

传输带有无效 DLID 的数据包

rsvd4

保留字节

tx_logic

其他传输错误

rsvd5

保留字节

tx_drop_state

在非转发端口状态下进行的数据包传输

rx_bad_veswid

接收带有无效 vesw id 的数据包

rsvd6

保留字节

rx_runt

接收的以太网数据包长度 < 64 字节

rx_oversize

接收的以太网数据包长度 > MTU 大小

rsvd7

保留字节

rx_eth_down

当接口关闭时接收的数据包

rx_drop_state

在非转发端口状态下接收的数据包

rx_logic

其他接收错误

rsvd8

保留字节

rsvd9

保留字节

描述

以上所有都是相应错误条件的计数器。

struct opa_veswport_trap

VNIC 发送到 EM 的陷阱消息

定义:

struct opa_veswport_trap {
    __be16 fabric_id;
    __be16 veswid;
    __be32 veswportnum;
    __be16 opaportnum;
    u8 veswportindex;
    u8 opcode;
    __be32 reserved;
};

成员

fabric_id

10 位 Fabric ID

veswid

12 位虚拟以太网交换机 ID

veswportnum

虚拟交换机上的逻辑端口号

opaportnum

物理端口号(在主机上是冗余的)

veswportindex

基于 0 的 OPA 端口上的交换机端口索引

opcode

操作

reserved

用于对齐的 32 位

描述

VNIC 将向以太网管理器发送陷阱消息,以通知它 VNIC 配置、行为等的更改。这是陷阱有效负载的格式。

struct opa_vnic_iface_mac_entry

MAC 列表中的单个条目

定义:

struct opa_vnic_iface_mac_entry {
    u8 mac_addr[ETH_ALEN];
};

成员

mac_addr

MAC 地址

struct opa_veswport_iface_macs

用于设置全局管理的 MAC 的消息

定义:

struct opa_veswport_iface_macs {
    __be16 start_idx;
    __be16 num_macs_in_msg;
    __be16 tot_macs_in_lst;
    __be16 gen_count;
    struct opa_vnic_iface_mac_entry entry[];
};

成员

start_idx

第一个条目的位置(基于 0)

num_macs_in_msg

此消息中的 MAC 数

tot_macs_in_lst

代理拥有的 MAC 总数

gen_count

指示更改的 gen_count

entry

MAC 列表条目

描述

与用于设置全局管理的地址的本地管理的地址中的属性 ID 和属性修饰符相同

struct opa_vnic_vema_mad

通用 VEMA MAD

定义:

struct opa_vnic_vema_mad {
    struct ib_mad_hdr  mad_hdr;
    struct ib_rmpp_hdr rmpp_hdr;
    u8 reserved;
    u8 oui[3];
    u8 data[OPA_VNIC_EMA_DATA];
};

成员

mad_hdr

通用 MAD 标头

rmpp_hdr

特定于供应商的 MAD 的 RMPP 标头

reserved

保留字节

oui

唯一组织标识符

data

MAD 数据

struct opa_vnic_notice_attr

通用通知 MAD

定义:

struct opa_vnic_notice_attr {
    u8 gen_type;
    u8 oui_1;
    u8 oui_2;
    u8 oui_3;
    __be16 trap_num;
    __be16 toggle_count;
    __be32 issuer_lid;
    __be32 reserved;
    u8 issuer_gid[16];
    u8 raw_data[64];
};

成员

gen_type

通用/特定位和通知类型

oui_1

供应商 ID 字节 1

oui_2

供应商 ID 字节 2

oui_3

供应商 ID 字节 3

trap_num

陷阱编号

toggle_count

通知切换位和计数值

issuer_lid

陷阱发布者的 LID

reserved

保留字节

issuer_gid

发布者 GID(仅当使用报告方法时)

raw_data

陷阱消息正文

struct opa_vnic_vema_mad_trap

通用 VEMA MAD 陷阱

定义:

struct opa_vnic_vema_mad_trap {
    struct ib_mad_hdr            mad_hdr;
    struct ib_rmpp_hdr           rmpp_hdr;
    u8 reserved;
    u8 oui[3];
    struct opa_vnic_notice_attr  notice;
};

成员

mad_hdr

通用 MAD 标头

rmpp_hdr

特定于供应商的 MAD 的 RMPP 标头

reserved

保留字节

oui

唯一组织标识符

notice

通知结构

void opa_vnic_vema_report_event(struct opa_vnic_adapter *adapter, u8 event)

发送陷阱以报告指定的事件

参数

struct opa_vnic_adapter *adapter

vnic 端口适配器

u8 event

要报告的事件

描述

此函数调用 vema api 以针对给定事件发送陷阱。

void opa_vnic_get_summary_counters(struct opa_vnic_adapter *adapter, struct opa_veswport_summary_counters *cntrs)

获取汇总计数器

参数

struct opa_vnic_adapter *adapter

vnic 端口适配器

struct opa_veswport_summary_counters *cntrs

指向目标汇总计数器结构的指针

描述

此函数将给定适配器维护的汇总计数器填充到提供的目标地址。

void opa_vnic_get_error_counters(struct opa_vnic_adapter *adapter, struct opa_veswport_error_counters *cntrs)

获取错误计数器

参数

struct opa_vnic_adapter *adapter

vnic 端口适配器

struct opa_veswport_error_counters *cntrs

指向目标错误计数器结构的指针

描述

此函数将给定适配器维护的错误计数器填充到提供的目标地址。

void opa_vnic_get_vesw_info(struct opa_vnic_adapter *adapter, struct opa_vesw_info *info)
  • 获取 vesw 信息

参数

struct opa_vnic_adapter *adapter

vnic 端口适配器

struct opa_vesw_info *info

指向目标 vesw 信息结构的指针

描述

此函数将给定适配器维护的 vesw 信息复制到提供的目标地址。

void opa_vnic_set_vesw_info(struct opa_vnic_adapter *adapter, struct opa_vesw_info *info)
  • 设置 vesw 信息

参数

struct opa_vnic_adapter *adapter

vnic 端口适配器

struct opa_vesw_info *info

指向 vesw 信息结构的指针

描述

此函数使用提供的 vesw 信息更新给定适配器维护的 vesw 信息。保留字段按原样存储并返回给 EM。

void opa_vnic_get_per_veswport_info(struct opa_vnic_adapter *adapter, struct opa_per_veswport_info *info)
  • 获取每个端口的 vesw 信息

参数

struct opa_vnic_adapter *adapter

vnic 端口适配器

struct opa_per_veswport_info *info

指向目标 vport 信息结构的指针

描述

此函数将给定适配器维护的每个端口的 vesw 信息复制到提供的目标地址。请注意,只读字段不会被复制。

void opa_vnic_set_per_veswport_info(struct opa_vnic_adapter *adapter, struct opa_per_veswport_info *info)
  • 设置每个端口的 vesw 信息

参数

struct opa_vnic_adapter *adapter

vnic 端口适配器

struct opa_per_veswport_info *info

指向 vport 信息结构的指针

描述

此函数使用提供的每个端口的 vesw 信息更新给定适配器维护的每个端口的 vesw 信息。保留字段按原样存储并返回给 EM。

void opa_vnic_query_mcast_macs(struct opa_vnic_adapter *adapter, struct opa_veswport_iface_macs *macs)

查询组播 MAC 列表

参数

struct opa_vnic_adapter *adapter

vnic 端口适配器

struct opa_veswport_iface_macs *macs

指向 MAC 列表的指针

描述

此函数使用适配器中配置的组播地址填充提供的 MAC 列表。

void opa_vnic_query_ucast_macs(struct opa_vnic_adapter *adapter, struct opa_veswport_iface_macs *macs)

查询单播 MAC 列表

参数

struct opa_vnic_adapter *adapter

vnic 端口适配器

struct opa_veswport_iface_macs *macs

指向 MAC 列表的指针

描述

此函数使用适配器中配置的单播地址填充提供的 MAC 列表。

struct opa_vnic_vema_port
  • VNIC VEMA 端口详细信息

定义:

struct opa_vnic_vema_port {
    struct opa_vnic_ctrl_port      *cport;
    struct ib_mad_agent            *mad_agent;
    struct opa_class_port_info      class_port_info;
    u64 tid;
    u8 port_num;
    struct xarray                   vports;
    struct ib_event_handler         event_handler;
    struct mutex                    lock;
};

成员

cport

指向端口的指针

mad_agent

指向端口的 MAD 代理的指针

class_port_info

类端口信息。

tid

事务 ID

port_num

OPA 端口号

vports

vnic 端口

event_handler

IB 事件处理程序

lock

适配器接口锁

u8 vema_get_vport_num(struct opa_vnic_vema_mad *recvd_mad)
  • 从 MAD 获取 VNIC

参数

struct opa_vnic_vema_mad *recvd_mad

接收到的 MAD

返回值

返回 VNIC 端口号的值

struct opa_vnic_adapter *vema_get_vport_adapter(struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_port *port)
  • 从接收到的 MAD 获取 VNIC 端口适配器

参数

struct opa_vnic_vema_mad *recvd_mad

接收到的 MAD

struct opa_vnic_vema_port *port

指向收到 MAD 的端口结构的指针

返回值

VNIC 适配器

bool vema_mac_tbl_req_ok(struct opa_veswport_mactable *mac_tbl)
  • 检查 MAC 请求是否具有正确的值

参数

struct opa_veswport_mactable *mac_tbl

MAC 表

描述

此函数检查所需的偏移量和条目数的有效性。

返回值

如果 offset 和 num_entries 有效,则为 true

struct opa_vnic_adapter *vema_add_vport(struct opa_vnic_vema_port *port, u8 vport_num)
  • 添加新的 VNIC 端口

参数

struct opa_vnic_vema_port *port

指向 opa_vnic_vema_port 结构的指针

u8 vport_num

VNIC 端口号(要添加)

描述

返回指向 VNIC 适配器结构的指针

void vema_get_class_port_info(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad)
  • 获取端口的类信息

参数

struct opa_vnic_vema_port *port

接收到 MAD 的端口

struct opa_vnic_vema_mad *recvd_mad

指向接收到的 MAD 的指针

struct opa_vnic_vema_mad *rsp_mad

指向响应 MAD 的指针

描述

此函数复制端口的最新类端口信息值集,并存储它以生成陷阱

void vema_set_class_port_info(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad)
  • 获取端口的类信息

参数

struct opa_vnic_vema_port *port

接收到 MAD 的端口

struct opa_vnic_vema_mad *recvd_mad

指向接收到的 MAD 的指针

struct opa_vnic_vema_mad *rsp_mad

指向响应 MAD 的指针

描述

此函数更新特定 VNIC 的端口类信息,并设置响应 MAD 数据

void vema_get_veswport_info(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad)
  • 获取 veswport 信息

参数

struct opa_vnic_vema_port *port

接收 MAD 的源端口

struct opa_vnic_vema_mad *recvd_mad

指向接收到的 MAD 的指针

struct opa_vnic_vema_mad *rsp_mad

指向响应 MAD 的指针

void vema_set_veswport_info(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad)
  • 设置 veswport 信息

参数

struct opa_vnic_vema_port *port

接收 MAD 的源端口

struct opa_vnic_vema_mad *recvd_mad

指向接收到的 MAD 的指针

struct opa_vnic_vema_mad *rsp_mad

指向响应 MAD 的指针

描述

此函数获取 VNIC 的端口类信息

void vema_get_mac_entries(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad)
  • 获取 VNIC MAC 表中的 MAC 条目

参数

struct opa_vnic_vema_port *port

接收 MAD 的源端口

struct opa_vnic_vema_mad *recvd_mad

指向接收到的 MAD 的指针

struct opa_vnic_vema_mad *rsp_mad

指向响应 MAD 的指针

描述

此函数获取编程到 VNIC MAC 转发表中的 MAC 条目。它检查 MAC 表索引的有效性以及要检索的条目数。

void vema_set_mac_entries(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad)
  • 在 VNIC MAC 表中设置 MAC 条目

参数

struct opa_vnic_vema_port *port

接收 MAD 的源端口

struct opa_vnic_vema_mad *recvd_mad

指向接收到的 MAD 的指针

struct opa_vnic_vema_mad *rsp_mad

指向响应 MAD 的指针

描述

此函数在 VNIC 转发表中设置 MAC 条目。 它检查索引的有效性和要编程的转发表条目数。

void vema_set_delete_vesw(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad)
  • 将 VESW 信息重置为 POD 值

参数

struct opa_vnic_vema_port *port

接收 MAD 的源端口

struct opa_vnic_vema_mad *recvd_mad

指向接收到的 MAD 的指针

struct opa_vnic_vema_mad *rsp_mad

指向响应 MAD 的指针

描述

此函数清除请求的 vesw 的 veswport 信息的所有字段,并将它们设置回上电默认值。 它不会删除 vesw。

void vema_get_mac_list(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad, u16 attr_id)
  • 获取单播/多播 MAC。

参数

struct opa_vnic_vema_port *port

接收 MAD 的源端口

struct opa_vnic_vema_mad *recvd_mad

接收到的 MAD 包含用于设置 VNIC 参数的字段

struct opa_vnic_vema_mad *rsp_mad

要构建的响应 MAD

u16 attr_id

指示多播或单播 MAC 列表的属性 ID

void vema_get_summary_counters(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad)
  • 获取摘要计数器。

参数

struct opa_vnic_vema_port *port

接收 MAD 的源端口

struct opa_vnic_vema_mad *recvd_mad

接收到的 MAD 包含用于设置 VNIC 参数的字段

struct opa_vnic_vema_mad *rsp_mad

要构建的响应 MAD

void vema_get_error_counters(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad)
  • 获取摘要计数器。

参数

struct opa_vnic_vema_port *port

接收 MAD 的源端口

struct opa_vnic_vema_mad *recvd_mad

接收到的 MAD 包含用于设置 VNIC 参数的字段

struct opa_vnic_vema_mad *rsp_mad

要构建的响应 MAD

void vema_get(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad)
  • 处理接收到的 get MAD

参数

struct opa_vnic_vema_port *port

接收 MAD 的源端口

struct opa_vnic_vema_mad *recvd_mad

接收到的 MAD

struct opa_vnic_vema_mad *rsp_mad

要构建的响应 MAD

void vema_set(struct opa_vnic_vema_port *port, struct opa_vnic_vema_mad *recvd_mad, struct opa_vnic_vema_mad *rsp_mad)
  • 处理接收到的设置 MAD

参数

struct opa_vnic_vema_port *port

接收 MAD 的源端口

struct opa_vnic_vema_mad *recvd_mad

接收到的 MAD 包含用于设置 VNIC 参数的字段

struct opa_vnic_vema_mad *rsp_mad

要构建的响应 MAD

void vema_send(struct ib_mad_agent *mad_agent, struct ib_mad_send_wc *mad_wc)
  • VEMA MAD 代理的发送处理程序

参数

struct ib_mad_agent *mad_agent

指向 MAD 代理的指针

struct ib_mad_send_wc *mad_wc

指向 MAD 发送工作完成信息的指针

描述

释放与已发送 MAD 关联的所有数据结构

void vema_recv(struct ib_mad_agent *mad_agent, struct ib_mad_send_buf *send_buf, struct ib_mad_recv_wc *mad_wc)
  • VEMA MAD 代理的接收处理程序

参数

struct ib_mad_agent *mad_agent

指向 MAD 代理的指针

struct ib_mad_send_buf *send_buf

如果找到发送缓冲区,否则为 NULL

struct ib_mad_recv_wc *mad_wc

指向 MAD 发送工作完成信息的指针

描述

仅处理 set 和 get 方法,并将其他方法响应为不支持。 为响应 MAD 分配响应缓冲区和地址句柄。

struct opa_vnic_vema_port *vema_get_port(struct opa_vnic_ctrl_port *cport, u8 port_num)
  • 获取 opa_vnic_vema_port

参数

struct opa_vnic_ctrl_port *cport

指向控制设备的指针

u8 port_num

端口号

描述

此函数遍历端口,并返回与 OPA 端口号关联的 opa_vnic_vema 端口结构

返回值

指向请求的 opa_vnic_vema_port 结构的指针

如果成功,则为 NULL,否则不成功

void opa_vnic_vema_send_trap(struct opa_vnic_adapter *adapter, struct __opa_veswport_trap *data, u32 lid)
  • 此函数向 EM 发送陷阱

参数

struct opa_vnic_adapter *adapter

指向 VNIC 适配器的指针

struct __opa_veswport_trap *data

指向调用函数填充的陷阱数据的指针

u32 lid

发布者的 lid (来自 vesw_port_info 的 encap_slid)

描述

如果 EM 应该收到有关某些内容的通知,则从 VNIC 驱动程序调用此函数以发送陷阱。 这些事件当前为 1) 单播接口 MAC 地址更改 2) 多播接口 MAC 地址更改 3) 以太网链路状态更改。在分配发送 MAD 时,使用的远程站点 qpn 为 1,因为这是众所周知的 QP。

void vema_unregister(struct opa_vnic_ctrl_port *cport)
  • 取消注册代理

参数

struct opa_vnic_ctrl_port *cport

指向控制端口的指针

描述

这将删除 VEMA 对 MAD 的注册

int vema_register(struct opa_vnic_ctrl_port *cport)
  • 注册代理

参数

struct opa_vnic_ctrl_port *cport

指向控制端口的指针

描述

此函数注册 VEMA MAD 的处理程序

返回值

成功返回 0。 否则返回非零值

void opa_vnic_ctrl_config_dev(struct opa_vnic_ctrl_port *cport, bool en)
  • 此函数通过 ib_modify_port 向 EM 发送陷阱,以指示对光纤网上的以太网的支持。

参数

struct opa_vnic_ctrl_port *cport

指向控制端口的指针

bool en

在光纤网上启用或禁用以太网支持

int opa_vnic_vema_add_one(struct ib_device *device)
  • 处理新的 IB 设备

参数

struct ib_device *device

IB 设备指针

描述

分配 VNIC 控制端口并对其进行初始化。

void opa_vnic_vema_rem_one(struct ib_device *device, void *client_data)
  • 处理 IB 设备删除

参数

struct ib_device *device

IB 设备指针

void *client_data

IB 客户端数据

描述

取消初始化并释放 VNIC 控制端口。

InfiniBand SCSI RDMA 协议目标支持

enum srpt_command_state

SRPT 管理的 SCSI 命令状态

常量

SRPT_STATE_NEW

新命令已到达并且正在处理中。

SRPT_STATE_NEED_DATA

正在处理写入或双向命令并等待数据到达。

SRPT_STATE_DATA_IN

写入或双向命令的数据已到达并且正在处理中。

SRPT_STATE_CMD_RSP_SENT

已发送 SRP_CMD 的 SRP_RSP。

SRPT_STATE_MGMT

正在处理 SCSI 任务管理命令。

SRPT_STATE_MGMT_RSP_SENT

已发送 SRP_TSK_MGMT 的 SRP_RSP。

SRPT_STATE_DONE

命令处理成功完成、命令处理已中止或命令处理失败。

struct srpt_ioctx

共享的 SRPT I/O 上下文信息

定义:

struct srpt_ioctx {
    struct ib_cqe           cqe;
    void *buf;
    dma_addr_t dma;
    uint32_t offset;
    uint32_t index;
};

成员

cqe

完成队列元素。

buf

指向缓冲区的指针。

dma

缓冲区的 DMA 地址。

offset

bufdma 中实际使用的第一个字节的偏移量。

index

I/O 上下文在其 ioctx_ring 数组中的索引。

struct srpt_recv_ioctx

SRPT 接收 I/O 上下文

定义:

struct srpt_recv_ioctx {
    struct srpt_ioctx       ioctx;
    struct list_head        wait_list;
    int byte_len;
};

成员

ioctx

见上文。

wait_list

用于插入 srpt_rdma_ch.cmd_wait_list 的节点。

byte_len

ioctx.buf 中的字节数。

struct srpt_send_ioctx

SRPT 发送 I/O 上下文

定义:

struct srpt_send_ioctx {
    struct srpt_ioctx       ioctx;
    struct srpt_rdma_ch     *ch;
    struct srpt_recv_ioctx  *recv_ioctx;
    struct srpt_rw_ctx      s_rw_ctx;
    struct srpt_rw_ctx      *rw_ctxs;
    struct scatterlist      imm_sg;
    struct ib_cqe           rdma_cqe;
    enum srpt_command_state state;
    struct se_cmd           cmd;
    u8 n_rdma;
    u8 n_rw_ctx;
    bool queue_status_only;
    u8 sense_data[TRANSPORT_SENSE_BUFFER];
};

成员

ioctx

见上文。

ch

通道指针。

recv_ioctx

与此发送 I/O 上下文关联的接收 I/O 上下文。 仅用于处理即时数据。

s_rw_ctx

如果只需要单个 rw_ctx,则 rw_ctxs 指向此处。

rw_ctxs

RDMA 读/写上下文。

imm_sg

用于即时数据的散列表。

rdma_cqe

RDMA 完成队列元素。

state

I/O 上下文状态。

cmd

目标核心命令数据结构。

n_rdma

传输此 ioctx 所需的工作请求数量。

n_rw_ctx

rw_ctxs 数组的大小。

queue_status_only

将 SCSI 状态发送回发起程序,但不发送数据。

sense_data

要发送给发起程序的 Sense 数据。

enum rdma_ch_state

SRP 通道状态

常量

CH_CONNECTING

QP 处于 RTR 状态;等待 RTU。

CH_LIVE

QP 处于 RTS 状态。

CH_DISCONNECTING

已发送 DREQ,正在等待 DREP,或已接收到 DREQ。

CH_DRAINING

已接收到 DREP 或等待 DREP 超时,并且已将最后一个工作请求加入队列。

CH_DISCONNECTED

已接收到最后一个完成。

struct srpt_rdma_ch

RDMA 通道

定义:

struct srpt_rdma_ch {
    struct srpt_nexus       *nexus;
    struct ib_qp            *qp;
    union {
        struct {
            struct ib_cm_id         *cm_id;
        } ib_cm;
        struct {
            struct rdma_cm_id       *cm_id;
        } rdma_cm;
    };
    struct ib_cq            *cq;
    u32 cq_size;
    struct ib_cqe           zw_cqe;
    struct rcu_head         rcu;
    struct kref             kref;
    struct completion       *closed;
    int rq_size;
    u32 max_rsp_size;
    atomic_t sq_wr_avail;
    struct srpt_port        *sport;
    int max_ti_iu_len;
    atomic_t req_lim;
    atomic_t req_lim_delta;
    u16 imm_data_offset;
    spinlock_t spinlock;
    enum rdma_ch_state      state;
    struct kmem_cache       *rsp_buf_cache;
    struct srpt_send_ioctx  **ioctx_ring;
    struct kmem_cache       *req_buf_cache;
    struct srpt_recv_ioctx  **ioctx_recv_ring;
    struct list_head        list;
    struct list_head        cmd_wait_list;
    uint16_t pkey;
    bool using_rdma_cm;
    bool processing_wait_list;
    struct se_session       *sess;
    u8 sess_name[40];
    struct work_struct      release_work;
};

成员

nexus

此通道关联的 I_T nexus。

qp

用于通过此通道进行通信的 IB 队列对。

{unnamed_union}

anonymous

ib_cm

见下文。

ib_cm.cm_id

与通道关联的 IB CM ID。

rdma_cm

见下文。

rdma_cm.cm_id

与通道关联的 RDMA CM ID。

cq

此通道的 IB 完成队列。

cq_size

cq 中的 CQE 数量。

zw_cqe

零长度写入 CQE。

rcu

RCU 头部。

kref

此通道的 kref。

closed

一旦可以创建具有相同标识的新通道对象,将发出信号的完成对象。

rq_size

IB 接收队列大小。

max_rsp_size

RSP 响应消息的最大大小(以字节为单位)。

sq_wr_avail

发送队列中可用的工作请求数量。

sport

指向此通道使用的 HCA 端口信息的指针。

max_ti_iu_len

最大目标到发起程序信息单元长度。

req_lim

请求限制:发起程序可能发送的最大请求数量,而无需收到响应。

req_lim_delta

尚未发送回发起程序的信用额度数量。

imm_data_offset

用于即时数据的 SRP_CMD 起始偏移量。

spinlock

保护 free_list 和状态。

state

通道状态。另请参见 enum rdma_ch_state

rsp_buf_cache

ioctx_ring 的 kmem_cache。

ioctx_ring

发送环。

req_buf_cache

ioctx_recv_ring 的 kmem_cache。

ioctx_recv_ring

接收 I/O 上下文环。

list

srpt_nexus.ch_list 中的节点。

cmd_wait_list

在 RTU 事件之前到达的 SCSI 命令列表。此列表包含 struct srpt_ioctx 元素,并通过 cm_id 自旋锁防止并发修改。

pkey

此 SRP 通道的 IB 分区的 P_Key。

using_rdma_cm

此通道是使用 RDMA/CM 还是 IB/CM。

processing_wait_list

是否正在处理 cmd_wait_list。

sess

与此 SRP 通道关联的会话信息。

sess_name

会话名称。

release_work

允许计划 srpt_release_channel()。

struct srpt_nexus

I_T nexus

定义:

struct srpt_nexus {
    struct rcu_head         rcu;
    struct list_head        entry;
    struct list_head        ch_list;
    u8 i_port_id[16];
    u8 t_port_id[16];
};

成员

rcu

此数据结构的 RCU 头部。

entry

srpt_port.nexus_list 列表节点。

ch_list

struct srpt_rdma_ch 列表。受 srpt_port.mutex 保护。

i_port_id

从 SRP_LOGIN_REQ 复制的 128 位发起程序端口标识符。

t_port_id

从 SRP_LOGIN_REQ 复制的 128 位目标端口标识符。

struct srpt_port_attrib

SRPT 端口的属性

定义:

struct srpt_port_attrib {
    u32 srp_max_rdma_size;
    u32 srp_max_rsp_size;
    u32 srp_sq_size;
    bool use_srq;
};

成员

srp_max_rdma_size

新连接的 SRP RDMA 传输的最大大小。

srp_max_rsp_size

SRP 响应消息的最大大小(以字节为单位)。

srp_sq_size

共享接收队列 (SRQ) 大小。

use_srq

是否使用 SRQ。

struct srpt_tpg

有关单个“目标门户组”的信息

定义:

struct srpt_tpg {
    struct list_head        entry;
    struct srpt_port_id     *sport_id;
    struct se_portal_group  tpg;
};

成员

entry

sport_id->tpg_list 中的条目。

sport_id

此 TPG 关联的端口名称。

tpg

LIO TPG 数据结构。

描述

零个或多个目标门户组与每个端口名称 (srpt_port_id) 关联。每个 TPG 都与一个 ACL 列表关联。

struct srpt_port_id

LIO RDMA 端口信息

定义:

struct srpt_port_id {
    struct mutex            mutex;
    struct list_head        tpg_list;
    struct se_wwn           wwn;
    char name[64];
};

成员

mutex

保护 tpg_list 更改。

tpg_list

与 RDMA 端口名称关联的 TPG。

wwn

与 RDMA 端口名称关联的 WWN。

name

端口名称的 ASCII 表示形式。

描述

多个 sysfs 目录可以与单个 RDMA 端口关联。此数据结构表示单个 (端口、名称) 对。

struct srpt_port

SRPT RDMA 端口信息

定义:

struct srpt_port {
    struct srpt_device      *sdev;
    struct ib_mad_agent     *mad_agent;
    bool enabled;
    u8 port;
    u32 sm_lid;
    u32 lid;
    union ib_gid            gid;
    struct work_struct      work;
    char guid_name[64];
    struct srpt_port_id     *guid_id;
    char gid_name[64];
    struct srpt_port_id     *gid_id;
    struct srpt_port_attrib port_attrib;
    atomic_t refcount;
    struct completion       *freed_channels;
    struct mutex            mutex;
    struct list_head        nexus_list;
};

成员

sdev

指向 HCA 信息的反向指针。

mad_agent

每个端口的管理数据报处理信息。

enabled

是否启用此目标端口。

port

从 1 开始的端口号。

sm_lid

端口的 sm_lid 的缓存值。

lid

端口的 lid 的缓存值。

gid

端口的 gid 的缓存值。

work

用于刷新上述缓存值的工作结构。

guid_name

GUID 格式的端口名称。

guid_id

GUID 格式的端口名称的 LIO 目标端口信息。

gid_name

GID 格式的端口名称。

gid_id

GID 格式的端口名称的 LIO 目标端口信息。

port_attrib

可以通过 configfs 访问的端口属性。

refcount

与此端口关联的对象数量。

freed_channels

一旦 refcount 变为 0,将发出信号的完成。

mutex

保护 nexus_list。

nexus_list

Nexus 列表。另请参见 srpt_nexus.entry。

struct srpt_device

SRPT 与单个 HCA 关联的信息

定义:

struct srpt_device {
    struct kref             refcnt;
    struct ib_device        *device;
    struct ib_pd            *pd;
    u32 lkey;
    struct ib_srq           *srq;
    struct ib_cm_id         *cm_id;
    int srq_size;
    struct mutex            sdev_mutex;
    bool use_srq;
    struct kmem_cache       *req_buf_cache;
    struct srpt_recv_ioctx  **ioctx_ring;
    struct ib_event_handler event_handler;
    struct list_head        list;
    struct srpt_port        port[];
};

成员

refcnt

此设备的引用计数。

device

指向 IB 核心管理的 struct ib_device 的反向指针。

pd

IB 保护域。

lkey

对所有本地内存具有写入权限的 L_Key(本地密钥)。

srq

每个 HCA 的 SRQ(共享接收队列)。

cm_id

连接标识符。

srq_size

SRQ 大小。

sdev_mutex

序列化 use_srq 更改。

use_srq

是否使用 SRQ。

req_buf_cache

ioctx_ring 缓冲区的 kmem_cache。

ioctx_ring

每个 HCA 的 SRQ。

event_handler

每个 HCA 的异步 IB 事件处理程序。

list

srpt_dev_list 中的节点。

port

有关此 HCA 拥有的端口的信息。

void srpt_event_handler(struct ib_event_handler *handler, struct ib_event *event)

异步 IB 事件回调函数

参数

struct ib_event_handler *handler

ib_register_event_handler() 注册的 IB 事件处理程序。

struct ib_event *event

发生的事件的描述。

描述

当发生异步 IB 事件时,InfiniBand 核心调用的回调函数。此回调可能在中断上下文中发生。另请参见 InfiniBand 架构规范中的 11.5.2 节“设置异步事件处理程序”。

void srpt_srq_event(struct ib_event *event, void *ctx)

SRQ 事件回调函数

参数

struct ib_event *event

发生的事件的描述。

void *ctx

在 SRQ 创建时指定的用户指针。

void srpt_qp_event(struct ib_event *event, void *ptr)

QP 事件回调函数

参数

struct ib_event *event

发生的事件的描述。

void *ptr

SRPT RDMA 通道。

void srpt_set_ioc(u8 *c_list, u32 slot, u8 value)

初始化 IOUnitInfo 结构

参数

u8 *c_list

控制器列表。

u32 slot

从 1 开始的槽号。

u8 value

四位值。

描述

将值中最低的四位复制到称为 c_list(控制器列表)的四位元素数组的槽号元素中。索引槽号从 1 开始。

void srpt_get_class_port_info(struct ib_dm_mad *mad)

将 ClassPortInfo 复制到管理数据报

参数

struct ib_dm_mad *mad

将作为 DM_ATTR_CLASS_PORT_INFO 的响应发送的数据报。

描述

另请参阅 InfiniBand 架构规范中的 16.3.3.1 ClassPortInfo 节。

void srpt_get_iou(struct ib_dm_mad *mad)

将 IOUnitInfo 写入管理数据报

参数

struct ib_dm_mad *mad

将作为 DM_ATTR_IOU_INFO 的响应发送的数据报。

描述

另请参阅 InfiniBand 架构规范中的 16.3.3.3 IOUnitInfo 节。另请参阅 SRP r16a 文档中的 B.7 节,表 B.6。

void srpt_get_ioc(struct srpt_port *sport, u32 slot, struct ib_dm_mad *mad)

将 IOControllerprofile 写入管理数据报

参数

struct srpt_port *sport

接收到 MAD 的 HCA 端口。

u32 slot

DM_ATTR_IOC_PROFILE 查询中指定的槽号。

struct ib_dm_mad *mad

将作为 DM_ATTR_IOC_PROFILE 的响应发送的数据报。

描述

另请参阅 InfiniBand 架构规范中的 16.3.3.4 IOControllerProfile 节。另请参阅 SRP r16a 文档中的 B.7 节,表 B.7。

void srpt_get_svc_entries(u64 ioc_guid, u16 slot, u8 hi, u8 lo, struct ib_dm_mad *mad)

将 ServiceEntries 写入管理数据报

参数

u64 ioc_guid

在回复中使用的 I/O 控制器 GUID。

u16 slot

I/O 控制器编号。

u8 hi

回复中要指定的服务条目范围的结束。

u8 lo

回复中要指定的服务条目范围的开始。

struct ib_dm_mad *mad

将作为 DM_ATTR_SVC_ENTRIES 的响应发送的数据报。

描述

另请参阅 InfiniBand 架构规范中的 16.3.3.5 ServiceEntries 节。另请参阅 SRP r16a 文档中的 B.7 节,表 B.8。

void srpt_mgmt_method_get(struct srpt_port *sp, struct ib_mad *rq_mad, struct ib_dm_mad *rsp_mad)

处理接收到的管理数据报

参数

struct srpt_port *sp

接收到 MAD 的 HCA 端口。

struct ib_mad *rq_mad

接收到的 MAD。

struct ib_dm_mad *rsp_mad

响应 MAD。

void srpt_mad_send_handler(struct ib_mad_agent *mad_agent, struct ib_mad_send_wc *mad_wc)

MAD 发送完成回调

参数

struct ib_mad_agent *mad_agent

ib_register_mad_agent() 的返回值。

struct ib_mad_send_wc *mad_wc

报告 MAD 已发送的工作完成。

void srpt_mad_recv_handler(struct ib_mad_agent *mad_agent, struct ib_mad_send_buf *send_buf, struct ib_mad_recv_wc *mad_wc)

MAD 接收回调函数

参数

struct ib_mad_agent *mad_agent

ib_register_mad_agent() 的返回值。

struct ib_mad_send_buf *send_buf

未使用。

struct ib_mad_recv_wc *mad_wc

报告已接收到 MAD 的工作完成。

int srpt_refresh_port(struct srpt_port *sport)

配置 HCA 端口

参数

struct srpt_port *sport

SRPT HCA 端口。

描述

启用 InfiniBand 管理数据报处理,更新缓存的 sm_lid、lid 和 gid 值,并为指定端口上的 MAD 处理注册回调函数。

注意

对于同一端口,多次调用此函数是安全的。

void srpt_unregister_mad_agent(struct srpt_device *sdev, int port_cnt)

取消注册 MAD 回调函数

参数

struct srpt_device *sdev

SRPT HCA 指针。

int port_cnt

具有已注册 MAD 的端口数

注意

对于同一设备,多次调用此函数是安全的。

struct srpt_ioctx *srpt_alloc_ioctx(struct srpt_device *sdev, int ioctx_size, struct kmem_cache *buf_cache, enum dma_data_direction dir)

分配一个 SRPT I/O 上下文结构

参数

struct srpt_device *sdev

SRPT HCA 指针。

int ioctx_size

I/O 上下文大小。

struct kmem_cache *buf_cache

I/O 缓冲区缓存。

enum dma_data_direction dir

DMA 数据方向。

void srpt_free_ioctx(struct srpt_device *sdev, struct srpt_ioctx *ioctx, struct kmem_cache *buf_cache, enum dma_data_direction dir)

释放一个 SRPT I/O 上下文结构

参数

struct srpt_device *sdev

SRPT HCA 指针。

struct srpt_ioctx *ioctx

I/O 上下文指针。

struct kmem_cache *buf_cache

I/O 缓冲区缓存。

enum dma_data_direction dir

DMA 数据方向。

struct srpt_ioctx **srpt_alloc_ioctx_ring(struct srpt_device *sdev, int ring_size, int ioctx_size, struct kmem_cache *buf_cache, int alignment_offset, enum dma_data_direction dir)

分配 SRPT I/O 上下文结构的环。

参数

struct srpt_device *sdev

用于分配 I/O 上下文环的设备。

int ring_size

I/O 上下文环中的元素数量。

int ioctx_size

I/O 上下文大小。

struct kmem_cache *buf_cache

I/O 缓冲区缓存。

int alignment_offset

每个环形缓冲区中 SRP 信息单元开始的偏移量。

enum dma_data_direction dir

DMA 数据方向。

void srpt_free_ioctx_ring(struct srpt_ioctx **ioctx_ring, struct srpt_device *sdev, int ring_size, struct kmem_cache *buf_cache, enum dma_data_direction dir)

释放 SRPT I/O 上下文结构的环。

参数

struct srpt_ioctx **ioctx_ring

要释放的 I/O 上下文环。

struct srpt_device *sdev

SRPT HCA 指针。

int ring_size

环元素数量。

struct kmem_cache *buf_cache

I/O 缓冲区缓存。

enum dma_data_direction dir

DMA 数据方向。

enum srpt_command_state srpt_set_cmd_state(struct srpt_send_ioctx *ioctx, enum srpt_command_state new)

设置 SCSI 命令的状态。

参数

struct srpt_send_ioctx *ioctx

发送 I/O 上下文。

enum srpt_command_state new

新的 I/O 上下文状态。

描述

不修改已中止命令的状态。返回之前的命令状态。

bool srpt_test_and_set_cmd_state(struct srpt_send_ioctx *ioctx, enum srpt_command_state old, enum srpt_command_state new)

测试并设置命令的状态。

参数

struct srpt_send_ioctx *ioctx

发送 I/O 上下文。

enum srpt_command_state old

当前的 I/O 上下文状态。

enum srpt_command_state new

新的 I/O 上下文状态。

描述

当且仅当之前的命令状态等于“old”时返回 true。

int srpt_post_recv(struct srpt_device *sdev, struct srpt_rdma_ch *ch, struct srpt_recv_ioctx *ioctx)

发布 IB 接收请求。

参数

struct srpt_device *sdev

SRPT HCA 指针。

struct srpt_rdma_ch *ch

SRPT RDMA 通道。

struct srpt_recv_ioctx *ioctx

接收 I/O 上下文指针。

int srpt_zerolength_write(struct srpt_rdma_ch *ch)

执行零长度 RDMA 写操作。

参数

struct srpt_rdma_ch *ch

SRPT RDMA 通道。

描述

摘自 InfiniBand 规范:C9-88:对于使用可靠连接服务的 HCA 响应器,对于每个零长度 RDMA READ 或 WRITE 请求,即使请求包含立即数据,也不应验证 R_Key。

int srpt_get_desc_tbl(struct srpt_recv_ioctx *recv_ioctx, struct srpt_send_ioctx *ioctx, struct srp_cmd *srp_cmd, enum dma_data_direction *dir, struct scatterlist **sg, unsigned int *sg_cnt, u64 *data_len, u16 imm_data_offset)

解析 SRP_CMD 请求的数据描述符。

参数

struct srpt_recv_ioctx *recv_ioctx

与接收到的命令 srp_cmd 关联的 I/O 上下文。

struct srpt_send_ioctx *ioctx

将用于响应启动器的 I/O 上下文。

struct srp_cmd *srp_cmd

指向 SRP_CMD 请求数据的指针。

enum dma_data_direction *dir

指向变量的指针,该变量将写入传输方向。

struct scatterlist **sg

[out] 解析的 SRP_CMD 的散列表。

unsigned int *sg_cnt

[out] sg 的长度。

u64 *data_len

指向变量的指针,该变量将写入 SRP_CMD 请求中所有描述符的总数据长度。

u16 imm_data_offset

[in] SRP_CMD 请求中即时数据开始的偏移量。

描述

此函数初始化 ioctx->nrbuf 和 ioctx->r_bufs。

当 SRP_CMD 请求包含不一致的描述符时返回 -EINVAL;当内存分配失败时返回 -ENOMEM,成功时返回零。

int srpt_init_ch_qp(struct srpt_rdma_ch *ch, struct ib_qp *qp)

初始化队列对属性。

参数

struct srpt_rdma_ch *ch

SRPT RDMA 通道。

struct ib_qp *qp

队列对指针。

描述

通过允许本地写入、远程读取和远程写入来初始化队列对“qp”的属性。还将“qp”转换为 IB_QPS_INIT 状态。

int srpt_ch_qp_rtr(struct srpt_rdma_ch *ch, struct ib_qp *qp)

将通道状态更改为“准备接收” (RTR)。

参数

struct srpt_rdma_ch *ch

队列对的通道。

struct ib_qp *qp

要更改状态的队列对。

描述

成功时返回零,失败时返回负值。

注意

目前,一个 struct ib_qp_attr 在 64 位系统上占用 136 个字节。如果此结构变得更大,则可能需要动态分配它,而不是在堆栈上分配。

int srpt_ch_qp_rts(struct srpt_rdma_ch *ch, struct ib_qp *qp)

将通道状态更改为“准备发送”(RTS)

参数

struct srpt_rdma_ch *ch

队列对的通道。

struct ib_qp *qp

要更改状态的队列对。

描述

成功时返回零,失败时返回负值。

注意

目前,一个 struct ib_qp_attr 在 64 位系统上占用 136 个字节。如果此结构变得更大,则可能需要动态分配它,而不是在堆栈上分配。

int srpt_ch_qp_err(struct srpt_rdma_ch *ch)

将通道队列对状态设置为“错误”

参数

struct srpt_rdma_ch *ch

SRPT RDMA 通道。

struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch)

获取用于发送到发起程序的 I/O 上下文

参数

struct srpt_rdma_ch *ch

SRPT RDMA 通道。

int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)

中止 SCSI 命令

参数

struct srpt_send_ioctx *ioctx

与 SCSI 命令关联的 I/O 上下文。

void srpt_rdma_read_done(struct ib_cq *cq, struct ib_wc *wc)

RDMA 读取完成回调

参数

struct ib_cq *cq

完成队列。

struct ib_wc *wc

工作完成。

描述

XXX:现在 target_execute_cmd 曾经是异步的,并且必须将通过 IB RDMA 传输的数据的取消映射推迟到 check_stop_free() 回调。现在这些都不再必要,需要清理。

int srpt_build_cmd_rsp(struct srpt_rdma_ch *ch, struct srpt_send_ioctx *ioctx, u64 tag, int status)

构建一个 SRP_RSP 响应

参数

struct srpt_rdma_ch *ch

接收到请求的 RDMA 通道。

struct srpt_send_ioctx *ioctx

与 SRP_CMD 请求关联的 I/O 上下文。响应将构建在 ioctx->buf 指向的缓冲区中,因此此函数将覆盖请求数据。

u64 tag

正在为其生成此响应的请求的标记。

int status

SRP_RSP 信息单元的 STATUS 字段的值。

描述

返回 SRP_RSP 响应的大小(以字节为单位)。

SRP_RSP 响应包含 SCSI 状态或服务响应。有关 SRP_RSP 响应的格式,另请参阅 SRP r16a 文档中的 6.9 节。另请参阅 SPC-2 了解有关感知数据的更多信息。

int srpt_build_tskmgmt_rsp(struct srpt_rdma_ch *ch, struct srpt_send_ioctx *ioctx, u8 rsp_code, u64 tag)

构建任务管理响应

参数

struct srpt_rdma_ch *ch

接收到请求的 RDMA 通道。

struct srpt_send_ioctx *ioctx

将在其中构建 SRP_RSP 响应的 I/O 上下文。

u8 rsp_code

将存储在响应中的 RSP_CODE。

u64 tag

正在为其生成此响应的请求的标记。

描述

返回 SRP_RSP 响应的大小(以字节为单位)。

SRP_RSP 响应包含 SCSI 状态或服务响应。有关 SRP_RSP 响应的格式,另请参阅 SRP r16a 文档中的 6.9 节。

void srpt_handle_cmd(struct srpt_rdma_ch *ch, struct srpt_recv_ioctx *recv_ioctx, struct srpt_send_ioctx *send_ioctx)

处理 SRP_CMD 信息单元

参数

struct srpt_rdma_ch *ch

SRPT RDMA 通道。

struct srpt_recv_ioctx *recv_ioctx

接收 I/O 上下文。

struct srpt_send_ioctx *send_ioctx

发送 I/O 上下文。

void srpt_handle_tsk_mgmt(struct srpt_rdma_ch *ch, struct srpt_recv_ioctx *recv_ioctx, struct srpt_send_ioctx *send_ioctx)

处理 SRP_TSK_MGMT 信息单元

参数

struct srpt_rdma_ch *ch

SRPT RDMA 通道。

struct srpt_recv_ioctx *recv_ioctx

接收 I/O 上下文。

struct srpt_send_ioctx *send_ioctx

发送 I/O 上下文。

描述

当且仅当目标核心将处理该请求时返回 0。

有关 SRP_TSK_MGMT 信息单元的更多信息,另请参阅 SRP r16a 文档中的 6.7 节。

bool srpt_handle_new_iu(struct srpt_rdma_ch *ch, struct srpt_recv_ioctx *recv_ioctx)

处理新接收的信息单元

参数

struct srpt_rdma_ch *ch

接收到信息单元的 RDMA 通道。

struct srpt_recv_ioctx *recv_ioctx

与信息单元关联的接收 I/O 上下文。

void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc)

发送完成回调

参数

struct ib_cq *cq

完成队列。

struct ib_wc *wc

工作完成。

注意

虽然在测试中尚未观察到这一点,但至少从理论上讲,srpt_get_send_ioctx() 调用由 srpt_handle_new_iu() 调用失败是可能的。这是可能的,因为每个响应中的 req_lim_delta 值设置为 1,并且此响应有可能使发起程序在该响应的发送完成被处理之前发送新的请求。例如,如果由于优先级较高的中断而延迟了对 srpt_put_send_iotcx() 的调用,或者如果 IB 重传导致延迟了发送完成的生成,则可能会发生这种情况。对于 srpt_get_send_ioctx() 失败的传入信息单元将排队到 cmd_wait_list 上。以下代码一次处理一个这些延迟的请求。

int srpt_create_ch_ib(struct srpt_rdma_ch *ch)

创建接收和发送完成队列

参数

struct srpt_rdma_ch *ch

SRPT RDMA 通道。

bool srpt_close_ch(struct srpt_rdma_ch *ch)

关闭一个 RDMA 通道

参数

struct srpt_rdma_ch *ch

SRPT RDMA 通道。

描述

确保与该通道关联的所有资源在适当的时候被释放。

当且仅当通道状态被修改为 CH_DRAINING 时返回 true。

int srpt_cm_req_recv(struct srpt_device *const sdev, struct ib_cm_id *ib_cm_id, struct rdma_cm_id *rdma_cm_id, u8 port_num, __be16 pkey, const struct srp_login_req *req, const char *src_addr)

处理 IB_CM_REQ_RECEIVED 事件

参数

struct srpt_device *const sdev

接收到登录请求的 HCA。

struct ib_cm_id *ib_cm_id

在 IB/CM 的情况下,IB/CM 连接标识符。

struct rdma_cm_id *rdma_cm_id

在 RDMA/CM 的情况下,RDMA/CM 连接标识符。

u8 port_num

接收到 REQ 消息的端口。

__be16 pkey

传入连接的 P_Key。

const struct srp_login_req *req

SRP 登录请求。

const char *src_addr

提交登录请求的端口的 GID (IB/CM) 或 IP 地址 (RDMA/CM)。

描述

如果此函数返回零,则 cm_id 的所有权将转移到目标会话。否则,调用者仍然是 cm_id 的所有者。

void srpt_cm_rtu_recv(struct srpt_rdma_ch *ch)

处理 IB_CM_RTU_RECEIVED 或 USER_ESTABLISHED 事件

参数

struct srpt_rdma_ch *ch

SRPT RDMA 通道。

描述

RTU(准备使用)消息指示连接已建立,并且接收者可以开始传输。

int srpt_cm_handler(struct ib_cm_id *cm_id, const struct ib_cm_event *event)

IB 连接管理器回调函数

参数

struct ib_cm_id *cm_id

IB/CM 连接标识符。

const struct ib_cm_event *event

IB/CM 事件。

描述

非零返回值将导致调用者销毁 CM ID。

注意

当通过 srpt_cm_req_recv() 将 cm_id 的所有权转移到通道失败时,srpt_cm_handler() 必须只返回非零值。在任何其他情况下返回非零值都会触发与 srpt_release_channel() 中的 ib_destroy_cm_id() 调用的竞争。

void srpt_queue_response(struct se_cmd *cmd)

传输对 SCSI 命令的响应

参数

struct se_cmd *cmd

SCSI 目标命令。

描述

由 TCM 核心调用的回调函数。由于它可以在 IB 完成处理程序的上下文中调用,因此不能阻塞。

int srpt_release_sport(struct srpt_port *sport)

禁用登录并等待关联的通道

参数

struct srpt_port *sport

SRPT HCA 端口。

struct port_and_port_id srpt_lookup_port(const char *name)

按名称查找 RDMA 端口

参数

const char *name

ASCII 端口名称

描述

如果返回 RDMA 端口指针,则增加 RDMA 端口的引用计数。调用者必须通过调用 srpt_port_put_ref() 来减少该引用计数。

int srpt_add_one(struct ib_device *device)

InfiniBand 设备添加回调函数

参数

struct ib_device *device

描述一个 HCA。

void srpt_remove_one(struct ib_device *device, void *client_data)

InfiniBand 设备移除回调函数

参数

struct ib_device *device

描述一个 HCA。

void *client_data

作为第三个参数传递给 ib_set_client_data() 的值。

void srpt_close_session(struct se_session *se_sess)

强制关闭会话

参数

struct se_session *se_sess

SCSI 目标会话。

描述

当用户调用 rmdir /sys/kernel/config/target/$driver/$port/$tpg/acls/$i_port_id 时,由 TCM 核心调用的回调函数,用于清理与节点 ACL 关联的会话。

int srpt_parse_i_port_id(u8 i_port_id[16], const char *name)

解析启动器端口 ID

参数

u8 i_port_id[16]

二进制 128 位端口 ID。

const char *name

128 位启动器端口 ID 的 ASCII 表示形式。

struct se_portal_group *srpt_make_tpg(struct se_wwn *wwn, const char *name)

为 mkdir /sys/kernel/config/target/$driver/$port/$tpg 调用的 configfs 回调

参数

struct se_wwn *wwn

对应于 $driver/$port。

const char *name

$tpg。

void srpt_drop_tpg(struct se_portal_group *tpg)

为 rmdir /sys/kernel/config/target/$driver/$port/$tpg 调用的 configfs 回调

参数

struct se_portal_group *tpg

要注销的目标门户组。

struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf, struct config_group *group, const char *name)

为 mkdir /sys/kernel/config/target/$driver/$port 调用的 configfs 回调

参数

struct target_fabric_configfs *tf

未使用。

struct config_group *group

未使用。

const char *name

$port.

void srpt_drop_tport(struct se_wwn *wwn)

为 rmdir /sys/kernel/config/target/$driver/$port 调用的 configfs 回调函数

参数

struct se_wwn *wwn

$port.

int srpt_init_module(void)

内核模块初始化

参数

void

无参数

注意

由于 ib_register_client() 注册了回调函数,并且由于至少其中一个回调函数 (srpt_add_one()) 调用了目标核心函数,因此必须在调用 ib_register_client() 之前将此驱动程序注册到目标核心。

用于 RDMA 的 iSCSI 扩展 (iSER) 目标支持

void isert_conn_terminate(struct isert_conn *isert_conn)

启动连接终止

参数

struct isert_conn *isert_conn

isert 连接结构体

备注

如果连接状态为 BOUND,则将状态移动到 TERMINATING 并启动拆卸序列 (rdma_disconnect)。如果连接状态为 UP,则完成刷新。

描述

此例程必须在持有互斥锁的情况下调用。因此,多次调用是安全的。

void isert_put_unsol_pending_cmds(struct iscsit_conn *conn)

删除等待未请求数据输出的命令

参数

struct iscsit_conn *conn

iSCSI 连接

描述

我们可能仍然有命令在等待未请求的数据输出消息。在阻塞 target_wait_for_session_cmds 之前,我们必须对这些命令添加额外的引用。