Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 278344
b: refs/heads/master
c: 117632e
h: refs/heads/master
v: v3
  • Loading branch information
Eric Dumazet authored and David S. Miller committed Dec 4, 2011
1 parent 578abba commit a85efd9
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c2e4e25afcc8ae1835a6100089f1f9fd3a362430
refs/heads/master: 117632e64d2a5f464e491fe221d7169a3814a77b
11 changes: 9 additions & 2 deletions trunk/include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -568,8 +568,9 @@ extern struct sk_buff *skb_clone(struct sk_buff *skb,
gfp_t priority);
extern struct sk_buff *skb_copy(const struct sk_buff *skb,
gfp_t priority);
extern struct sk_buff *pskb_copy(struct sk_buff *skb,
gfp_t gfp_mask);
extern struct sk_buff *__pskb_copy(struct sk_buff *skb,
int headroom, gfp_t gfp_mask);

extern int pskb_expand_head(struct sk_buff *skb,
int nhead, int ntail,
gfp_t gfp_mask);
Expand Down Expand Up @@ -1799,6 +1800,12 @@ static inline dma_addr_t skb_frag_dma_map(struct device *dev,
frag->page_offset + offset, size, dir);
}

static inline struct sk_buff *pskb_copy(struct sk_buff *skb,
gfp_t gfp_mask)
{
return __pskb_copy(skb, skb_headroom(skb), gfp_mask);
}

/**
* skb_clone_writable - is the header of a clone writable
* @skb: buffer to check
Expand Down
11 changes: 6 additions & 5 deletions trunk/net/core/skbuff.c
Original file line number Diff line number Diff line change
Expand Up @@ -840,8 +840,9 @@ struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
EXPORT_SYMBOL(skb_copy);

/**
* pskb_copy - create copy of an sk_buff with private head.
* __pskb_copy - create copy of an sk_buff with private head.
* @skb: buffer to copy
* @headroom: headroom of new skb
* @gfp_mask: allocation priority
*
* Make a copy of both an &sk_buff and part of its data, located
Expand All @@ -852,16 +853,16 @@ EXPORT_SYMBOL(skb_copy);
* The returned buffer has a reference count of 1.
*/

struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask)
{
unsigned int size = skb_end_pointer(skb) - skb->head;
unsigned int size = skb_headlen(skb) + headroom;
struct sk_buff *n = alloc_skb(size, gfp_mask);

if (!n)
goto out;

/* Set the data pointer */
skb_reserve(n, skb_headroom(skb));
skb_reserve(n, headroom);
/* Set the tail pointer and length */
skb_put(n, skb_headlen(skb));
/* Copy the bytes */
Expand Down Expand Up @@ -897,7 +898,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
out:
return n;
}
EXPORT_SYMBOL(pskb_copy);
EXPORT_SYMBOL(__pskb_copy);

/**
* pskb_expand_head - reallocate header of &sk_buff
Expand Down
10 changes: 9 additions & 1 deletion trunk/net/ipv4/tcp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -2147,7 +2147,15 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
*/
TCP_SKB_CB(skb)->when = tcp_time_stamp;

err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
/* make sure skb->data is aligned on arches that require it */
if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) {
struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
GFP_ATOMIC);
err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
-ENOBUFS;
} else {
err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
}

if (err == 0) {
/* Update global TCP statistics. */
Expand Down

0 comments on commit a85efd9

Please sign in to comment.