0.NDSPI接口-provider实例化

1. 版本2.0

NetworkDirect架构为应用程序开发人员提供了一套网络接口,利用这套接口可以完成应用程序之间的零拷贝数据传输,I/O内核旁路的发送生成和完成处理,以及单向的数据传输操作。NetworkDirect服务提供者接口(SPI)定义了NetworkDirect提供者(Provider)实现的接口,用于向应用程序暴露其硬件功能。

2. NDSPI模型

NetworkDirect客户端应用程序使用组件对象模型(COM)接口与提供商通信。NetworkDirect客户端应用程序只使用核心的COM编程模型,而不是COM运行时。
COM接口通过IUnknown::QueryInterface方法提供了灵活的可扩展性,允许提供者返回他们想要提供的任何其它接口,从而轻松地向外暴露特定的硬件特性。NetworkDirect提供商(Provider)不会在系统中注册他们的对象,因为他们不是真正的COM对象。

在NetworkDirect SPI体系结构中不支持封送(marshaling)处理,提供者公开的COM接口总是在进程内实例化。这个模型类似于Windows驱动程序框架-用户模式驱动程序框架(UMDF)所使用的驱动程序模型。
NDSPI框架定义了如下的接口:

  • IND2Provider
    表示一个服务提供者。IND2Adapter对象通过IND2Provider::OpenAdapter方法实例化。
  • IND2Overlapped
    用于执行重叠(overlapped)IO对象的基类。
  • IND2Adapter
    服务提供商(Provider)硬件适配器实例的接口。
  • IND2CompletionQueue
    完成队列(CQ)实例的接口,通过IND2Adapter::CreateCompletionQueue方法来完成创建。
  • IND2MemoryRegion
    内存区的接口,该内存区是已在适配器实例上注册的本地缓冲区,通过IND2Adapter::CreateMemoryRegion方法完成创建。
  • IND2SharedReceiveQueue
    用于在队列对(QPair)之间聚合接收缓冲区的共享接收队列的接口,通过IND2Adapter::CreateSharedReceiveQueue方法创建。
  • IND2QueuePair
    用于执行I/O操作的队列对(QPair)实例的接口,通过IND2Adapter::CreateQueuePair或IND2Adapter::CreateQueuePairWithSrq方法创建。
  • IND2Connector
    用于管理IND2QueuePair对象连接建立的连接器实例的接口,通过IND2Adapter::CreateConnector方法创建。
  • IND2Listener
    监听请求的接口,通过IND2Adapter::CreateListener方法创建。

3. Provider管理

NetworkDirect SPI应用程序支持零个、一个或多个服务提供商库。NetworkDirect提供商的管理,遵循为Windows Sockets Direct提供商和传统分层服务提供商定义的既定机制。

3.1 注册一个Network Direct provider

要注册您的提供商(Provider),请调用WSCInstallProvider函数。WSAPROTOCOL_INFO结构的下列字段将提供者标识为NetworkDirect提供者。

  • dwServiceFlags1
    • XP1_GUARANTEED_DELIVERY
    • XP1_GUARANTEED_ORDER
    • XP1_MESSAGE_ORIENTED
    • XP1_CONNECT_DATA
  • dwProviderFlags
    • PFL_HIDDEN - 在WSAEnumProtocols函数枚举结果中不予返回当前Provider。
    • PFL_NETWORKDIRECT_PROVIDER (0x00000010) 标识当前Provider为ND provider。
  • iVersion
    当前NDSPI版本(2.0)。
  • iAddressFamily
    AF_INET或AF_INET6:支持IPv4和IPv6地址的提供商不需要多次注册他们的提供商。一个AF_INET6的注册就足够了。NetworkDirect SPI框架可以支持同时上报的IPv4和IPv6地址。
  • iSocketType
    -1 (0xFFFFFFFF)
  • iProtocol
    0,NetworkDirect SPI架构没有定义新协议。
  • iProtocolMaxOffset
    0

3.2 初始化一个Network Direct provider

