前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >RDMA技术 - 请求事件SE(SOLICITED EVENT)-降低CPU开销

RDMA技术 - 请求事件SE(SOLICITED EVENT)-降低CPU开销

原创
作者头像
晓兵
发布2024-12-21 09:21:03
发布2024-12-21 09:21:03
14000
代码可运行
举报
文章被收录于专栏:DPUDPU
运行总次数:0
代码可运行

术语

  • SDP: Sockets Direct Protocol, RDMA SDP(RDMA over SDP)是一种使用套接字直接协议(SDP)通过UDPIPv4 网络实现 远程直接内存访问(RDMA)通信的协议。SDP 是一种传输协议,旨在通过标准以太网网络(包括使用 UDP 的网络)提供 RDMA 功能,从而实现低延迟、高吞吐量通信,而无需 InfiniBand 等专用硬件

简介

请求事件是一种机制,请求方发送消息,当响应方收到消息时,响应方会生成特殊(即请求的)事件。当工作完成添加到响应方(在接收队列中)的完成队列时,将为消息生成事件,因此它仅对发送(SEND)、立即发送(Send with immediate)和 RDMA 立即写入(Write with immediate)操作有效(因为只有这些操作会在响应方生成工作完成)

何时使用请求事件?

如果希望降低 CPU 消耗,并且不想使用常规频繁的工作完成事件,即下一个工作完成时,接收方总是将WQE添加到完成队列, 而是发送方将其标记为“特殊”的工作完成,那么请求事件机制就是答案

使用请求事件可以帮助减少接收方的 CPU 消耗,因为它可以休眠直到收到带有请求事件的消息(即来自发送方的“提示”)。与每次收到消息时唤醒并检查特定条件相比(即处理的事件更少)。

一般SE配合CQ中断模式使用

如何使用

发送方

发送方调用ibv_post_send()时,需要在 send_wr.send_flags 中设置IBV_SEND_SOLICITED标记位。注意: 这仅与上面提到的操作相关

如UCX中的零拷贝发送(uct_rc_verbs_ep_am_zcopy):

代码语言:javascript
代码运行次数:0
复制
ucs_status_t do_am_zcopy -> 零拷贝
ucs_status_t uct_rc_verbs_ep_am_zcopy(uct_ep_h tl_ep, uint8_t id, const void *header,
                                      unsigned header_length, const uct_iov_t *iov,
                                      size_t iovcnt, unsigned flags,
                                      uct_completion_t *comp)
{
    uct_rc_verbs_iface_t     *iface = ucs_derived_of(tl_ep->iface, uct_rc_verbs_iface_t);
    uct_rc_verbs_ep_t        *ep    = ucs_derived_of(tl_ep, uct_rc_verbs_ep_t);
    uct_rc_iface_send_desc_t *desc  = NULL;
    struct ibv_sge sge[UCT_IB_MAX_IOV]; /* First sge is reserved for the header */
    struct ibv_send_wr wr;
    int send_flags;
    size_t sge_cnt;
​
    /* 1 iov consumed by am header */
    UCT_CHECK_IOV_SIZE(iovcnt, iface->config.max_send_sge - 1,
                       "uct_rc_verbs_ep_am_zcopy");
    UCT_RC_CHECK_AM_ZCOPY(id, header_length, uct_iov_total_length(iov, iovcnt),
                          iface->config.short_desc_size,
                          iface->super.super.config.seg_size);
    UCT_RC_CHECK_RES_AND_FC(&iface->super, &ep->super, id);
​
    UCT_RC_IFACE_GET_TX_AM_ZCOPY_DESC(&iface->super, &iface->short_desc_mp,
                                      desc, id, header, header_length, comp,
                                      &send_flags);
    sge[0].length = sizeof(uct_rc_hdr_t) + header_length;
    sge_cnt = uct_ib_verbs_sge_fill_iov(sge + 1, iov, iovcnt);
    UCT_RC_VERBS_FILL_AM_ZCOPY_WR_IOV(wr, sge, (sge_cnt + 1), wr.opcode);
    UCT_TL_EP_STAT_OP(&ep->super.super, AM, ZCOPY,
                      (header_length + uct_iov_total_length(iov, iovcnt)));
    // 发送方设置请求事件标记
    uct_rc_verbs_ep_post_send_desc(ep, &wr, desc, send_flags | IBV_SEND_SOLICITED,
                                   UCT_IB_MAX_ZCOPY_LOG_SGE(&iface->super.super));
    UCT_RC_UPDATE_FC(&ep->super, id);
​
    return UCS_INPROGRESS;
}

