On Fri, 2005-12-16 at 14:52 -0500, Benjamin LaHaise wrote:
> In __alloc_skb(), the use of skb_shinfo() which casts a u8 * to the 
> shared info structure results in gcc being forced to do a reload of the 
> pointer since it has no information on possible aliasing.  Fix this by 
> using a pointer to refer to skb_shared_info.

How about moving this into a helper function
and calling it from alloc_skb_from_cache too?

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 83fee37..7f6f4f5 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -118,6 +118,19 @@ void skb_under_panic(struct sk_buff *skb
  *
  */
 
+static inline void skb_init_shared_info(struct sk_buff *skb)
+{
+       /* make sure we initialize shinfo sequentially */
+       struct skb_shared_info* shinfo = skb_shinfo(skb);
+       atomic_set(&shinfo->dataref, 1);
+       shinfo->nr_frags = 0;
+       shinfo->tso_size = 0;
+       shinfo->tso_segs = 0;
+       shinfo->ufo_size = 0;
+       shinfo->ip6_frag_id = 0;
+       shinfo->frag_list = NULL;
+}
+
 /**
  *     __alloc_skb     -       allocate a network buffer
  *     @size: size to allocate
@@ -139,13 +152,8 @@ struct sk_buff *__alloc_skb(unsigned int
        u8 *data;
 
        /* Get the HEAD */
-       if (fclone)
-               skb = kmem_cache_alloc(skbuff_fclone_cache,
-                                      gfp_mask & ~__GFP_DMA);
-       else
-               skb = kmem_cache_alloc(skbuff_head_cache,
-                                      gfp_mask & ~__GFP_DMA);
-
+       skb = kmem_cache_alloc(fclone ? skbuff_fclone_cache : skbuff_head_cache,
+                               gfp_mask & ~__GFP_DMA);
        if (!skb)
                goto out;
 
@@ -162,6 +170,9 @@ struct sk_buff *__alloc_skb(unsigned int
        skb->data = data;
        skb->tail = data;
        skb->end  = data + size;
+
+       skb_init_shared_info(skb);
+
        if (fclone) {
                struct sk_buff *child = skb + 1;
                atomic_t *fclone_ref = (atomic_t *) (child + 1);
@@ -171,13 +182,6 @@ struct sk_buff *__alloc_skb(unsigned int
 
                child->fclone = SKB_FCLONE_UNAVAILABLE;
        }
-       atomic_set(&(skb_shinfo(skb)->dataref), 1);
-       skb_shinfo(skb)->nr_frags  = 0;
-       skb_shinfo(skb)->tso_size = 0;
-       skb_shinfo(skb)->tso_segs = 0;
-       skb_shinfo(skb)->frag_list = NULL;
-       skb_shinfo(skb)->ufo_size = 0;
-       skb_shinfo(skb)->ip6_frag_id = 0;
 out:
        return skb;
 nodata:
@@ -227,11 +231,7 @@ struct sk_buff *alloc_skb_from_cache(kme
        skb->tail = data;
        skb->end  = data + size;
 
-       atomic_set(&(skb_shinfo(skb)->dataref), 1);
-       skb_shinfo(skb)->nr_frags  = 0;
-       skb_shinfo(skb)->tso_size = 0;
-       skb_shinfo(skb)->tso_segs = 0;
-       skb_shinfo(skb)->frag_list = NULL;
+       skb_init_shared_info(skb);
 out:
        return skb;
 nodata:


-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to