久久精品在这里_成人99免费视频_国产激情视频一区二区在线观看_国产伦精品一区二区三区免费 _亚洲午夜免费福利视频_色狠狠色狠狠综合_av在线综合网_91毛片在线观看_欧美视频一区二区在线观看_极品美女销魂一区二区三区免费_国产亚洲欧美激情_在线免费观看不卡av_日韩不卡一区二区三区_91精品国产麻豆国产自产在线_亚洲国产精品一区二区久久恐怖片_a4yy欧美一区二区三区


曙海教育集團論壇Linux專區Linux驅動開發 → NAPI技術在Linux網絡驅動上的應用


  共有9762人關注過本帖樹形打印

主題:NAPI技術在Linux網絡驅動上的應用

美女呀,離線,留言給我吧!
wangxinxin
  1樓 個性首頁 | 博客 | 信息 | 搜索 | 郵箱 | 主頁 | UC


加好友 發短信
等級:青蜂俠 帖子:1393 積分:14038 威望:0 精華:0 注冊:2010-11-12 11:08:23
NAPI技術在Linux網絡驅動上的應用  發帖心情 Post By:2010-11-24 11:29:37

這個方法通常被網絡層在向驅動的接收循環隊列獲取新的數據包時刻調用,而驅動的接收循環隊列中可以向網絡層交付的包數量則在 dev->quota 字段中表示,我們來看 8139cp 中 POLL 的原型:

  static int cp_rx_poll (struct net_device *dev, int *budget)   

  參數 budget 的上層任務所需要底層傳遞的數據包的數量,這個數值不能超過netdev_max_backlog 的值。   

  總而言之,POLL 方法被網絡層調用,只負責按照網絡層的要求值("預算"值)提交對應數量的數據包。8139CP 的 POLL 方法注冊通常在設備驅動程序模塊初始化(調用 probe)的時候進行,如下:

  static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)

  {

  … …

  dev->poll = cp_rx_poll;

  … …

  }

  

  設備的 POLL 方法正如前所說的是被網絡層上的軟中斷 net_rx_action 調用,我們現在來看具體的流程:

  

  static int cp_rx_poll (struct net_device *dev, int *budget)

  {

   struct cp_private *cp = netdev_priv(dev);

   unsigned rx_tail = cp->rx_tail;

   /*設定每次進行調度的時候從設備發送到網絡層次最大的數據包的大小*/

  unsigned rx_work = dev->quota;

   unsigned rx;

  

  rx_status_loop:

   rx = 0;

  /*重新打開NIC中斷,在 cp_interrupt 中斷句柄中中斷關閉了,現在 POLl 已經開始處理環行緩沖隊列中的數據,

  所以中斷可以打開,準備接收新的數據包*/

   cpw16(IntrStatus, cp_rx_intr_mask);  

   while (1) {/*POLL循環的開始*/

   u32 status, len;

   dma_addr_t mapping;

   struct sk_buff *skb, *new_skb;

   struct cp_desc *desc;

   unsigned buflen;

  /*從下標為rx_tail的內存中的環行緩沖隊列接收隊列rx_skb上"摘下"套接字緩沖區*/

   skb = cp->rx_skb[rx_tail].skb;

   if (!skb)

   BUG();

  

   desc = &cp->rx_ring[rx_tail];

  /*檢查在 NIC 的環形隊列(rx_ring)上的最后的數據接收狀態,是否有出現接收或者 FIFO 的錯誤,是否*/

   status = le32_to_cpu(desc->opts1);

   if (status & DescOwn)

   break;

  

   len = (status & 0x1fff) - 4;

   mapping = cp->rx_skb[rx_tail].mapping;

  

   if ((status & (FirstFrag   LastFrag)) != (FirstFrag   LastFrag)) {

   /* we don't support incoming fragmented frames.

   * instead, we attempt to ensure that the

   * pre-allocated RX skbs are properly sized such

   * that RX fragments are never encountered

   */

   cp_rx_err_acct(cp, rx_tail, status, len);

   cp->net_stats.rx_dropped++;

   cp->cp_stats.rx_frags++;

   goto rx_next;

   }

  

   if (status & (RxError   RxErrFIFO)) {

   cp_rx_err_acct(cp, rx_tail, status, len);

   goto rx_next;

   }

  

   if (netif_msg_rx_status(cp))

   printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d\n",

   cp->dev->name, rx_tail, status, len);

  

   buflen = cp->rx_buf_sz + RX_OFFSET;

  /*創建新的套接字緩沖區*/

   new_skb = dev_alloc_skb (buflen);

   if (!new_skb) {

   cp->net_stats.rx_dropped++;

   goto rx_next;

   }

  

   skb_reserve(new_skb, RX_OFFSET);

   new_skb->dev = cp->dev;

  /*解除原先映射的環行隊列上的映射區域*/

   pci_unmap_single(cp->pdev, mapping,

   buflen, PCI_DMA_FROMDEVICE);

  /*檢查套接字緩沖區(sk_buff)上得到的數據校驗和是否正確*/

   /* Handle checksum offloading for incoming packets. */

   if (cp_rx_csum_ok(status))

   skb->ip_summed = CHECKSUM_UNNECESSARY;

   else

   skb->ip_summed = CHECKSUM_NONE;

  /*按照數據的實際大小重新定義套接字緩沖區的大小*/

   skb_put(skb, len);  

   mapping =

   cp->rx_skb[rx_tail].mapping =

  /*DMA影射在前面新創建的套接字緩沖區虛擬地址new_buf->tail到實際的物理地址上,

  并且把這個物理地址掛在接收緩沖區的隊列中*/

   pci_map_single(cp->pdev, new_skb->tail,

   buflen, PCI_DMA_FROMDEVICE);

  /*把新建立的緩沖區的虛擬地址掛在接收緩沖區的隊列中,在下一次訪問rx_skb數組的這個結構時候,

  POLL方法會從這個虛擬地址讀出接收到的數據包*/

   cp->rx_skb[rx_tail].skb = new_skb;

  /*在cp_rx_skb調用netif_rx_skb,填充接收數據包隊列,等待網絡層在Bottom half隊列中調用ip_rcv接收網絡數據,

  這個函數替代了以前使用的netif_rx*/

   cp_rx_skb(cp, skb, desc);

   rx++;  

  rx_next:

  /*把前面映射的物理地址掛在NIC設備的環行隊列上(也就是rx_ring上,它是在和NIC中物理存儲區進行了DMA映射的,

  而不是驅動在內存中動態建立的),準備提交給下層(NIC)進行數據傳輸*/

   cp->rx_ring[rx_tail].opts2 = 0;

   cp->rx_ring[rx_tail].addr = cpu_to_le64(mapping);

  /*在相應的傳輸寄存器中寫入控制字,把rx_ring的控制權從驅動程序交還給NIC硬件*/

   if (rx_tail == (CP_RX_RING_SIZE - 1))

   desc->opts1 = cpu_to_le32(DescOwn   RingEnd  

   cp->rx_buf_sz);

   else

   desc->opts1 = cpu_to_le32(DescOwn   cp->rx_buf_sz);

  /*步進到下一個接收緩沖隊列的下一個單元*/

   rx_tail = NEXT_RX(rx_tail);

  

   if (!rx_work--)

   break;  

   cp->rx_tail = rx_tail;

  /*遞減配額值quota,一旦quota遞減到0表示這次的POLL傳輸已經完成了使命,

  就等待有數據到來的時候再次喚醒軟中斷執行POLL方法*/

   dev->quota -= rx;

   *budget -= rx;  

   /* if we did not reach work limit, then we're done with

   * this round of polling

   */

   if (rx_work) {

  /*如果仍然有數據達到,那么返回POLL方法循環的開始,繼續接收數據*/

   if (cpr16(IntrStatus) & cp_rx_intr_mask)

   goto rx_status_loop;

  /*這里表示數據已經接收完畢,而且沒有新的接收中斷產生了,這個時候使能NIC的接收中斷,

  并且調用__netif_rx_complete把已經完成POLL的設備從poll_list上摘除,等待下一次中斷產生的時候,

  再次把設備掛上poll_list隊列中。*/

   local_irq_disable();

   cpw16_f(IntrMask, cp_intr_mask);

   __netif_rx_complete(dev);

   local_irq_enable();  

   return 0; /* done */

   }  

   return 1; /* not done */

  }  

  其他的使用 NAPI 的驅動程序和 8139CP 大同小異,只是使用了網絡層專門提供的 POLL 方法--proecess_backlog(/net/dev.c),在 NIC 中斷接收到了數據包后,調用網絡層上的 netif_rx(/net/dev.c)將硬件中斷中接收到數據幀存入 sk_buff 結構, 然后檢查硬件幀頭,識別幀類型, 放入接收隊列(softnet_data 結構中的 input_pkt_queue 隊列上), 激活接收軟中斷作進一步處理. 軟中斷函數(net_rx_action)提取接收包,而 process_backlog(也就是 POLL 方法)向上層提交數據。


