免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7087 | 回复: 2
打印 上一主题 下一主题

ip_rcv函数中为什么调用skb_share_check [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-03-21 14:25 |只看该作者 |倒序浏览
skb_share_check函数中,会判断skb->use是否等于1,如果不等于1,克隆skb包,创建新的skb结构体,并回收原有skb结构体

从收包角度看,什么情况下,use不等于1?
从发包角度看,什么情况下,use不等于1?
上述情况下,为什么要克隆skb包,回收原有skb结构体,如果仅仅脱离SOCKET,为什么不做Update操作?非得复制一份再删除?

还请各位高手多多帮忙!

  1. int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
  2. {
  3.          struct iphdr *iph;
  4.                  u32 len;

  5.         /* When the interface is in promisc. mode, drop all the crap
  6.          * that it receives, do not try to analyse it.
  7.          */
  8.         if (skb->pkt_type == PACKET_OTHERHOST)
  9.                 goto drop;

  10.                 if ((skb = skb_share_check(skb, CSP_GFP_ATOMIC)) == NULL) {
  11.                 IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS);
  12.                 goto out;
  13.         }
  14.                 ....
  15. }

  16. static inline struct sk_buff *skb_share_check(struct sk_buff *skb,
  17.                                               CSP_gfp_t pri)
  18. {
  19.         might_sleep_if(pri & __GFP_WAIT);
  20.         if (skb_shared(skb)) {
  21.                 struct sk_buff *nskb = skb_clone(skb, pri);
  22.                 kfree_skb(skb);
  23.                 skb = nskb;
  24.         }
  25.         return skb;
  26. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2011-03-25 09:07 |只看该作者
高手呢?难道没人能解决我的困惑?

论坛徽章:
0
3 [报告]
发表于 2011-03-27 12:06 |只看该作者
skb->usr就是一个很常用统计计数嘛,为0时表示没有任务hold skb,大于1时,表示多个任务hold,如果在你的任务处理skb时,有可能被抢占导致skb被释放,通常你要skb_get(),把计数加1。

对于接收,在dev层向L3发包时,如果不止ip协议,这时usr>1,当其它协议处理完后不至于把它释放。
对于发送,你搜一下,也比较多,也就是你希望你发包后,这个包不会被释放。

有的时候,我们自己的模块会想改变skb的内容,注意是skb本身的内容,不是buffer的内容,这个时候,因为有可能这个skb共享的(usr>1), 如果我们在自己的模块改了,就可能导致其它模块出错,因为其它模块共享这个skb,它不知道我们改了。因此,我们在改变skb时,一定要先判断这个skb是否共享,如果是,我们删除这个计数,再重新创建一个。表示我们不共享这个skb了。

这里可以多加一句,这只是skb的共享,如果我们模块想改变buffer,那还有函数来判断是否buffer是共享的,克隆就是这个情况,如果是cloned,则我们必须复制整个buffer,然后把该skb->cloned=0,旧的buffer计数减一。表示我们不再是cloned了。详见skb_cow等等函数
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP