⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ieee80211_skb.c.svn-base

📁 最新之atheros芯片driver source code, 基于linux操作系统,內含atheros芯片HAL全部代码
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
		skb_print_message(0 /* show_counter */, 			skb, func, line,			"ERROR: Untracked skb received.  Probable duplicate free error!");		dump_stack();		return;	}	/* If free is unacceptable for current user count, report the error. */	if (atomic_read(&skb->users) < 1) {		skb_print_message(0 /* show_counter */, 			skb, func, line,			"ERROR: free an skb with %d users", 			atomic_read(&skb->users));		dump_stack();		return;	}        if (skb_shared(skb)) {		atomic_dec(&skb_refs_counter);		print_skb_refchange_message(skb, -1, func2, line2);	}	else {		if (SKB_NI(skb) != NULL) {			printk(KERN_ERR "%s:%d - ERROR: non-NULL node pointer in %p, %p<" MAC_FMT ">!  "					"Driver Leak Detected!\n", 			       __func__, __LINE__, 			       skb, SKB_NI(skb), MAC_ADDR(SKB_NI(skb)->ni_macaddr));			dump_stack();			/* Allow the leak and let programmer fix it, but do not			 * report it again in the destructor. */			SKB_NI(skb) = NULL;		}		untrack_skb(skb, -1, func, line);	}#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)	if ((in_irq() || irqs_disabled()) && 			(type == UNREF_USE_KFREE_SKB || 			 type == UNREF_USE_DEV_KFREE_SKB)) {		skb_print_message(0 /* show_counter */, 			skb, func, line,			"ERROR: free an skb in interrupt context using a non-"			"safe form of skb free function.");		type = UNREF_USE_DEV_KFREE_SKB_ANY;		dump_stack();	}#endif	switch (type) {	case UNREF_USE_DEV_KFREE_SKB_ANY:		dev_kfree_skb_any(skb);		break;	case UNREF_USE_DEV_KFREE_SKB_IRQ:		dev_kfree_skb_irq(skb);		break;	case UNREF_USE_DEV_KFREE_SKB:		/* NOTE: dev_kfree_skb is a macro pointing to kfree_skb, so		 * fallthrough... */	case UNREF_USE_KFREE_SKB:		/* fallthrough */	default:		kfree_skb(skb);		break;	}}/* Assumes SKB reference counter has already been updated and reports count as * atomic_read(&skb->users). */static struct sk_buff *ref_skb(struct sk_buff *skb, 	const char *func, int line) {	if (NULL == skb) {		skb_print_message(0 /* show_counter */, 			skb, func, line,			"ERROR: NULL skb received.  No changes made.");		dump_stack();		return NULL;	}	if (!M_FLAG_GET(skb, M_SKB_TRACKED)) {		skb_print_message(0 /* show_counter */, 			skb, func, line,			"ERROR: Untracked skb received.  Probable use after free!  "			"No changes made.");		dump_stack();		return skb;	}	print_skb_refchange_message(skb, 0, func, line);	return skb;}#endif /* #ifdef IEEE80211_DEBUG_REFCNT *//******************************************************************************* * Public API ******************************************************************************//* ieee80211_dev_kfree_skb will release one reference from SKB. * If SKB refcount is going to zero: *  - Free the node reference and set it to null. *  - Break the linked list, clearing next skb's prev pointer if possible. */void ieee80211_dev_kfree_skb(struct sk_buff **pskb) {	struct sk_buff *skb;	/* Do not fail on null, as we are going to use this in cleanup code. */	if (!pskb || !(skb = *pskb))		return;	/* Release the SKB references, for fragments of chain that are	 * unshared... starting at skb passed in. */	if (skb->prev == NULL) {		if (skb->next != NULL)			skb->next->prev = NULL;		skb->next = NULL;	}	if (SKB_NI(skb) != NULL)		ieee80211_unref_node(&SKB_NI(skb));#ifdef IEEE80211_DEBUG_REFCNT	unref_skb(skb, UNREF_USE_DEV_KFREE_SKB_ANY, 		  __func__, __LINE__);#else	dev_kfree_skb_any(skb);#endif	*pskb = NULL;}/* ieee80211_dev_kfree_skb_list will invoke ieee80211_dev_kfree_skb on each node in * a list of skbs, starting with the first. */voidieee80211_dev_kfree_skb_list(struct sk_buff **pskb) {	struct sk_buff *skb, *tskb;	/* Do not fail on null, as we are going to use this in cleanup code */	if (!pskb || !(skb = *pskb))		return;	while (skb) {		tskb = skb->next;		ieee80211_dev_kfree_skb(&skb);		skb = tskb;	}	*pskb = NULL;}struct sk_buff *ieee80211_dev_alloc_skb(int size) {	struct sk_buff *skb = dev_alloc_skb(size);	if (skb == NULL) {		skb_print_message(				0 /* show_counter */, 				NULL /* skb */, 				__func__, __LINE__,				"sk_buff allocation of size %u failed",				size);		return NULL;	}#ifdef IEEE80211_DEBUG_REFCNT	return track_skb(skb, 0,  __func__, __LINE__);#else	return skb;#endif}voidieee80211_skb_track(struct sk_buff *skb) {#ifdef IEEE80211_DEBUG_REFCNT	track_skb(skb, 0 /* users_adjustment */, 		  __func__, __LINE__);#else	/* Just a dumb counter, in no-debug builds */	atomic_inc(&skb_total_counter);#endif /* #ifdef IEEE80211_DEBUG_REFCNT */}voidieee80211_skb_untrack(struct sk_buff *skb) {	/* Just a dumb counter, in no-debug builds */	atomic_dec(&skb_total_counter);}#ifdef IEEE80211_DEBUG_REFCNTint ieee80211_skb_counter(void) {	return atomic_read(&skb_total_counter);}intieee80211_skb_references(void) {	return atomic_read(&skb_refs_counter);}#endif /* #ifdef IEEE80211_DEBUG_REFCNT *//******************************************************************************* * skbuff leak/refcount debugging Replacement Functions * PUT last in order to avoid conflicts with use of original functions in * inline functions above this point. ******************************************************************************/#ifdef IEEE80211_DEBUG_REFCNTint  vlan_hwaccel_rx_debug(struct sk_buff *skb, 			       struct vlan_group *grp, unsigned short vlan_tag, 			       const char *func, int line) {	return vlan_hwaccel_rx(		untrack_skb(skb, 0, __func__, __LINE__),		grp, vlan_tag);}int netif_rx_debug(struct sk_buff *skb, const char *func, int line) {	return netif_rx(untrack_skb(skb, 0, __func__, __LINE__));}struct sk_buff *alloc_skb_debug(unsigned int length, gfp_t gfp_mask,		const char *func, int line) {	return track_skb(alloc_skb(length, gfp_mask),			0 /* users_adjustment */,			__func__, __LINE__);}struct sk_buff *dev_alloc_skb_debug(unsigned int length,		    const char *func, int line){	return track_skb(dev_alloc_skb(length),			0 /* users_adjustment */,			__func__, __LINE__);}struct sk_buff *skb_clone_debug(struct sk_buff *skb, gfp_t pri, 			       const char *func, int line) {	return track_skb(			clean_clone_or_copy(skb_clone(skb, pri)),			0 /* users_adjustment */,			__func__, __LINE__);}struct sk_buff *skb_copy_debug(struct sk_buff *skb, gfp_t pri, 	       const char *func, int line){	return track_skb(		clean_clone_or_copy(skb_copy(skb, pri)), 0 /* users_adjustment */,			 __func__, __LINE__);}struct sk_buff *skb_get_debug(struct sk_buff *skb, 	      const char *func, int line){	return ref_skb(skb_get(skb), 		       __func__, __LINE__);}struct sk_buff *skb_realloc_headroom_debug(struct sk_buff *skb, unsigned int headroom, 			   const char *func, int line){	/* skb_realloc_headroom ALWAYS returns a copy or a clone, refcount of	 * new one is always zero and refcount of original is not touched. */	return track_skb(			clean_clone_or_copy(				skb_realloc_headroom(skb, headroom)), 			0 /* users_adjustment */,			__func__, __LINE__);}struct sk_buff *pskb_copy_debug(struct sk_buff *skb, gfp_t pri,		const char *func, int line){	return track_skb(			clean_clone_or_copy(pskb_copy(skb, pri)), 			0 /* users_adjustment */,			__func__, __LINE__);}int dev_queue_xmit_debug(struct sk_buff *skb,		     const char *func, int line){	return dev_queue_xmit(untrack_skb(skb, 0, __func__, __LINE__));}struct sk_buff *skb_share_check_debug(struct sk_buff *skb, gfp_t pri,		      const char *func, int line){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)	might_sleep_if(pri & __GFP_WAIT);#endif	if (skb_shared(skb)) {		struct sk_buff *nskb = track_skb(			clean_clone_or_copy(skb_clone(skb, pri)), 			0,			__func__, __LINE__);		unref_skb(skb, UNREF_USE_DEV_KFREE_SKB_ANY, 			  __func__, __LINE__);		skb = nskb;	}	return skb;}void  kfree_skb_fast_debug(struct sk_buff *skb, 		     const char *func, int line){	/* NOT so fast... */	unref_skb(skb, UNREF_USE_DEV_KFREE_SKB_ANY, func, line, __func__, __LINE__);}struct sk_buff *skb_unshare_debug(struct sk_buff *skb, gfp_t pri,		  const char *func, int line){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)	might_sleep_if(pri & __GFP_WAIT);#endif	if (skb_cloned(skb)) {		struct sk_buff *nskb = track_skb(			clean_clone_or_copy(skb_copy(skb, pri)), 0,			__func__, __LINE__);		unref_skb(skb, UNREF_USE_DEV_KFREE_SKB_ANY, 			  __func__, __LINE__);		skb = nskb;	}	return skb;}struct sk_buff *skb_copy_expand_debug(const struct sk_buff *skb, int newheadroom, 		      int newtailroom, gfp_t gfp_mask, 		      const char *func, int line){	return track_skb(		clean_clone_or_copy(			skb_copy_expand(skb, newheadroom, newtailroom, gfp_mask)), 			0 /* users_adjustment */,			__func__, __LINE__);}EXPORT_SYMBOL(vlan_hwaccel_rx_debug);EXPORT_SYMBOL(netif_rx_debug);EXPORT_SYMBOL(alloc_skb_debug);EXPORT_SYMBOL(dev_alloc_skb_debug);EXPORT_SYMBOL(skb_clone_debug);EXPORT_SYMBOL(skb_copy_debug);EXPORT_SYMBOL(skb_get_debug);EXPORT_SYMBOL(skb_realloc_headroom_debug);EXPORT_SYMBOL(pskb_copy_debug);EXPORT_SYMBOL(dev_queue_xmit_debug);EXPORT_SYMBOL(skb_share_check_debug);EXPORT_SYMBOL(kfree_skb_fast_debug);EXPORT_SYMBOL(skb_unshare_debug);EXPORT_SYMBOL(skb_copy_expand_debug);EXPORT_SYMBOL(ieee80211_skb_counter);EXPORT_SYMBOL(ieee80211_skb_references);#endif /* #ifdef IEEE80211_DEBUG_REFCNT */EXPORT_SYMBOL(ieee80211_dev_alloc_skb);EXPORT_SYMBOL(ieee80211_skb_untrack);EXPORT_SYMBOL(ieee80211_dev_kfree_skb_list);EXPORT_SYMBOL(ieee80211_dev_kfree_skb);EXPORT_SYMBOL(ieee80211_skb_track);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -