rcu学习心得

来源:百度文库 编辑:神马文学网 时间:2024/04/28 06:10:08
void __dev_remove_pack(struct packet_type *pt)
{
 struct list_head *head;
 struct packet_type *pt1; spin_lock_bh(&ptype_lock); if (pt->type == htons(ETH_P_ALL))
  head = &ptype_all;
 else
  head = &ptype_base[ntohs(pt->type) & PTYPE_HASH_MASK]; list_for_each_entry(pt1, head, list) {
  if (pt == pt1) {
   list_del_rcu(&pt->list);
   goto out;
  }
 } printk(KERN_WARNING "dev_remove_pack: %p not found.\n", pt);
out:
 spin_unlock_bh(&ptype_lock);
} 从上面的代码看出,当需要遍历删除hash表的时候,只需要在相应的桶上加写锁就可以了, spin_lock_bh(&ptype_lock); 在读取的时候需要加上读临界锁就可以了   static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
{
 struct packet_type *ptype;#ifdef CONFIG_NET_CLS_ACT
 if (!(skb->tstamp.tv64 && (G_TC_FROM(skb->tc_verd) & AT_INGRESS)))
  net_timestamp(skb);
#else
 net_timestamp(skb);
#endif rcu_read_lock();
 list_for_each_entry_rcu(ptype, &ptype_all, list) {
  /* Never send packets back to the socket
   * they originated from - MvS (miquels@drinkel.ow.org)
   */
  if ((ptype->dev == dev || !ptype->dev) &&
      (ptype->af_packet_priv == NULL ||
       (struct sock *)ptype->af_packet_priv != skb->sk)) {
   struct sk_buff *skb2= skb_clone(skb, GFP_ATOMIC);
   if (!skb2)
    break;   /* skb->nh should be correctly
      set by sender, so that the second statement is
      just protection against buggy protocols.
    */
   skb_reset_mac_header(skb2);   if (skb_network_header(skb2) < skb2->data ||
       skb2->network_header > skb2->tail) {
    if (net_ratelimit())
     printk(KERN_CRIT "protocol %04x is "
            "buggy, dev %s\n",
            skb2->protocol, dev->name);
    skb_reset_network_header(skb2);
   }   skb2->transport_header = skb2->network_header;
   skb2->pkt_type = PACKET_OUTGOING;
   ptype->func(skb2, skb->dev, ptype, skb->dev);
  }
 }
 rcu_read_unlock();
}