深入理解Linux網路技術內幕-關鍵資料結構(四)

來源:互聯網
上載者:User

緩衝區的複製和拷貝

當一個緩衝區需要被特別處理時,可能需要修改sk_buff描述符的內容,但核心不需要完全拷貝sk_buff結構和相關聯的資料緩衝區。為了提高效率,核心可以只複製原始值,也就是拷貝sk_buff結構,然後增加資料緩衝區的引用計數,防止被釋放。    當一個資料包需要被傳輸給多個接受者,如協議處理常式或多個網路分流器時,就需要使用資料包複製技術。    sk_buff的複製沒有連結到任何錶,而且也沒有引用通訊端的擁有者。skb->cloned欄位在複製的和原來的結構豬都設定為1.複製的skb->users設定為1,但對資料緩衝區的引用計數會遞增,因為又有一個sk_buff結構指向這個資料區。skb_clone函數可用於檢查一個skb緩衝區的複製狀態。skb_share_check函數檢查skb->users引用計數是否為1,當不為1時,則說明這個skb是共用的,複製一個新的skb返回,同時將原來的skb引用計數減一。否則直接返回原來的skb。
當一個緩衝區被複製是,資料區塊的內容不能修改,因此訪問該資料的代碼不需要上鎖機制。當若函數不僅需要修改sk_buff結構體的欄位,還需要修改資料時,就必須連資料緩衝區一起複製。這種情況有兩種選擇:若只需要修改skb->head和skb->end地區的資料內容,則可以使用pskb_copy只複製這個地區。若需要修改分區資料區塊中的內容,則需要使用skb_copy將分區地區的資料一起複製。在skb_shared_info結構中也可以包含一個sk_buff結構列表frag_list。以下分別為pskb_copy和skb_copy函數的操作結果:常見sk_buff元素隊列的管理函數skb_queue_head_init:對skb_buff_head隊列頭指標進行初始化skb_queue_head、skb_queue_tail:把一個sk_buff添加到隊列頭或尾skb_dequeue、skb_dequeue_tail:將一個sk_buff從隊列頭或尾移除skb_queue_purge:把隊列變為空白隊列skb_queue_walk:遍曆隊列中的每個元素
這類函數必須以原子方式執行,所以會擷取sk_buff_head隊列頭結構的自旋鎖
  1. void skb_queue_head(struct sk_buff_head *list, struct
    sk_buff *newsk)
  2. {
  3.     unsigned long flags;

  4.     spin_lock_irqsave(&list->lock, flags);
  5.     __skb_queue_head(list, newsk);
  6.     spin_unlock_irqrestore(&list->lock, flags);
  7. }
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.