1)要获得在计算机上注册的NetworkDirect提供商,调用WSCEnumProtocols函数。对于该函数返回的每个协议,将WSAPROTOCOL_INFO结构的成员与上一节中指定的成员进行比较。如果成员值匹配,协议是NetworkDirect提供商。

2)要确定提供者是否是NetworkDirect服务提供者,需要实例化IND2Provider接口。

下面的步骤展示了如何实例化provider:

  • 加载提供程序的DLL
    要获得DLL的路径,可以使用WSAPROTOCOL_INFO结构中的ProviderId成员调用WSCGetProviderPath函数。
  • 调用库的DllGetClassObject入口点来实例化IND2Provider接口
    服务提供者库需要实现一个DllCanUnloadNow入口点,以允许客户端在不再使用时卸载服务提供者库。提供者(Provider)还必须能够处理IND2Provider接口的多个调用。

现在您有了一个提供者(Provider),您需要确定提供者是否支持您想要使用的IP地址。要确定提供商支持的IP地址列表,请调用IND2Provider::QueryAddressList方法。IND2Provider接口提供了获取一个NetworkDirect Adapter接口的详细信息。

3.3 获取NetworkDirect adapter的一个实例

如果你知道你想使用的NetworkDirect适配器的IP地址,调用IND2Provider::OpenAdapter方法。如果不是,首先需要确定适配器的本地IP地址,它将为您提供对目标地址的最佳访问。例如,您可以调用GetBestInterfaceEx函数来获取本地地址。

获得本地IP地址后,调用QueryAddressList方法并枚举提供者支持的IP地址。如果提供者支持您的本地IP地址,则调用IND2Provider::OpenAdapter方法来获得适配器的接口。

4. 异步操作

NetworkDirect SPI中的许多操作采用一个OVERLAPPED结构作为输入。这些操作有望提供与传统Win32异步I/O相同的功能。再加上适配器暴露出来的的底层文件句柄(异步操作在其上执行),这种设计为应用程序提供了最适合其处理操作的灵活性。例如,应用程序可以用IOCP(IO完成端口)来注册底层的文件句柄。所有通知,例如CQ通知,都是通过完成一个包含OVERLAPPED结构的通知请求来传递的。因此,providers从不需要调用客户端代码中的回调。而是客户端显式地请求所有通知。

接受指向OVERLAPPED结构的指针的函数将始终接收到一个有效的指针,而不是nullptr。

注意ND Provider使用FILE_SKIP_COMPLETION_PORT_ON_SUCCESS和FILE_SKIP_SET_EVENT_ON_HANDLE调用SetFileCompletionNotificationModes。如此以来,唯一会使得后续存在异步事件通知的情况是:当前操作的返回值是ND_PENDING。如果操作返回ND_SUCCESS,那么请求就完成了,OVERLAPPED将不会被使用/通知,或者如果你使用IOCP,你将不会在那里看到通知;操作中的所有错误值都表示立即失败,因此不会有异步通知,因为请求提交失败。因而,应用程序必须处理两个不同的代码路径,其中一个操作要么直接成功返回,要么必须异步完成。

5. 实现须知

当前的异步操作设计将处理同步调用的负担丢给用户。因此,每当可能存在OVERLAPPED操作时,提供者(Provider)总是会看到异步调用。

Providers可能有同步命令(例如CreateCompletionQueue),它们可能会在内部处理同步I/O,或者在不同的文件句柄上发出请求。如果Provider使用两个文件句柄,一个用于异步调用,另一个用于同步调用,那么让Provider库处理同步请求(在这里pOverlapped == nullptr)可能比让客户端处理它们更简单。

关于作者:
犇叔,浙江大学计算机科学与技术专业,研究生毕业,而立有余。先后在华为、阿里巴巴和字节跳动,从事技术研发工作,资深研发专家。主要研究领域包括虚拟化、分布式技术和存储系统(包括CPU与计算、GPU异构计算、分布式块存储、分布式数据库等领域)、高性能RDMA网络协议和数据中心应用、Linux内核等方向。
专业方向爱好:数学、科学技术应用
关注犇叔,期望为您带来更多科研领域的知识和产业应用。
内容坚持原创,坚持干货有料。坚持长期创作,关注犇叔不迷路。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值