高性能网络I/O框架-netmap源码分析(5)

简介: 高性能网络I/O框架-netmap源码分析(5) 作者:gfree.wind@gmail.com 博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net 微博:weibo.com/glinuxer QQ技术群:4367710 今天继续前面的netmap_ioctl netmap_ioctl 上次分析完了NIOCGINFO和NIOCREGIF两个,剩下的比较简单了。

高性能网络I/O框架-netmap源码分析(5)

作者:gfree.wind@gmail.com
博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net
微博:weibo.com/glinuxer
QQ技术群:4367710

今天继续前面的netmap_ioctl

netmap_ioctl

上次分析完了NIOCGINFO和NIOCREGIF两个,剩下的比较简单了。那么今天争取干掉剩下所有的case,以及上篇中netmap_ioctl调用的函数

NIOCUNREGIF

case NIOCUNREGIF:
    if (priv == NULL) {
        /* 没有priv肯定是不对的,肯定是没有调用过NIOCREGIF */
        error = ENXIO;
        break;
    }

    /* the interface is unregistered inside the
       destructor of the private data. */
    /* 释放priv内存*/
    devfs_clear_cdevpriv();
    break; 

NIOCTXSYNC和NIOCRXSYNC

这两个使用相同的代码。

case NIOCTXSYNC:
case NIOCRXSYNC:
    /* 检查priv,确保之前调用了NIOCREGIF */
    if (priv == NULL) {
        error = ENXIO;
        break;
    }
    /* 
    记得之前分析NIOCREGIF时,priv->np_ifp保存了net_device指针,所有现在可以直接获得这个指针。
    要不要担心net_device指针的有效性呢?不用,因为NIOCREGIF时,在得到net_device时,已经增加了计数
    */
    ifp = priv->np_ifp; /* we have a reference */
    na = NA(ifp); /* retrieve netmap adapter */

    /* 
    np_qfirst表示需要检查的第一个ring 
    当其值为NETMAP_SW_RING是一个特殊的值,表示处理host的ring
    */
    if (priv->np_qfirst == NETMAP_SW_RING) { /* host rings */
        /* 
        对于host ring处理,这个地方的代码有点奇怪。
        当cmd是NIOCTXSYNC,是将数据包传给host;
        当cmd是NIOCRXSYNC,是将数据包从host发送出去;
        感觉好像写反了。我给作者发了邮件,不知道能不能得到回复。
        反正从语义上,我是觉得有问题。


        现在已经得到了作者的回复——再次感叹外国人的友好。这里的方向,是以netmap的角度去看。
        所以,当cmd是txsync时,是netmap把包送出去,那么自然是交给host。反之亦然。
        */
        if (cmd == NIOCTXSYNC)
            netmap_sync_to_host(na);
        else
            netmap_sync_from_host(na, NULL, NULL);
        break;
    }

    /* find the last ring to scan */
    /* 
    得到需要检查的最后一个ring,如果是NETMAP_HW_RING,那么就是最大ring数值 
    关于np_qfirst和np_qlast,等看到netmap_set_ringid时,大家就明白了
    */
    lim = priv->np_qlast;
    if (lim == NETMAP_HW_RING)
        lim = (cmd == NIOCTXSYNC) ?
            na->num_tx_rings : na->num_rx_rings;

    /* 从第一个开始遍历每个ring */
    for (i = priv->np_qfirst; i tx_rings[i];
            if (netmap_verbose & NM_VERB_TXSYNC)
                D("pre txsync ring %d cur %d hwcur %d",
                    i, kring->ring->cur,
                    kring->nr_hwcur);
            /* 执行发送工作,留到后面分析 */
            na->nm_txsync(ifp, i, 1 /* do lock */);
            if (netmap_verbose & NM_VERB_TXSYNC)
                D("post txsync ring %d cur %d hwcur %d",
                    i, kring->ring->cur,
                    kring->nr_hwcur);
        } else {
            /* 执行接收工作,留到后面分析*/
            na->nm_rxsync(ifp, i, 1 /* do lock */);
            /* 
            在linux平台上,实际上是调用了do_gettimeofday,不知道为什么接收需要的这个时间
            看看以后是不是可以知道原因。
            */
            microtime(&na->rx_rings[i].ring->ts);
        }
    } 

到此,netmap_ioctl分析学习完毕。

netmap_set_ringid

在上篇文章中,遗留了这个函数。

