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

简介: 作者:gfree.wind@gmail.com 博客:blog.focus-linux.net linuxfocus.blog.chinaunix.net 微博:weibo.com/glinuxer QQ技术群:4367710 前面e1000_probe的分析,按照Linux驱动框架,接下来就该e1000_open。


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

前面e1000_probe的分析,按照Linux驱动框架,接下来就该e1000_open。netmap并没有对e1000_open进行任何修改,而是改动了e1000_configure,其会被e1000_open及e1000_up调用。

e1000_configure的修改

按照惯例,还是先看diff文件

@@ -393,6 +397,10 @@ static void e1000_configure(struct e1000
    e1000_configure_tx(adapter);
    e1000_setup_rctl(adapter);
    e1000_configure_rx(adapter);
+#ifdef DEV_NETMAP
+   if (e1000_netmap_init_buffers(adapter))
+       return;
+#endif /* DEV_NETMAP */
    /* call E1000_DESC_UNUSED which always leaves
    * at least 1 descriptor unused to make sure
    * next_to_use != next_to_clean */ 

从diff文件可以看出,netmap替代了原有的e1000申请ring buffer的代码。如果e1000_netmap_init_buffers成功返回,e1000_configure就直接退出了。

接下来进入e1000_netmap_init_buffers:

/*
* Make the tx and rx rings point to the netmap buffers.
*/
static int e1000_netmap_init_buffers(struct SOFTC_T *adapter)
{
    struct e1000_hw *hw = &adapter->hw;
    struct ifnet *ifp = adapter->netdev;
    struct netmap_adapter* na = NA(ifp);
    struct netmap_slot* slot;
    struct e1000_tx_ring* txr = &adapter->tx_ring[0];
    unsigned int i, r, si;
    uint64_t paddr;

    /* 
    还记得前面的netmap_attach吗?
    所谓的attach,即申请了netmap_adapter,并将net_device->ax25_ptr保存了指针,并设置了NETMAP_SET_CAPABLE。
    因此这里做一个sanity check,以免影响正常的网卡驱动
    */
    if (!na || !(na->ifp->if_capenable & IFCAP_NETMAP))
        return 0;
    /* e1000_no_rx_alloc如其名,为一个不该调用的函数,只输出一行错误日志 */
    adapter->alloc_rx_buf = e1000_no_rx_alloc;
    for (r = 0; r num_rx_rings; r++) {
        struct e1000_rx_ring *rxr;
        /* 初始化对应的netmap对应的ring */
        slot = netmap_reset(na, NR_RX, r, 0);
        if (!slot) {
            D("strange, null netmap ring %d", r);
            return 0;
        }
        /* 得到e1000对应的ring */
        rxr = &adapter->rx_ring[r];

        for (i = 0; i count; i++) {
            // XXX the skb check and cleanup can go away
            struct e1000_buffer *bi = &rxr->buffer_info[i];
            /* 将当前的buff索引转换为netmap的buff索引 */
            si = netmap_idx_n2k(&na->rx_rings[r], i);
            /* 获得netmap的buff的物理地址 */
            PNMB(slot + si, &paddr);
            if (bi->skb)
                D("rx buf %d was set", i);
            bi->skb = NULL;
            // netmap_load_map(...)
            /* 现在网卡的这个buffer已经指向了netmap申请的buff地址了 */
            E1000_RX_DESC(*rxr, i)->buffer_addr = htole64(paddr);
        }

        rxr->next_to_use = 0;

        /* 
        下面这几行代码没看明白怎么回事。
        有明白的同学指点一下,多谢。
        */
        /* preserve buffers already made available to clients */
        i = rxr->count - 1 - na->rx_rings[0].nr_hwavail;
        if (i count;
        D("i now is %d", i);
        wmb(); /* Force memory writes to complete */
        writel(i, hw->hw_addr + rxr->rdt);
    }

    /* 
    初始化发送ring,与接收类似.
    区别在于没有考虑发送多队列。难道是因为e1000只可能是接收多队列,发送只可能是一个队列?
    这个问题不影响后面的代码阅读。咱们可以暂时将其假设为e1000只有一个发送队列
    */
    /* now initialize the tx ring(s) */
    slot = netmap_reset(na, NR_TX, 0, 0);
    for (i = 0; i num_tx_desc; i++) {
        si = netmap_idx_n2k(&na->tx_rings[0], i);
        PNMB(slot + si, &paddr);
        // netmap_load_map(...)
        E1000_TX_DESC(*txr, i)->buffer_addr = htole64(paddr);
    }
    return 1;
} 

e1000cleanrx_irq的修改

@@ -3952,6 +3973,11 @@ static bool e1000_clean_rx_irq(struct e1
    bool cleaned = false;
    unsigned int total_rx_bytes=0, total_rx_packets=0;

+#ifdef DEV_NETMAP
+   ND("calling netmap_rx_irq");
+   if (netmap_rx_irq(netdev, 0, work_done))
+       return 1; /* seems to be ignored */
+#endif /* DEV_NETMAP */
    i = rx_ring->next_to_clean;
    rx_desc = E1000_RX_DESC(*rx_ring, i);
    buffer_info = &rx_ring->buffer_info[i]; 

进入netmap_rx_irq, int netmaprxirq(struct ifnet *ifp, int q, int *workdone) { struct netmapadapter *na; struct netmap_kring *r; NMSELINFOT *main_wq;

 if (!(ifp->if_capenable & IFCAP_NETMAP))
        return 0;

    na = NA(ifp);

    /* 
    尽管函数名为rx,但实际上这个函数服务于rx和tx两种情况,用work_done做区分。
    */
    if (work_done) { /* RX path */
        r = na->rx_rings + q;
        r->nr_kflags |= NKR_PENDINTR;
        main_wq = (na->num_rx_rings > 1) ? &na->rx_si : NULL;
    } else { /* tx path */
        r = na->tx_rings + q;
        main_wq = (na->num_tx_rings > 1) ? &na->tx_si : NULL;
        work_done = &q; /* dummy */
    }


    /* 
    na->separate_locks只在ixgbe和bridge中会被设置为1。
    根据下面的代码,这个separate_locks表示多队列时,是每个队列使用一个锁。——这样可以提高性能
    其余的代码基本相同。都是唤醒等待数据的进程。
     */
    if (na->separate_locks) {
        mtx_lock(&r->q_lock);
        selwakeuppri(&r->si, PI_NET);
        mtx_unlock(&r->q_lock);
        if (main_wq) {
            mtx_lock(&na->core_lock);
            selwakeuppri(main_wq, PI_NET);
            mtx_unlock(&na->core_lock);
        }
    } else {
        mtx_lock(&na->core_lock);
        selwakeuppri(&r->si, PI_NET);
        if (main_wq)
            selwakeuppri(main_wq, PI_NET);
        mtx_unlock(&na->core_lock);
    }
    *work_done = 1; /* do not fire napi again */
    return 1;
} 


发送部分的修改与接收类似,就不重复了。
今天的学习,到此为止 (未完待续。。。)


目录
相关文章
|
7天前
|
存储 SQL 安全
网络安全与信息安全:守护数字世界的坚盾在这个高度数字化的时代,网络安全和信息安全已经成为个人、企业乃至国家安全的重要组成部分。本文将深入探讨网络安全漏洞、加密技术以及安全意识的重要性,旨在为读者提供一个全面的网络安全知识框架。
随着互联网技术的飞速发展,网络安全问题日益凸显。从个人信息泄露到企业数据被盗,再到国家安全受到威胁,网络安全事件层出不穷。本文将从网络安全漏洞的定义与分类入手,探讨常见的网络攻击手段;随后深入解析加密技术的原理及其在保护信息安全中的作用;最后强调提升公众与企业的安全意识的重要性,并提出具体的建议。通过综合运用这些知识点,我们可以更好地构建起一道道坚固的防线,守护我们的数字世界。
|
10天前
|
编解码 分布式计算 网络协议
Netty高性能网络框架(一)
Netty高性能网络框架(一)
完成切换网络+修改网络连接图标提示的代码框架
完成切换网络+修改网络连接图标提示的代码框架
|
4天前
|
存储 安全 网络安全
云计算与网络安全:技术融合下的信息安全新挑战
【9月更文挑战第29天】在数字化浪潮的推动下,云计算服务如雨后春笋般涌现,为各行各业提供了前所未有的便利和效率。然而,随着数据和服务的云端化,网络安全问题也日益凸显,成为制约云计算发展的关键因素之一。本文将从技术角度出发,探讨云计算环境下网络安全的重要性,分析云服务中存在的安全风险,并提出相应的防护措施。我们将通过实际案例,揭示如何在享受云计算带来的便捷的同时,确保数据的安全性和完整性。
|
4天前
|
SQL 安全 算法
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【9月更文挑战第29天】随着互联网的普及,网络安全问题日益严重。本文将介绍网络安全漏洞、加密技术以及安全意识等方面的内容,帮助读者了解网络安全的重要性,提高自身的网络安全意识。
|
4天前
|
存储 SQL 安全
网络安全与信息安全:构建安全防线的关键策略
本文深入探讨了网络安全与信息安全领域的核心要素,包括网络安全漏洞、加密技术以及安全意识的重要性。通过对这些关键领域的分析,旨在为读者提供一套综合性的防护策略,帮助企业和个人在日益复杂的网络环境中保障数据安全。
16 4
|
1天前
|
安全 网络协议 网络安全
网络安全与信息安全:漏洞、加密与意识的三重奏
【9月更文挑战第32天】在数字世界的交响乐中,网络安全是那不可或缺的乐章。本文将带您深入探索网络安全的三大主题:网络漏洞的识别与防范、加密技术的奥秘以及安全意识的重要性。通过深入浅出的方式,我们将一起揭开这些概念的神秘面纱,并学习如何在实际生活中应用它们来保护自己的数字足迹。让我们开始这场既刺激又富有教育意义的旅程,提升个人和组织的网络安全防御能力。
|
3天前
|
SQL 安全 程序员
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【9月更文挑战第30天】在数字化时代,网络安全和信息安全已成为全球关注的焦点。本文将探讨网络安全漏洞、加密技术以及提升安全意识的重要性。我们将通过代码示例,深入理解网络安全的基础知识,包括常见的网络攻击手段、防御策略和加密技术的实际应用。同时,我们还将讨论如何提高个人和企业的安全意识,以应对日益复杂的网络安全威胁。
|
2天前
|
SQL 安全 算法
数字时代的守护者:网络安全与信息安全的现代策略
【9月更文挑战第31天】在数字化时代,网络安全与信息安全成为保护个人隐私和企业资产的关键。本文将深入探讨网络安全漏洞的成因、加密技术的应用以及提升安全意识的重要性,旨在为读者提供防范网络威胁的策略和知识分享。
17 7
|
2天前
|
存储 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【9月更文挑战第31天】在数字化时代,网络安全和信息安全成为了我们生活中不可或缺的一部分。本文将从网络安全漏洞、加密技术和安全意识等方面进行知识分享,帮助读者更好地了解和保护自己的网络安全。
下一篇
无影云桌面