响应方(接收方)

应该在接收完成队列上调用ibv_req_notify_cq() ,该队列可能会收到带有 Solicited 事件的传入消息;solicited_only参数值应该非零。

该还函数参数和实现如下:

代码语言:javascript
代码运行次数:0
复制
请求 CQ 上的完成通知。当条目添加到 CQ 时,将向与 CQ 关联的完成通道(completion channel)添加事件。
    @cq:请求通知的完成队列。
    @solicited_only:如果非零,则仅为下一个请求事件完成(SE),生成CQ事件。如果为零,则任何 CQ 条目(无论是否请求)都将生成事件 (Notifies only if the WR is flagged as solicited)
static inline int ibv_req_notify_cq(struct ibv_cq *cq, int solicited_only)
{
    return cq->context->ops.req_notify_cq(cq, solicited_only);
}

这将导致ibv_get_cq_event()被阻塞,直到发生下列情况之一:

  • 带有请求事件指示符的传入消息的下一个工作完成将被添加到完成队列。这最多可能发生一次,如果需要再次等待下一个请求事件,则可能需要再次调用ibv_req_notify_cq() 。
  • 任何有错误的工作完成都会被添加到完成队列(无论它来自发送队列还是接收队列)

IB规范中的SE

传输层中SE

概括为一句话: A facility by which a message sender may cause an event to be generated at the recipient when the message is received

在基本传输头BTH中的SE

详解SE标记位

  • 请求者将此位设置为 1,表示响应者应调用 CQ 事件处理程序。其他操作指南: • SE 位应仅在 SEND、SEND with Immediate 或 RDMA WRITE with Immediate 业务操作的最后一个或唯一数据包中设置(即用于通知整体操作完成)。 • 有关影响 HCA 的其他操作指南,请参阅第 689 页上的第 11.4.2.2 节“请求完成通知”。
  • SE 位不被视为数据包头验证的一部分,即,收到设置了此位但不符合调用要求的数据包不会导致生成 NAK。
  • C9-3:对于 HCA,如果入站请求数据包的 BTH 中的 Solicited Event 位设置为 1,并且其他 SE 操作指南有效,则它应调用 CQ 事件处理程序。
  • o9-1:对于支持 Solicited Events 的 TCA,如果入站请求数据包的 BTH 中的 Solicited Event 位设置为 1,并且其他 SE 操作指南有效,则它也应调用 CQ 事件处理程序。
  • C9-4:响应方不应在数据包头验证的 BTH 部分考虑 SE 位。除了在 SEND、SEND with Immediate 或 RDMA Write with Immediate 操作中使用外,SE 位还可以在 SEND with Invalidate 操作中设置。在这种情况下,SE 位应仅在 SEND with Invalidate 的最后一个或唯一一个数据包中设置。在所有其他方面,SE 位的使用遵循与正常 SEND 操作中 SE 位的使用相同的规则

一般在创建CQ时会设置事件处理程序

代码语言:javascript
代码运行次数:0
复制
创建CQ时设置回调函数
static int create_cq
    ...
    cq->comp_handler  = ib_uverbs_comp_handler;
    cq->event_handler = ib_uverbs_cq_event_handler;
    ...
​
​
static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)
​
    ...
​
     cq->comp_handler  = ib_uverbs_comp_handler;