static int
netmap_set_ringid(struct netmap_priv_d *priv, u_int ringid)
{
    struct ifnet *ifp = priv->np_ifp;
    struct netmap_adapter *na = NA(ifp);

    /*
    从下面三个宏,可以得知ringid是一个“复用”的结构。低24位用于表示id值,高位作为标志。
    #define NETMAP_HW_RING  0x4000      /* low bits indicate one hw ring */
    #define NETMAP_SW_RING  0x2000      /* process the sw ring */
    #define NETMAP_NO_TX_POLL   0x1000  /* no automatic txsync on poll */
    #define NETMAP_RING_MASK 0xfff      /* the ring number */
    */
    u_int i = ringid & NETMAP_RING_MASK;
    /*
    根据注释,在初始化阶段,np_qfirst和np_qlast相等,不需要锁保护。
    关于这点我没想明白。如果两个线程同时进入怎么办?
    */
    /* initially (np_qfirst == np_qlast) we don't want to lock */
    int need_lock = (priv->np_qfirst != priv->np_qlast);
    int lim = na->num_rx_rings;

    /* 上限取发送和接收队列数量的最大值 */
    if (na->num_tx_rings > lim)
        lim = na->num_tx_rings;
    /* 当处理HW ring时,要对id进行有效性判断 */
    if ( (ringid & NETMAP_HW_RING) && i >= lim) {
        D("invalid ring id %d", i);
        return (EINVAL);
    }
    if (need_lock)
        na->nm_lock(ifp, NETMAP_CORE_LOCK, 0);
    priv->np_ringid = ringid;
    /*
    根据三种标志,设置正确的np_qfirst和qlast。从这里也可以看出,只有在初始化时,np_qfirst才可能等于np_qlast。 
    */
    if (ringid & NETMAP_SW_RING) {
        priv->np_qfirst = NETMAP_SW_RING;
        priv->np_qlast = 0;
    } else if (ringid & NETMAP_HW_RING) {
        priv->np_qfirst = i;
        priv->np_qlast = i + 1;
    } else {
        priv->np_qfirst = 0;
        priv->np_qlast = NETMAP_HW_RING ;
    }
    /* 是否在执行接收数据包的poll时,发送数据包 */
    priv->np_txpoll = (ringid & NETMAP_NO_TX_POLL) ? 0 : 1;
    if (need_lock)
        na->nm_lock(ifp, NETMAP_CORE_UNLOCK, 0);
    if (ringid & NETMAP_SW_RING)
        D("ringid %s set to SW RING", ifp->if_xname);
    else if (ringid & NETMAP_HW_RING)
        D("ringid %s set to HW RING %d", ifp->if_xname,
            priv->np_qfirst);
    else
        D("ringid %s set to all %d HW RINGS", ifp->if_xname, lim);
    return 0;
} 

(未完待续。。。)

目录
相关文章
|
1月前
|
存储 分布式计算 监控
Hadoop【基础知识 01+02】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
【4月更文挑战第3天】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
77 2
|
3天前
|
存储 网络协议 Linux
RTnet – 灵活的硬实时网络框架
本文介绍了开源项目 RTnet。RTnet 为以太网和其他传输媒体上的硬实时通信提供了一个可定制和可扩展的框架。 本文描述了 RTnet 的架构、核心组件和协议。
11 0
RTnet – 灵活的硬实时网络框架
|
13天前
|
负载均衡 网络协议 应用服务中间件
【亮剑】在Linux中构建高可用性和高性能网络服务的负载均衡工具HAProxy、Nginx和Keepalived。
【4月更文挑战第30天】本文介绍了在Linux中构建高可用性和高性能网络服务的负载均衡工具HAProxy、Nginx和Keepalived。HAProxy是一个高性能的开源TCP和HTTP负载均衡器,适合处理大量并发连接;Nginx是一个多功能Web服务器和反向代理,支持HTTP、HTTPS和TCP负载均衡,同时提供缓存和SSL功能;Keepalived用于监控和故障切换,通过VRRP实现IP热备份,保证服务连续性。文中详细阐述了如何配置这三个工具实现负载均衡,包括安装、配置文件修改和启动服务,为构建可靠的负载均衡系统提供了指导。
|
16天前
|
Rust 前端开发 安全
【专栏】WebAssembly将支持更多语言,结合低代码平台
【4月更文挑战第27天】WebAssembly是种虚拟机格式,用于在浏览器中运行编译后的C/C++、Rust等语言代码,提供高性能、高可移植性和安全性。其优势在于更快的执行速度、跨平台兼容及安全的沙箱环境。广泛应用在游戏开发、图形处理、计算机视觉等领域。未来,WebAssembly将支持更多语言,结合低代码平台,优化开发流程,同时应对优化编译和安全性的挑战,引领高性能网络应用新时代。
|
1月前
|
网络协议 Java API
Python网络编程基础(Socket编程)Twisted框架简介
【4月更文挑战第12天】在网络编程的实践中,除了使用基本的Socket API之外,还有许多高级的网络编程库可以帮助我们更高效地构建复杂和健壮的网络应用。这些库通常提供了异步IO、事件驱动、协议实现等高级功能,使得开发者能够专注于业务逻辑的实现,而不用过多关注底层的网络细节。
|
1月前
|
分布式计算 监控 Hadoop
Hadoop【基础知识 02】【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
【4月更文挑战第3天】Hadoop【基础知识 02】【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
58 0
|
2月前
|
XML 网络协议 前端开发
Netty网络框架(三)
Netty网络框架
29 1
|
2月前
|
存储 编解码 网络协议
Netty网络框架(二)
Netty网络框架
37 0
|
存储 设计模式 网络协议
Netty网络框架(一)
Netty网络框架
40 1