赞
踩
- int ipoib_intf_init(struct ib_device *hca, u8 port, const char *name,
- struct net_device *dev, struct ipoib_dev_priv *priv)
- {
- struct rdma_netdev *rn = netdev_priv(dev);
- int rc;
- priv->ca = hca;
- priv->port = port;
- rc = rdma_init_netdev(hca, port, RDMA_NETDEV_IPOIB, name,
- NET_NAME_UNKNOWN, ipoib_setup_common, dev,
- !ipoib_enhanced_enabled);
- if (rc) {
- if (rc != -EOPNOTSUPP)
- goto out;
- if (priv->num_tx_queues > 1) {
- netif_set_real_num_tx_queues(dev, priv->num_tx_queues);
- netif_set_real_num_rx_queues(dev, priv->num_rx_queues);
- rn->attach_mcast = ipoib_mcast_attach_rss;
- rn->send = ipoib_send_rss;
- /* Override ethtool_ops to ethtool_ops_rss */
- ipoib_set_ethtool_ops_rss(dev);
- } else {
- rn->attach_mcast = ipoib_mcast_attach;
- rn->send = ipoib_send;
- }
- dev->netdev_ops = ipoib_get_rn_ops(priv);
- rn->detach_mcast = ipoib_mcast_detach;
- rn->hca = hca;
- }
- priv->rn_ops = dev->netdev_ops;
- dev->netdev_ops = ipoib_get_netdev_ops(priv);
- rn->clnt_priv = priv;
- /*
- * Only the child register_netdev flows can handle priv_destructor
- * being set, so we force it to NULL here and handle manually until it
- * is safe to turn on.
- */
- priv->next_priv_destructor = dev->priv_destructor;
- dev->priv_destructor = NULL;
- ipoib_build_priv(dev);
- return 0;
- out:
- return rc;
- }
是的,这个函数`ipoib_intf_init`在初始化一个IP over InfiniBand (IPoIB) 网络接口时注册了回调函数 ipoib_send_rss 和 ipoib_send。让我们用中文逐步解读这个函数的作用和它做了什么:
1. 函数 ipoib_intf_init 接收了几个参数:
- *hca:指向InfiniBand设备 (ib_device) 的指针。
- port:表示InfiniBand端口的号码。
- *name:网络接口的名字。
- *dev:指向网络设备 (net_device) 的指针。
- *priv:指向IPoIB私有数据结构 (ipoib_dev_priv) 的指针。
2. 函数开始时,将 hca 和 port 存储在 priv 结构中,这样就能在后面使用这些IB设备和端口信息。
3. 调用 rdma_init_netdev 来初始化网络设备。这个过程会设置一些基础的网络设备操作,并且可以通过参数 ipoib_setup_common 来定制一些IPoIB的特定设置。
4. 如果 rdma_init_netdev 返回的 rc 不为零,表示初始化失败,除非错误代码是 -EOPNOTSUPP,否则会直接跳到函数最后,并返回错误码。
5. 如果初始化成功,函数将会根据 priv->num_tx_queues 的值来决定使用哪一套回调函数:
- 如果 priv->num_tx_queues 大于1,表示启用了多个发送队列(可能是为了RSS)。这时,函数会设置真正的发送(netif_set_real_num_tx_queues)和接收(netif_set_real_num_rx_queues)队列数量,并注册多队列版本的回调函数 ipoib_mcast_attach_rss 和 ipoib_send_rss。
- 如果只有一个发送队列,就会注册单队列版本的回调函数 ipoib_mcast_attach 和 ipoib_send。
6. 还有其他一些回调函数被设置,例如 ipoib_mcast_detach 用于处理组播的分离操作。
7. ipoib_get_rn_ops 和 ipoib_get_netdev_ops 函数被用于获取和设置适当的网络操作结构(netdev_ops),其中可能还包含了更多回调函数。
8. 函数设置了 rn->clnt_priv 为 priv,将私有结构关联到设备上下文中。
9. 有一个特别的代码块处理了网络设备的 priv_destructor。原来的析构器被存储在 priv->next_priv_destructor 中,而 dev->priv_destructor 被设置为 NULL。这表明在特定情况下,设备的内存或资源会在后续过程手动释放而不是自动释放。
10. 调用 ipoib_build_priv 函数来对IPoIB私有结构进行进一步初始和构建。
11. 在成功完成所有操作之后,函数返回0,表示成功。如果有步骤失败,则跳转至 out 标签,并返回相应的错误码。
总之,这个函数负责根据InfiniBand设备和端口对IPoIB网络接口进行初始化,注册了网络操作回调函数以及其他相关职能的函数,以便正确处理网络数据包的发送和接收。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。