​
     cq->event_handler = ib_uverbs_cq_event_handler;
​
    ...

请求完成通知

11.4.2.2 请求完成通知

描述:当指定类型的下一个完成条目添加到指定 CQ 时,请求调用 CQ 事件处理程序。对于特定的 CQ,每次请求完成通知调用时,处理程序最多调用一次。在启用通知之前存在的任何 CQ 条目都不会导致调用处理程序, 完成事件有两种类型:请求的或未经请求的。当传入的发送或 RDMA 写入即时数据消息(设置了请求的事件标头位)导致成功的接收工作完成添加到 CQ 时,或者当不成功的工作完成添加到 CQ 时,会发生请求的完成事件。当任何其他成功的接收工作完成或任何成功的发送工作完成添加到 CQ 时,会发生未经请求的完成事件。

C11-29:CI 应支持请求的和未经请求的完成事件类型。消费者请求完成通知时,必须指定是否为以下事件调用通知回调:

• 仅限下一个请求的完成事件,或

• 下一个请求或非请求的完成事件。

C11-29.1.1:当“仅限下一个请求的完成事件”未完成时,CI 应在以下任一情况下调用通知回调:

• 设置了请求的事件标头位的传入发送导致成功的接收工作完成被添加到指定的 CQ。

• 设置了请求的事件标头位的传入 RDMA 写入和立即数据导致成功的接收工作完成被添加到指定的 CQ。

• 将不成功的发送或接收工作完成添加到指定的 CQ。

C11-29.1.2:当“下一个请求或非请求的完成事件”未完成时,CI 应在将任何工作完成添加到指定的 CQ 时调用通知回调。如果请求完成通知处于待处理状态,则在完成事件之前对同一 CQ 的请求完成通知的后续调用仅在通知发生时才会生效。下一个完成事件的请求完成通知优先于同一 CQ 的请求事件完成的请求完成通知。如果对同一 CQ 进行了多次请求完成通知调用,并且至少有一个请求将类型设置为下一个完成,则在将下一个完成添加到该 CQ 时将调用 CQ 事件处理程序。即使在指定 CQ 的完成事件之前进行了多个 CQ 通知请求,CQ 事件处理程序也只会被调用一次。一旦调用 CQ 事件处理程序,必须先注册另一个完成通知请求,然后才能再次调用 CQ 事件处理程序。

C11-30:当 CQ 上请求的完成类型的完成通知请求未完成,并且对该 CQ 进行了另一个指定下一个完成通知的请求时,CI 应将未完成的完成通知类型更改为下一个完成。

C11-31:当 CQ 上下一个完成的完成通知请求未完成,并且对该 CQ 发出了另一个通知请求时,CI 不得更改未完成的完成通知类型。在调用此例程之前,必须指定 CQ 事件处理程序。如果在生成事件时尚未注册 CQ 事件处理程序,则不会进行处理程序调用。调用 CQ 事件处理程序时,它仅表示已将新条目添加到指定的 CQ。HCA 和 CQ 句柄被传递给 CQ 事件处理程序,因此 CQ 事件处理程序可以确定哪个 CQ 导致它被调用。调用处理程序例程后,消费者必须再次调用请求完成通知,以便在向该 CQ 添加新条目时收到通知。消费者有责任调用轮询完成动词来检索工作完成。注意:如果消费者在没有与 CQ 关联的 CQ 事件处理程序 ID 的 CQ 句柄上请求完成通知,则该操作将不起作用。也就是说,不会生成任何完成事件。

输入修饰符:

• HCA 句柄。

• CQ 句柄。

• 请求的完成通知类型。类型是下一个完成或请求的完成发生时。

输出修饰符:

动词结果:

• 操作已成功完成。

• 无效的 HCA 句柄。

• 无效的 CQ 句柄。

• 无效的完成通知类型

IB传输层的一些问题 - SDP的请求事件

A4.11.2 请求事件