支持(0中立(0反對(0單帖管理 | 引用 | 回復 回到頂部

返回版面帖子列表

NAPI技術在Linux網絡驅動上的應用








簽名
久久精品在这里_成人99免费视频_国产激情视频一区二区在线观看_国产伦精品一区二区三区免费 _亚洲午夜免费福利视频_色狠狠色狠狠综合_av在线综合网_91毛片在线观看_欧美视频一区二区在线观看_极品美女销魂一区二区三区免费_国产亚洲欧美激情_在线免费观看不卡av_日韩不卡一区二区三区_91精品国产麻豆国产自产在线_亚洲国产精品一区二区久久恐怖片_a4yy欧美一区二区三区
免费在线观看一区| 日韩aⅴ视频一区二区三区| 亚洲一区自拍偷拍| 亚洲一二三四久久| 一区二区三区中文字幕精品精品 | 久久久久久电影| 26uuu精品一区二区三区四区在线| 日韩精品中文字幕在线不卡尤物| 欧美r级在线观看| 久久久精品综合| 中文字幕在线观看一区二区| 一区二区三区视频在线观看| 性做久久久久久免费观看| 蜜桃视频第一区免费观看| 精品一区二区三区日韩| 国产成人av电影| 国产精品一 二 三| 欧美xxxx黑人又粗又长密月| 影音先锋欧美在线| 91精品国产综合久久婷婷香蕉 | 成人深夜福利app| 国产精品免费一区二区三区四区| 欧美日韩另类综合| 欧美性感一区二区三区| 精品国产精品一区二区夜夜嗨| 国产精品无圣光一区二区| 亚洲制服丝袜在线| 国内精品自线一区二区三区视频| jizzjizzjizz欧美| 日韩国产美国| 欧美一区二区三区播放老司机| 日本一区二区免费在线| 亚洲国产aⅴ天堂久久| 国产剧情一区二区三区| 国产精品区一区二区三含羞草| 一区高清视频| 久久夜色精品国产噜噜av| 亚洲午夜一区二区三区| 国产成人精品1024| 蜜桃网站成人| 日韩美女一区二区三区| 亚洲欧美一区二区三区孕妇| 激情综合网最新| 国产三区精品| 欧洲精品视频在线观看| 日韩亚洲欧美精品| 免费在线一区观看| 一区二区三区四区蜜桃| 久久色视频免费观看| 亚洲午夜精品在线| 国产91精品一区二区麻豆亚洲| 久久久久se| 欧美一区二区视频在线观看| 亚洲欧美一区二区三区国产精品| 国产一区欧美二区| 免费av一区二区三区| 日韩三级伦理片妻子的秘密按摩| 一区二区三区不卡视频| 99热国产精品| 欧美性一二三区| 一区二区成人在线视频| 99精品视频一区二区| 色综合天天综合网天天狠天天| 久久夜色精品国产噜噜av| 日本中文一区二区三区| 狠狠色综合一区二区| 日韩欧美美女一区二区三区| 午夜欧美一区二区三区在线播放| 99热在线国产| 日韩一级完整毛片| 亚洲超碰精品一区二区| 国产精品免费观看高清| 日韩欧美国产一区二区在线播放| 午夜精品久久久久久久99樱桃| 91首页免费视频| 日韩一区二区三区四区| 免费在线观看不卡| 婷婷精品国产一区二区三区日韩| 欧美韩日一区二区三区四区| 粉嫩绯色av一区二区在线观看| 在线观看日韩片| 亚洲图片你懂的| 成人欧美一区二区三区视频xxx | 欧美蜜桃一区二区三区| 亚洲高清久久久| 国产精品一区二区三区在线观| 日韩欧美国产一区在线观看| 日本vs亚洲vs韩国一区三区二区| 久久福利电影| 国产精品私人自拍| 99精品视频一区二区| 日韩欧美成人一区二区| 国产不卡免费视频| 日韩视频在线你懂得| 国产成人综合在线| 日韩视频一区二区三区在线播放| 狠狠狠色丁香婷婷综合久久五月| 色综合久久88色综合天天免费| 亚洲成人中文在线| 日韩一区免费观看| 亚洲国产精品人人做人人爽| 日韩wuma| 首页国产欧美日韩丝袜| 亚洲国产精品日韩| 丝袜诱惑制服诱惑色一区在线观看 | 国产精品福利一区| 国产伦理久久久| 国产精品色一区二区三区| 成人91免费视频| 中文字幕视频一区二区三区久| 精品一区二区三区视频日产| 国产精品第13页| 欧美一级二级三级| 亚洲一区二区精品久久av| 一区二区av| 麻豆精品一区二区三区| 91精品久久久久久久91蜜桃| 本田岬高潮一区二区三区| 国产午夜一区二区三区| 精品视频在线观看| 亚洲综合自拍偷拍| 91九色最新地址| 国产精品一区在线| 久久精品夜色噜噜亚洲a∨| 精品免费国产| 亚洲国产精品久久人人爱| 欧美性高清videossexo| 成人污污视频在线观看| 国产欧美日韩精品a在线观看| 激情五月综合色婷婷一区二区 | 精品日本一区二区三区| 亚洲国产cao| 欧美久久高跟鞋激| 91在线视频在线| 一区二区三区在线视频免费观看| 一本色道久久99精品综合| 精品一区二区免费视频| 久久免费看少妇高潮| 久久久精品动漫| 蜜桃av一区二区| 久久久www免费人成精品| 日本一区二区免费看| 久久99热狠狠色一区二区| 欧美成人一区二区三区片免费| 国产精品免费视频一区二区| 五月婷婷另类国产| 精品欧美一区二区在线观看| 欧美二区三区在线| 狠狠色狠狠色综合日日91app| 久久蜜桃av一区精品变态类天堂 | 国产九色sp调教91| 中文字幕一区在线| 欧美日韩国产精品成人| 99国产视频| 蜜桃视频在线观看一区二区| 精品日韩一区二区三区免费视频| 欧美精品免费观看二区| 精品一区二区av| 国产欧美日韩不卡免费| 色哟哟一区二区三区| 99国内精品久久| 日韩精品一二三四| 欧美国产一区二区| 欧美亚洲国产bt| 久久另类ts人妖一区二区| 精东粉嫩av免费一区二区三区| 欧美国产一区在线| 欧美亚洲高清一区| 精品欧美一区二区精品久久| 国内精品第一页| 一个色在线综合| 欧美一区日本一区韩国一区| 久久久久一区二区| 成人精品免费看| 奇米色一区二区| 亚洲激情在线激情| 欧美激情中文字幕一区二区| 色猫猫国产区一区二在线视频| 国产99在线免费| 国产jizzjizz一区二区| 天堂久久一区二区三区| 国产精品成人免费| 日韩欧美国产一区二区在线播放 | 久久一区二区三区av| 国产精品系列在线观看| 亚洲成a人片在线不卡一二三区| 久久精品一区八戒影视| 3atv在线一区二区三区| 中文字幕不卡每日更新1区2区| av成人综合网| 成人中文字幕合集| 激情久久五月天| 五月婷婷久久丁香| 亚洲一区免费在线观看| 国产精品拍天天在线| 久久久久久久久久美女| 欧美一区二区国产| 欧美久久一二区| 日本精品视频一区二区三区| 日韩欧美亚洲v片|