karma303 发表于 2016-05-14 18:48

请问RTL8139在接收好一个package后,会自动继续接收下一个吗?

本帖最后由 karma303 于 2016-05-14 18:49 编辑

想象一个情景:
RTL8139从网线上完整的收到一个package,放在ring buffer里。这时当然会触发中断(ROK)。
但是,cpu很忙(例如处在一个critial area的cli状态),无法及时去读这个package。
那么,网卡会继续从网线上接收数据吗?
还是说,网卡在cpu响应这次中断之前,会暂停接收数据?

如果继续接收,那么新收到的package是放在RBSTART位置上,覆盖前一个package?还是接着放到第一个package后面呢?

如果接着放在第一个package后面,最后不断累积,会不会ring buffer溢出呢?或者说,硬件写入模式是回绕的话,是不是可能最终还是可能把第一个包给覆盖呢?


我产生这个疑惑,主要是因为linux内核里针对8139的这段驱动代码: while((readb(ioaddr + CR) & RxBufEmpty) == 0)
    {
      unsigned int rx_status;
      unsigned short rx_size;
      unsigned short pkt_size;
      struct sk_buff *skb;

      if(tp->cur_rx > RX_BUF_LEN)
            tp->cur_rx = tp->cur_rx % RX_BUF_LEN;

      /* TODO: need to convert rx_status from little to host endian
      * XXX: My CPU is little endian only
      */
      rx_status = *(unsigned int*)(tp->rx_ring + tp->cur_rx);
      rx_size = rx_status >> 16;

      /* first two bytes are receive status register
      * and next two bytes are frame length
      */
      pkt_size = rx_size - 4;

      /* hand over packet to system */
      skb = dev_alloc_skb (pkt_size + 2);
      if (skb) {
            skb->dev = dev;
            skb_reserve (skb, 2); /* 16 byte align the IP fields */

            eth_copy_and_sum(
            skb, tp->rx_ring + tp->cur_rx + 4, pkt_size, 0);

            skb_put (skb, pkt_size);
            skb->protocol = eth_type_trans (skb, dev);
            netif_rx (skb);

            dev->last_rx = jiffies;
            tp->stats.rx_bytes += pkt_size;
            tp->stats.rx_packets++;
      }
      else {
            LOG_MSG("Memory squeeze, dropping packet.\n");
            tp->stats.rx_dropped++;
      }

      /* update tp->cur_rx to next writing location* /
      tp->cur_rx = (tp->cur_rx + rx_size + 4 + 3) & ~3;

      /* update CAPR */
      writew(tp->cur_rx, ioaddr + CAPR);
      }
    }大家注意到没有,这是用一个while循环,意思是,ring buffer里可能不止一个package里。
但是!! 8139每收到一个package就会报告给cpu一个ROK中断,然后就被处理掉了。 所以,ring buffer里怎么可能出现堆积了两个以上的package的情形呢?

mordorwww 发表于 2016-05-16 09:23

放在缓存队列啊, ring buffer

nswcfd 发表于 2016-05-16 18:20

如果按照pkt arrive的速度去interrupt cpu,那cpu基本上就啥都做不了了。

NAPI本来就是关了中断去轮询,只有ring里有很多报文去轮询才有意义么。
页: [1]
查看完整版本: 请问RTL8139在接收好一个package后,会自动继续接收下一个吗?