philarlala 发表于 2016-06-30 10:00

linux 对于lookback,tunnels 这些非物理设备的数据包的发送是否没有触发软中断的?

分析2.3.32内核的 dev_queue_xmit 函数如下,注释:
int dev_queue_xmit(struct sk_buff *skb)
{
      struct net_device *dev = skb->dev;
      struct netdev_queue *txq;
      struct Qdisc *q;
      int rc = -ENOMEM;

      ………………

gso:
/* Disable soft irqs for various locks below. Also
         * stops preemption for RCU.
         */
      rcu_read_lock_bh();

      txq = dev_pick_tx(dev, skb);
      q = rcu_dereference(txq->qdisc);

#ifdef CONFIG_NET_CLS_ACT
      skb->tc_verd = SET_TC_AT(skb->tc_verd, AT_EGRESS);
#endif
      if (q->enqueue) {
                rc = __dev_xmit_skb(skb, q, dev, txq);/*这里会调用到netif_schedule,先放去softnet_data,
                                                                           *然后raise softirq NET_TX_SOFTIRQ,会先软中断,再到驱动发送函数
                                                                           */
                goto out;
      }

      /* The device has no queue. Common case for software devices:
         loopback, all the sorts of tunnels...

         Really, it is unlikely that netif_tx_lock protection is necessary
         here.(f.e. loopback and IP tunnels are clean ignoring statistics
         counters.)
         However, it is possible, that they rely on protection
         made by us here.

         Check this and shot the lock. It is not prone from deadlocks.
         Either shot noqueue qdisc, it is even simpler 8)
         */
      if (dev->flags & IFF_UP) {/*处理没有queue的设备的分支*/
               ………………

                        if (!netif_tx_queue_stopped(txq)) {
                              rc = NET_XMIT_SUCCESS;
                              if (!dev_hard_start_xmit(skb, dev, txq)) { /*直接调用了驱动的发送函数*/
                                        HARD_TX_UNLOCK(dev, txq);
                                        goto out;
                              }
                        }
                        
               ………………
      }

      rc = -ENETDOWN;
      rcu_read_unlock_bh();

out_kfree_skb:
      kfree_skb(skb);
      return rc;
out:
      rcu_read_unlock_bh();
      return rc;
}

问题如题

nswcfd 发表于 2016-06-30 17:54

1,对于有queue的情况,__dev_xmit_skb【一般】跟TX_SOFTIRQ没有【直接】关系吧?
除非tc的流控算法有延迟发送的情况,或者__qdisc_run跑的时间太长也是触发TX_SOFTIRQ的一种情况。

2. 对于没有queue的情况,直接调用drivre的xmit,跟TX_SOFTIRQ没有关系。
不过,取决于xmit的写法,
* 如果直接调用netif_receive_skb,不考虑rps的情况下,可以认为跟RX_SOFTIRQ没有关系。
* 通常虚拟device会调用netif_rx,通过enque_to_backlog会有RX_SOFTIRQ的调度产生。

philarlala 发表于 2016-07-01 09:31

是的,再仔细看了一下发送确实是这样的,接收的话应该是用napi的方式也会触发NET_RX_SOFTIRQ 吧回复 2# nswcfd


   

nswcfd 发表于 2016-07-01 11:30

是的,backlog dev就是留给netif_rx用的(把之前的非NAPI方式过渡到NAPI方式)

philarlala 发表于 2016-07-01 11:38

如果是直接发送,不就会频繁的触发硬中断,不是应该触发个软中断,让数据包积累到一定程度,或者等一段时间,再触发硬中断,发送,这样对大流量的性能更好吗?就像接收那样回复 4# nswcfd


   

nswcfd 发表于 2016-07-01 17:49

“直接发送”是针对哪种driver说的?

1. 像loopback/tunnel这样的virtual device本来就没有硬中断的概念。

2. 对于physical driver(例如e1000/igb等),不考虑tc的影响的话,确实有这个可能性。

a.早期kernel给device提供的xmit API是面向单个skb的,而不是面向一批skb的,所以就算是使用软中断延迟或者其它批量化的发送手段,最终调用driver xmit接口仍然是packet by packet的,并不改变问题的性质。

b.比较新的内核,在skb上有一个xmit_more的标记,指示是否有后续报文,驱动可以利用这个标记来推迟寄存器(例如igb的TAIL指针)的更新。

c.大流量的情况下,连续向driver提交descriptor,或许hw有自己的机制,抑制tx interrupt产生的频率?(这句话没有根据……:-L)

d.某些驱动的某些版本,会在xmit内部做一些优化,每隔多少次才更新一下寄存器,dpdk就有点像这个模型。

nswcfd 发表于 2016-07-01 17:57

linux的tx bh解决的问题是:
1. 中断上下文释放的skb的安全回收;
2. 已暂停qdisc的重新调度;
http://lxr.free-electrons.com/source/net/core/dev.c#L3810

tx中断的优化貌似不在这个上下文解决?
页: [1]
查看完整版本: linux 对于lookback,tunnels 这些非物理设备的数据包的发送是否没有触发软中断的?