- 论坛徽章:
- 0
|
本帖最后由 ljbphoebe 于 2012-11-06 16:51 编辑
问:原来的skb哪去了?
ip_rcv函数处理从链路层来的skb数据包,该函数会检查skb是否被共享,如果被共享就clone一个skb,原来的skb的user引用计数减1。
如果skb的user引用数为3的话,那么就会进入skb_share_check中的if (skb_shared(skb)) 段中执行,就会clone 一个新的skb,然后kfree_skb(skb)将旧的skb的引用计数减1,user为2,
struct sk_buff *nskb = skb_clone(skb, pri);
kfree_skb(skb);
skb = nskb;
从代码上看,skb指针指向了新clone的skb,kfree_skb(skb)并没有真正释放原来skb,那么原来的skb哪去了呢?岂不是内核内存泄露了?谁知道这是为什么?谢谢~- int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
- {
- struct iphdr *iph;
- /* When the interface is in promisc. mode, drop all the crap
- * that it receives, do not try to analyse it.
- */
- if (skb->pkt_type == PACKET_OTHERHOST)
- goto drop;
- IP_INC_STATS_BH(IPSTATS_MIB_INRECEIVES);
- if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
- IP_INC_STATS_BH(IPSTATS_MIB_INDISCARDS);
- goto out;
- }
- ......
- }
- static inline struct sk_buff *skb_share_check(struct sk_buff *skb, int pri)
- {
- might_sleep_if(pri & __GFP_WAIT);
- if (skb_shared(skb)) {
- struct sk_buff *nskb = skb_clone(skb, pri);
- kfree_skb(skb);
- skb = nskb;
- }
- return skb;
- }
- static inline void kfree_skb(struct sk_buff *skb)
- {
- if (atomic_read(&skb->users) == 1 || atomic_dec_and_test(&skb->users))
- __kfree_skb(skb);
- }
复制代码 |
|