SDP 实现的SE功能, 偶尔需要停止半连接上的处理并等待以下消息之一到达后再继续:

  1. 流控制信用更新 SDP 消息 - 接收私有缓冲池的流控制信用已耗尽,因此无法向对等方发送数据、控制和/或 RDMA 广播;
  2. 数据或 RDMA 广告 SDP 消息 - ULP 已通过套接字接口选择调用或接收表示对数据感兴趣;
  3. RDMA 完成(或取消)SDP 消息 - 在取消注册发送或接收 RDMA 缓冲区之前,它必须完成 RDMA 传输或接收取消确认消息。典型的 SDP 实现将请求完成队列通知并阻止 ULP 进程(或线程),直到相应的消息到达并传递通知。使用 SE(请求事件)位的目的是当到达的消息与实现所需的 SDP 消息类不匹配时,尽量减少完成队列通知事件和相应的进程(或线程)唤醒。例如,如果数据源正在等待 RdmaRdCompl 消息来完成发送 ULP 缓冲区,并且在相反的半通道(本地数据接收器)上没有发布本地接收 ULP 缓冲区或本地调用套接字接口选择,则如果对等方发送数据消息或 SrcAvail RDMA 广告,它不应该收到相反的半连接的通知。为了实现这一目标,所有 SDP 消息都细分为请求的或非请求的 SDP 消息。请求的 SDP 消息最有可能需要立即关注,无论远程对等方的 ULP 行为如何,也无论远程对等方是否正在等待其他(非请求的)消息。请求的 SDP 消息定义为: • AbortConn、SuspComm、SuspCommAck、SendSm、SrcAvailCancel、SinkAvailCancel - 因为对于这些消息的发送者来说,其对等方尽快对其做出反应至关重要; • RdmaWrCompl、RdmaRdCompl、SinkCancelAck - 因为对等方很可能需要在收到这些消息后取消注册并释放 RDMA 缓冲区到 ULP; • 设置了 OOB_PRES 或 OOB_PEND 位的数据 - 因为对等方 SDP 实现很可能需要尽快通知 ULP 已收到此消息。 CA4-119:SDP 实现应请求为请求的 SDP 消息设置 InfiniBand 基本传输头中的 InfiniBand SE 位。未经请求的 SDP 消息是那些可能需要对等方立即关注的消息,但只有对等方才能决定是否需要通知 - 这取决于 ULP 行为或对等方的实现。未经请求的 SDP 消息定义为: • 未设置 OOB_PEND 或 OOB_PRES 位的 DisConn、SrcAvail、SinkAvail、数据 - 因为对等方只需要在 ULP 发出套接字接口选择或接收请求时立即处理这些消息; • ModeChange、ChRcvBuf、ChRcvBufAck - 因为在收到这些消息后,对等端只需要对自己生成的新消息或随后的请求的 SDP 消息采取行动(例如,它不会被阻止专门等待这些 SDP 消息)。 CA4-120:SDP 实现不得请求为未经请求的 SDP 消息设置 InfiniBand 基础传输标头中的 InfiniBand SE 位。 SE 位永远不适用于 RDMA 读取,而 RDMA 写入仅适用于包含即时数据的 RDMA 写入。由于 SDP 从不生成带有即时数据的 RDMA 写入,因此 SE 位不适用于由 SDP 生成的 RDMA 读取或 RDMA 写入请求

参考

RDMAmojo-SE: https://www.rdmamojo.com/2014/05/27/solicited-event/

IBM_ibv_req_notify_cq: https://www.ibm.com/docs/en/aix/7.1?topic=management-ibv-req-notify-cq

IB_SPEC

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 术语
  • 简介
    • 何时使用请求事件?
    • 如何使用
      • 发送方
      • 响应方(接收方)
  • IB规范中的SE
    • 传输层中SE
      • 详解SE标记位
    • 请求完成通知
    • IB传输层的一些问题 - SDP的请求事件
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档