背景

前段时间在测试docker的网络性能的时候,发现了一个veth的性能问题,后来给docker官方提交了一个PR,参考set tx_queuelen to 0 when create veth device,引起了一些讨论。再后来,RedHat的网络专家Jesper Brouer 出来详细的讨论了一下这个问题。

可以看到,veth设备qdisc队列,而环回设备/桥接设备是没qdisc队列的,参考br_dev_setup函数。

内核实现

在注册(创建)设备时,qdisc设置为noop_qdisc, register_netdevice -> dev_init_scheduler

void dev_init_scheduler(struct net_device *dev)
{
dev->qdisc = &noop_qdisc;
netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc);
dev_init_scheduler_queue(dev, &dev->rx_queue, &noop_qdisc); setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev);
}

打开设备时,如果没有配置qdisc时,就指定为默认的pfifo_fast队列: dev_open -> dev_activate,

void dev_activate(struct net_device *dev)
{
int need_watchdog; /* No queueing discipline is attached to device;
create default one i.e. pfifo_fast for devices,
which need queueing and noqueue_qdisc for
virtual interfaces
*/ if (dev->qdisc == &noop_qdisc)
attach_default_qdiscs(dev);
...
} static void attach_default_qdiscs(struct net_device *dev)
{
struct netdev_queue *txq;
struct Qdisc *qdisc; txq = netdev_get_tx_queue(dev, 0); if (!netif_is_multiqueue(dev) || dev->tx_queue_len == 0) {
netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
dev->qdisc = txq->qdisc_sleeping;
atomic_inc(&dev->qdisc->refcnt);
} else {///multi queue
qdisc = qdisc_create_dflt(dev, txq, &mq_qdisc_ops, TC_H_ROOT);
if (qdisc) {
qdisc->ops->attach(qdisc);
dev->qdisc = qdisc;
}
}
} static void attach_one_default_qdisc(struct net_device *dev,
struct netdev_queue *dev_queue,
void *_unused)
{
struct Qdisc *qdisc; if (dev->tx_queue_len) {
qdisc = qdisc_create_dflt(dev, dev_queue,
&pfifo_fast_ops, TC_H_ROOT);
if (!qdisc) {
printk(KERN_INFO "%s: activation failed\n", dev->name);
return;
} /* Can by-pass the queue discipline for default qdisc */
qdisc->flags |= TCQ_F_CAN_BYPASS;
} else {
qdisc = &noqueue_qdisc;
}
dev_queue->qdisc_sleeping = qdisc;
}

创建noqueue

开始尝试直接删除设备默认的pfifo_fast队列,发现会出错:

# tc qdisc del dev vethd4ea root
RTNETLINK answers: No such file or directory
# tc -s qdisc ls dev vethd4ea
qdisc pfifo_fast 0: root refcnt 2 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 29705382 bytes 441562 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0

后来看到Jesper Brouer给出一个替换默认队列的方式,尝试了一下,成功完成。

替换默认的qdisc队列

# tc qdisc replace dev vethd4ea root pfifo limit 100
# tc -s qdisc ls dev vethd4ea
qdisc pfifo 8001: root refcnt 2 limit 100p
Sent 264 bytes 4 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
# ip link show vethd4ea
9: vethd4ea: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo master docker0 state UP mode DEFAULT qlen 1000
link/ether 3a:15:3b:e1:d7:6d brd ff:ff:ff:ff:ff:ff

修改队列长度

# ifconfig vethd4ea txqueuelen 0

删除qdisc

# tc qdisc del dev vethd4ea root
# ip link show vethd4ea
9: vethd4ea: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT
link/ether 3a:15:3b:e1:d7:6d brd ff:ff:ff:ff:ff:ff

可以看到,UP的veth设备成功修改成noqueue。

小结

总之,给虚拟网络设备创建默认的qdisc,是不太合理的。这会让虚拟机(或者容器)的网络瓶颈过早的出现在qdisc,而不是真实的物理设备(除非应用需要创建qdisc)。更多详细参考这里

本文转自https://hustcat.github.io/veth/

从veth看虚拟网络设备的qdisc的更多相关文章

  1. Linux 虚拟网络设备 veth-pair 详解,看这一篇就够了

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 前面这篇文章介 ...

  2. [转]UOS 中的虚拟网络设备

    随着网络技术,虚拟化技术的发展,越来越多的高级网络设备被加入了到了 Linux 中,这些设备在 UOS 中起到了广泛而关键的作用,包括 Open vSwitch.TAP 设备.Veth 设备等等,梳理 ...

  3. linux 虚拟网络设备的使用

    1. linux 常见虚拟网络设备分类 常见虚拟网络设备有:bridge, tun/tap, veth-pairs, macvlan, macvtap等.有一篇博文写的挺好的,图文并茂:虚拟网络设备, ...

  4. 云计算底层技术-虚拟网络设备(Bridge,VLAN)( 转发)

    云计算底层技术-虚拟网络设备(Bridge,VLAN) Posted on September 24, 2017 by opengers in openstack openstack底层技术-各种虚拟 ...

  5. Linux 虚拟网络设备详解之 Bridge 网桥

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 前面几篇文章介 ...

  6. 【转】TUN/TAP虚拟网络设备

    转: 原文:https://www.cnblogs.com/wyzhou/p/9286864.html ------------------------------------------------ ...

  7. [转]Linux虚拟网络设备之tun/tap

    转, 原文:https://segmentfault.com/a/1190000009249039 -------------------------------------------------- ...

  8. 一文总结 Linux 虚拟网络设备 eth, tap/tun, veth-pair

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. Linux 虚 ...

  9. [原创] 详解云计算网络底层技术——虚拟网络设备 tap/tun 原理解析

    本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 在云计算时代, ...

随机推荐

  1. windows Path变量优先级

    系统>用户 且第一次配置无需重启即可使用 如遇到升级版本,需要重新配置Path,则需要重启方可生效~~

  2. GSM Hacking Part② :使用SDR捕获GSM网络数据并解密

    0×00 在文章第一部分 GSM Hacking Part① :使用SDR扫描嗅探GSM网络 搭建了嗅探GSM流量的环境,在第二部中,我们来讨论如何捕获发短信以及通话过程中的流量,从捕获到的数据中解密 ...

  3. C# 时间计算 今天、昨天、前天、明天 一个月的开始日期与结束日期

    C# 时间计算    今天.昨天.前天.明天   class Program    {        static void Main(string[] args)        {          ...

  4. SQL注入的分类

    基于从服务器接收到的响应    基于错误的SQL注入    联合查询的类型    堆查询注射    SQL盲注        基于布尔SQL盲注        基于时间的SQL盲注        基于 ...

  5. ES5 对数组方法的扩展 以及 正则表达式

    ES5 对数组的扩展 forEach map some every indexOf lastIndexOf forEach 与 map 语法: 数组.forEach(function ( v, i ) ...

  6. Android ListView 多样式Item的一个注意点:(

    闲来无事,在写一个多样式Item的ListView的Demo时,遇到了一个以前没遇过的问题; ╮( ̄▽ ̄")╭ 我们知道,ListView里可以有多种样式的item, 实现只需要重写: @O ...

  7. Jquery和Javascript 实际项目中写法基础-弹出窗和弹出层 (4)

     一.实际项目中有很多如下界面效果.    二.该效果可以归结为弹出窗或者弹出层来实现的,为什么这么说?看如下代码:      <!DOCTYPE html> <html> & ...

  8. 10 条有趣的 Linux 命令

    在终端工作是一件很有趣的事情.今天,我们将会列举一些有趣得为你带来欢笑的Linux命令. 1. rev 创建一个文件,在文件里面输入几个单词,rev命令会将你写的东西反转输出到控制台. # rev & ...

  9. win32记事本程序(二)

    遇到一个较大的难题,做记事本要不要使用edit或者是richedit控件呢.如果用控件的话感觉没什么挑战,不用控件,现有的参考资料仅有<windows程序设计>第六章的TYPER程序,这个 ...

  10. qt 设置等待事件

    QElapsedTimer et;et.start();while(et.elapsed() < 1000)     QCoreApplication::processEvents();