免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5607 | 回复: 14
打印 上一主题 下一主题

[网络子系统] 网卡NAPI收包为何不放在硬中断中? [复制链接]

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-04-13 22:09 |只看该作者 |倒序浏览
中断模式收包放在在硬中断中,使用 backlog队列来缓存
NAPI模式收包缺放在在软中断中, 不再使用本CPU的队列来缓存。收一个包处理一个包
NAPI为何不也在硬中断中轮询收包,收的包都缓存在队列,收完后再处理

论坛徽章:
0
2 [报告]
发表于 2013-04-14 10:33 |只看该作者
我记得NAPI就是为了使用轮询来减少中断数,提高效率。
硬中断要简、短、快,同样的工作(比如轮询收包)能放在下半部的尽量放在下半部。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
3 [报告]
发表于 2013-04-14 12:37 |只看该作者
lenky0401 发表于 2013-04-14 10:33
我记得NAPI就是为了使用轮询来减少中断数,提高效率。
硬中断要简、短、快,同样的工作(比如轮询收包)能 ...


硬中断里多收几个包烧不了几个cpu cycle 吧

一般的网卡都是 DMA ring buffer 队列, 如果buffer里本来就有几个包,难道硬中断就只收一个包,对其它的包视而不见?

论坛徽章:
0
4 [报告]
发表于 2013-04-14 12:59 |只看该作者
mordorwww 发表于 2013-04-14 12:37
硬中断里多收几个包烧不了几个cpu cycle 吧

一般的网卡都是 DMA ring buffer 队列, 如果buffer里本 ...

关键是napi模式下队列上没有包了也得等着,直到配额完成(达到配额时间或收到配额量的包),这个过程是比较耗时的,放在硬中断中不合适,而如果减少配额则poll变的没有意义,无法达到减少网卡中断的目的

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
5 [报告]
发表于 2013-04-14 14:57 |只看该作者
junnyg 发表于 2013-04-14 12:59
关键是napi模式下队列上没有包了也得等着,直到配额完成(达到配额时间或收到配额量的包),这个过程是比 ...



不至于吧,没包还把CPU霸占着?

论坛徽章:
0
6 [报告]
发表于 2013-04-14 15:26 |只看该作者
回复 5# mordorwww
退出napi轮询状态有以下三个条件:
1. 处理时间超期
2. budget用完
3. 网卡收到的包少于预期收到的包,每次poll的时候会指定收一定数量的包,如果这次poll得到的包个数小于这个值,就打开网卡中断,停止napi轮询

我刚的说法有误,无包的时候确实会停止,但如果持续有包,会一直poll到budget用完或超时
static void net_rx_action(struct softirq_action *h)
{
        struct list_head *list = &__get_cpu_var(softnet_data).poll_list;
        unsigned long time_limit = jiffies + 2;
        int budget = netdev_budget;
        void *have;

        local_irq_disable();

        while (!list_empty(list)) { /*在这儿死循环,网卡注册的poll函数里会调用napi_complete将其从pool_list里删除*/
                struct napi_struct *n;
                int work, weight;

                /* If softirq window is exhuasted then punt.
                 * Allow this to run for 2 jiffies since which will allow
                 * an average latency of 1.5/HZ.
                 */
                if (unlikely(budget <= 0 || time_after(jiffies, time_limit)))/*这里判断是否超时或者用完budget,如果是,则poll结束*/
                        goto softnet_break;

                local_irq_enable();

                /* Even though interrupts have been re-enabled, this
                 * access is safe because interrupts can only add new
                 * entries to the tail of this list, and only ->poll()
                 * calls can remove this head entry from the list.
                 */
                n = list_first_entry(list, struct napi_struct, poll_list);

                have = netpoll_poll_lock(n);

                weight = n->weight;

                /* This NAPI_STATE_SCHED test is for avoiding a race
                 * with netpoll's poll_napi().  Only the entity which
                 * obtains the lock and sees NAPI_STATE_SCHED set will
                 * actually make the ->poll() call.  Therefore we avoid
                 * accidently calling ->poll() when NAPI is not scheduled.
                 */
                work = 0;
                if (test_bit(NAPI_STATE_SCHED, &n->state)) {
                        work = n->poll(n, weight); /*这里调用网卡注册的poll函数进行收包*/
                        trace_napi_poll(n);
                }

                WARN_ON_ONCE(work > weight);

                budget -= work; /* budget减去本次收到的包*/

                local_irq_disable();

                /* Drivers must not modify the NAPI state if they
                 * consume the entire weight.  In such cases this code
                 * still "owns" the NAPI instance and therefore can
                 * move the instance around on the list at-will.
                 */
                if (unlikely(work == weight)) {
                        if (unlikely(napi_disable_pending(n))) {
                                local_irq_enable();
                                napi_complete(n);
                                local_irq_disable();
                        } else
                                list_move_tail(&n->poll_list, list);
                }

                netpoll_poll_unlock(have);
        }
out:
        local_irq_enable();

#ifdef CONFIG_NET_DMA
        /*
         * There may not be any more sk_buffs coming right now, so push
         * any pending DMA copies to hardware
         */
        dma_issue_pending_all();
#endif

        return;

softnet_break:
        __get_cpu_var(netdev_rx_stat).time_squeeze++;
        __raise_softirq_irqoff(NET_RX_SOFTIRQ);
        goto out;
}

以intel的82599网卡为例:
static int ixgbe_poll(struct napi_struct *napi, int budget)
{
        struct ixgbe_q_vector *q_vector =
                                container_of(napi, struct ixgbe_q_vector, napi);
        struct ixgbe_adapter *adapter = q_vector->adapter;
        int tx_clean_complete, work_done = 0;

#ifdef CONFIG_IXGBE_DCA
        if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
                ixgbe_update_tx_dca(adapter, adapter->tx_ring[0]);
                ixgbe_update_rx_dca(adapter, adapter->rx_ring[0]);
        }
#endif

        tx_clean_complete = ixgbe_clean_tx_irq(q_vector, adapter->tx_ring[0]);
        ixgbe_clean_rx_irq(q_vector, adapter->rx_ring[0], &work_done, budget);

        if (!tx_clean_complete)
                work_done = budget;

        /* If budget not fully consumed, exit the polling mode */
        if (work_done < budget) {   /* 这里网卡如果没有收到预期的包个数,则会打开网卡中断,停止napi轮询 */
                napi_complete(napi);
                if (adapter->rx_itr_setting & 1)
                        ixgbe_set_itr(adapter);
                if (!test_bit(__IXGBE_DOWN, &adapter->state))
                        ixgbe_irq_enable_queues(adapter, IXGBE_EIMS_RTX_QUEUE);

        }
        return work_done;
}

   

论坛徽章:
0
7 [报告]
发表于 2013-04-18 03:28 |只看该作者
回复 1# mordorwww

第一个原因,收包可能会涉及到对ring重填,可能要分配内存
第二个原因,可能因为实际处理能力不足,收到的包最后还是要丢掉。浪费时间
第三个原因,按你的方法,最后处理方式还是没有变化,白添了操作。浪费时间

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
8 [报告]
发表于 2013-04-18 09:16 |只看该作者
kudakitsune 发表于 2013-04-18 03:28
回复 1# mordorwww

第一个原因,收包可能会涉及到对ring重填,可能要分配内存


第一个原因,收包可能会涉及到对ring重填,可能要分配内存
                        有什么问题?
                               如果不用NAPI,事实上还是硬中断收包,硬中断仍然要做这些情
第二个原因,可能因为实际处理能力不足,收到的包最后还是要丢掉。浪费时间
                       浪费的只是收包,收包动作本省就是非常轻量的。
                       包送到了进程,可能因为实际处理能力不足,进程处理不了,仍然要丢掉。仍然要浪费时间

第三个原因,按你的方法,最后处理方式还是没有变化,白添了操作。浪费时间
                       没看明白问题在哪里

论坛徽章:
7
丑牛
日期:2013-10-18 14:43:21技术图书徽章
日期:2013-11-03 09:58:03辰龙
日期:2014-01-15 22:57:50午马
日期:2014-09-15 07:04:39丑牛
日期:2014-10-16 14:25:222015年亚洲杯之伊朗
日期:2015-03-16 10:24:352015亚冠之城南
日期:2015-05-31 09:52:32
9 [报告]
发表于 2013-04-18 16:14 |只看该作者
回复 4# junnyg


    timeout

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-13 06:20:00数据库技术版块每日发帖之星
日期:2016-06-15 06:20:00数据库技术版块每日发帖之星
日期:2016-06-16 06:20:00数据库技术版块每日发帖之星
日期:2016-06-18 06:20:00程序设计版块每日发帖之星
日期:2016-06-27 06:20:00程序设计版块每日发帖之星
日期:2016-07-09 06:20:00IT运维版块每日发帖之星
日期:2016-07-15 06:20:00IT运维版块每日发帖之星
日期:2016-07-27 06:20:00程序设计版块每日发帖之星
日期:2016-08-18 06:20:00
10 [报告]
发表于 2013-12-08 00:20 |只看该作者
木有答案,顶上来
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP