--- zzzz-none-000/linux-2.6.28.10/net/core/skbuff.c 2009-05-02 18:54:43.000000000 +0000 +++ puma5-6360-529/linux-2.6.28.10/net/core/skbuff.c 2012-08-28 13:01:43.000000000 +0000 @@ -67,6 +67,11 @@ #include "kmap_skb.h" +#if (defined(CONFIG_FUSIV_ENABLE_MBUF_AP) && CONFIG_FUSIV_ENABLE_MBUF_AP) || (defined(CONFIG_FUSIV_ENABLE_AP_MBUF) && CONFIG_FUSIV_ENABLE_AP_MBUF) +unsigned char* (*ap_get_cluster_ptr)(struct sk_buff *skbuff, int size) = NULL; +void (*putCluster_ptr)(void *ulPtr) = NULL; +#endif + static struct kmem_cache *skbuff_head_cache __read_mostly; static struct kmem_cache *skbuff_fclone_cache __read_mostly; @@ -143,6 +148,13 @@ BUG(); } +static unsigned int global_uniq_id = 1; +atomic_t skbs_in_use = { counter: 0 }; +int get_skbs_in_use(void) { + return atomic_read(&skbs_in_use); +} +EXPORT_SYMBOL(get_skbs_in_use); /* WLAN module might want to display this value */ + /* Allocate a new skbuff. We do this ourselves so we can fill in a few * 'private' fields and also do memory statistics to find all the * [BEEP] leaks. @@ -170,7 +182,7 @@ struct kmem_cache *cache; struct skb_shared_info *shinfo; struct sk_buff *skb; - u8 *data; + u8 *data = NULL; cache = fclone ? skbuff_fclone_cache : skbuff_head_cache; @@ -179,11 +191,9 @@ if (!skb) goto out; - size = SKB_DATA_ALIGN(size); - data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info), - gfp_mask, node); - if (!data) - goto nodata; + if(cache == skbuff_head_cache) { + atomic_inc(&skbs_in_use); + } /* * Only clear those fields we need to clear, not those that we will @@ -191,12 +201,30 @@ * the tail pointer in struct sk_buff! */ memset(skb, 0, offsetof(struct sk_buff, tail)); + + size = SKB_DATA_ALIGN(size); +#if (defined(CONFIG_FUSIV_ENABLE_MBUF_AP) && CONFIG_FUSIV_ENABLE_MBUF_AP) || (defined(CONFIG_FUSIV_ENABLE_AP_MBUF) && CONFIG_FUSIV_ENABLE_AP_MBUF) + if( ap_get_cluster_ptr != NULL ) + data = (u8*)(*ap_get_cluster_ptr)(skb,size + sizeof(struct skb_shared_info)); + if(data == NULL) +#endif + { + data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info), + gfp_mask, node); + if (!data) + goto nodata; + + } + + skb_track_caller(skb); skb->truesize = size + sizeof(struct sk_buff); atomic_set(&skb->users, 1); skb->head = data; skb->data = data; skb_reset_tail_pointer(skb); skb->end = skb->tail + size; + skb->uniq_id = global_uniq_id++ & 0xffffff; + /* make sure we initialize shinfo sequentially */ shinfo = skb_shinfo(skb); atomic_set(&shinfo->dataref, 1); @@ -221,6 +249,9 @@ nodata: kmem_cache_free(cache, skb); skb = NULL; + if(cache == skbuff_head_cache) { + atomic_dec(&skbs_in_use); + } goto out; } @@ -293,6 +324,22 @@ } EXPORT_SYMBOL(dev_alloc_skb); + +/* AVM/RSP 20100413 + * This version of dev_alloc_skb does not die if there are no + * free pages in interrupt context + */ +struct sk_buff *dev_alloc_skb_nowarn(unsigned int length) +{ + /* + * There is more code here than it seems: + * __dev_alloc_skb is an inline + */ + return __dev_alloc_skb(length, GFP_ATOMIC | __GFP_NOWARN); +} +EXPORT_SYMBOL(dev_alloc_skb_nowarn); + + static void skb_drop_list(struct sk_buff **listp) { struct sk_buff *list = *listp; @@ -324,6 +371,9 @@ if (!skb->cloned || !atomic_sub_return(skb->nohdr ? (1 << SKB_DATAREF_SHIFT) + 1 : 1, &skb_shinfo(skb)->dataref)) { +#if (defined(CONFIG_FUSIV_ENABLE_MBUF_AP) && CONFIG_FUSIV_ENABLE_MBUF_AP) || (defined(CONFIG_FUSIV_ENABLE_AP_MBUF) && CONFIG_FUSIV_ENABLE_AP_MBUF) + if (skb->apAllocAddr != 0x1) { +#endif if (skb_shinfo(skb)->nr_frags) { int i; for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) @@ -333,6 +383,24 @@ if (skb_shinfo(skb)->frag_list) skb_drop_fraglist(skb); + /* Below code is to free AP Cluster. We don't want to free + the cluster if it is in Tx Path as it will be freed + in AP. For Tx , the pointer will have the value 1 + */ +#if (defined(CONFIG_FUSIV_ENABLE_MBUF_AP) && CONFIG_FUSIV_ENABLE_MBUF_AP) || (defined(CONFIG_FUSIV_ENABLE_AP_MBUF) && CONFIG_FUSIV_ENABLE_AP_MBUF) + } + if( (skb->apAllocAddr != NULL) && ((int)skb->apAllocAddr != 0x1)) { + if(putCluster_ptr != NULL) + (*putCluster_ptr)(skb->apAllocAddr); + //else + // printk("\n skbuff1: fusivlib_lkm not initilizedproperly...\n"); + skb->apAllocAddr = NULL; + } + else if((int)skb->apAllocAddr == 0x1) + skb->apAllocAddr = NULL; + else +#endif + kfree(skb->head); } } @@ -348,6 +416,7 @@ switch (skb->fclone) { case SKB_FCLONE_UNAVAILABLE: kmem_cache_free(skbuff_head_cache, skb); + atomic_dec(&skbs_in_use); break; case SKB_FCLONE_ORIG: @@ -373,14 +442,19 @@ static void skb_release_head_state(struct sk_buff *skb) { - dst_release(skb->dst); -#ifdef CONFIG_XFRM - secpath_put(skb->sp); -#endif if (skb->destructor) { WARN_ON(in_irq()); skb->destructor(skb); } + dst_release(skb->dst); + skb->dst = 0; +#ifdef CONFIG_XFRM + secpath_put(skb->sp); +#endif +#if defined(CONFIG_GENERIC_CONNTRACK) + generic_ct_put(skb->generic_ct); +#endif + #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) nf_conntrack_put(skb->nfct); nf_conntrack_put_reasm(skb->nfct_reasm); @@ -416,6 +490,13 @@ void __kfree_skb(struct sk_buff *skb) { skb_release_all(skb); +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + memset(&skb->apFlowData, 0, sizeof(skb->apFlowData)); +#else +#if defined(CONFIG_FUSIV_KERNEL_HOST_IPQOS) || defined(CONFIG_FUSIV_KERNEL_HOST_IPQOS_MODULE) + memset(&skb->qosInfo, 0, sizeof(skb->qosInfo)); +#endif +#endif kfree_skbmem(skb); } @@ -485,6 +566,20 @@ { new->tstamp = old->tstamp; new->dev = old->dev; + new->input_dev = old->input_dev; +#ifdef CONFIG_TI_META_DATA + new->ti_meta_info = old->ti_meta_info; + new->ti_meta_info2 = old->ti_meta_info2; +#endif +#ifdef CONFIG_TI_DOCSIS_INPUT_DEV + new->ti_docsis_input_dev = old->ti_docsis_input_dev ; +#endif /* CONFIG_TI_DOCSIS_INPUT_DEV */ +#ifdef CONFIG_TI_L2_SELECTIVE_FORWARDER + new->ti_selective_fwd_dev_info = old->ti_selective_fwd_dev_info; +#endif +#ifdef CONFIG_TI_PACKET_PROCESSOR + new->pp_packet_info = old->pp_packet_info; +#endif new->transport_header = old->transport_header; new->network_header = old->network_header; new->mac_header = old->mac_header; @@ -493,6 +588,10 @@ new->sp = secpath_get(old->sp); #endif memcpy(new->cb, old->cb, sizeof(old->cb)); +#ifdef CONFIG_AVM_PA + memcpy(&new->avm_pa.pktinfo, &old->avm_pa.pktinfo, + sizeof(old->avm_pa.pktinfo)); +#endif new->csum_start = old->csum_start; new->csum_offset = old->csum_offset; new->local_df = old->local_df; @@ -536,11 +635,15 @@ n->cloned = 1; n->nohdr = 0; n->destructor = NULL; + n->destructor_info = 0; C(iif); C(tail); C(end); C(head); C(data); +#if (defined(CONFIG_FUSIV_ENABLE_MBUF_AP) && CONFIG_FUSIV_ENABLE_MBUF_AP) || (defined(CONFIG_FUSIV_ENABLE_AP_MBUF) && CONFIG_FUSIV_ENABLE_AP_MBUF) + C(apAllocAddr); +#endif C(truesize); #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE) C(do_not_encrypt); @@ -550,6 +653,16 @@ atomic_inc(&(skb_shinfo(skb)->dataref)); skb->cloned = 1; + C(uniq_id); + +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + C(apFlowData); +#else +#if defined(CONFIG_FUSIV_KERNEL_HOST_IPQOS) || defined(CONFIG_FUSIV_KERNEL_HOST_IPQOS_MODULE) + C(qosInfo); +#endif +#endif + return n; #undef C } @@ -600,6 +713,7 @@ if (!n) return NULL; n->fclone = SKB_FCLONE_UNAVAILABLE; + atomic_inc(&skbs_in_use); } return __skb_clone(n, skb); @@ -616,6 +730,17 @@ __copy_skb_header(new, old); + new->uniq_id = old->uniq_id; + + +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + memcpy(&new->apFlowData, &old->apFlowData, sizeof(old->apFlowData)); +#else +#if defined(CONFIG_FUSIV_KERNEL_HOST_IPQOS) || defined(CONFIG_FUSIV_KERNEL_HOST_IPQOS_MODULE) + memcpy(&new->qosInfo, &old->qosInfo, sizeof(old->qosInfo)); +#endif +#endif + #ifndef NET_SKBUFF_DATA_USES_OFFSET /* {transport,network,mac}_header are relative to skb->head */ new->transport_header += offset; @@ -805,6 +930,9 @@ skb->csum_start += nhead; skb->cloned = 0; skb->hdr_len = 0; +#if (defined(CONFIG_FUSIV_ENABLE_MBUF_AP) && CONFIG_FUSIV_ENABLE_MBUF_AP) || (defined(CONFIG_FUSIV_ENABLE_AP_MBUF) && CONFIG_FUSIV_ENABLE_AP_MBUF) + skb->apAllocAddr = NULL; +#endif skb->nohdr = 0; atomic_set(&skb_shinfo(skb)->dataref, 1); return 0; @@ -2397,6 +2525,9 @@ 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); +#if defined(CONFIG_GENERIC_CONNTRACK) + generic_ct_init(); +#endif } /** @@ -2620,11 +2751,53 @@ void __skb_warn_lro_forwarding(const struct sk_buff *skb) { - if (net_ratelimit()) + if (net_ratelimit()) { pr_warning("%s: received packets cannot be forwarded" " while LRO is enabled\n", skb->dev->name); + WARN_ON(1); + } } +#if (defined(CONFIG_FUSIV_ENABLE_MBUF_AP) && CONFIG_FUSIV_ENABLE_MBUF_AP) || (defined(CONFIG_FUSIV_ENABLE_AP_MBUF) && CONFIG_FUSIV_ENABLE_AP_MBUF) +struct sk_buff *ap_get_skb(char *buf, unsigned int size) +{ + struct sk_buff *skb = NULL; + struct skb_shared_info *shinfo; + u8 *data; + + /* Commenting the size to increment 16 bytes, to support receiving + of 1728 byte packet to a single skbuff */ + //size += 16; + /* Get the HEAD */ + skb = kmem_cache_alloc(skbuff_head_cache, GFP_ATOMIC & ~__GFP_DMA); + if (!skb) + { + printk("phm_devget : alloc_skb() Failed. \n"); + return NULL; + } + atomic_inc(&skbs_in_use); + /* Get the DATA. Size must match skb_add_mtu(). */ + size = SKB_DATA_ALIGN(size); + data = buf; + memset(skb,0,offsetof(struct sk_buff, truesize)); + skb->truesize = size + sizeof(struct sk_buff); + atomic_set(&skb->users, 1); + skb->head = data; + skb->end = data + size; +/* make sure we initialize shinfo sequentially */ + shinfo = skb_shinfo(skb); + atomic_set(&shinfo->dataref, 1); + shinfo->nr_frags = 0; + shinfo->gso_size = 0; + shinfo->gso_segs = 0; + shinfo->gso_type = 0; + shinfo->ip6_frag_id = 0; + shinfo->frag_list = NULL; + skb_reserve(skb, 16); + return skb; +} +#endif + EXPORT_SYMBOL(___pskb_trim); EXPORT_SYMBOL(__kfree_skb); EXPORT_SYMBOL(kfree_skb); @@ -2663,3 +2836,8 @@ EXPORT_SYMBOL_GPL(skb_to_sgvec); EXPORT_SYMBOL_GPL(skb_cow_data); EXPORT_SYMBOL_GPL(skb_partial_csum_set); +#if (defined(CONFIG_FUSIV_ENABLE_MBUF_AP) && CONFIG_FUSIV_ENABLE_MBUF_AP) || (defined(CONFIG_FUSIV_ENABLE_AP_MBUF) && CONFIG_FUSIV_ENABLE_AP_MBUF) +EXPORT_SYMBOL(ap_get_cluster_ptr); +EXPORT_SYMBOL(putCluster_ptr); +EXPORT_SYMBOL(ap_get_skb); +#endif