Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 27563
b: refs/heads/master
c: 364c6ba
h: refs/heads/master
i:
  27561: c26b622
  27559: 6dd0b3b
v: v3
  • Loading branch information
Herbert Xu authored and David S. Miller committed Jun 18, 2006
1 parent 4ad7fcf commit 28a3931
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 92 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: 932ff279a43ab7257942cddff2595acd541cc49b
refs/heads/master: 364c6badde0dd62a0a38e5ed67f85d87d6665780
3 changes: 1 addition & 2 deletions trunk/drivers/block/aoe/aoenet.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt,
skb = skb_share_check(skb, GFP_ATOMIC);
if (skb == NULL)
return 0;
if (skb_is_nonlinear(skb))
if (skb_linearize(skb, GFP_ATOMIC) < 0)
if (skb_linearize(skb))
goto exit;
if (!is_aoe_netif(ifp))
goto exit;
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/mv643xx_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,7 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
}

if (has_tiny_unaligned_frags(skb)) {
if ((skb_linearize(skb, GFP_ATOMIC) != 0)) {
if (__skb_linearize(skb)) {
stats->tx_dropped++;
printk(KERN_DEBUG "%s: failed to linearize tiny "
"unaligned fragment\n", dev->name);
Expand Down
10 changes: 7 additions & 3 deletions trunk/drivers/net/via-velocity.c
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,13 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)

int pktlen = skb->len;

#ifdef VELOCITY_ZERO_COPY_SUPPORT
if (skb_shinfo(skb)->nr_frags > 6 && __skb_linearize(skb)) {
kfree_skb(skb);
return 0;
}
#endif

spin_lock_irqsave(&vptr->lock, flags);

index = vptr->td_curr[qnum];
Expand All @@ -1914,8 +1921,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
*/
if (pktlen < ETH_ZLEN) {
/* Cannot occur until ZC support */
if(skb_linearize(skb, GFP_ATOMIC))
return 0;
pktlen = ETH_ZLEN;
memcpy(tdinfo->buf, skb->data, skb->len);
memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
Expand All @@ -1933,7 +1938,6 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
int nfrags = skb_shinfo(skb)->nr_frags;
tdinfo->skb = skb;
if (nfrags > 6) {
skb_linearize(skb, GFP_ATOMIC);
memcpy(tdinfo->buf, skb->data, skb->len);
tdinfo->skb_dma[0] = tdinfo->buf_dma;
td_ptr->tdesc0.pktsize =
Expand Down
24 changes: 20 additions & 4 deletions trunk/include/linux/skbuff.h
Original file line number Diff line number Diff line change
Expand Up @@ -1169,18 +1169,34 @@ static inline int skb_can_coalesce(struct sk_buff *skb, int i,
return 0;
}

static inline int __skb_linearize(struct sk_buff *skb)
{
return __pskb_pull_tail(skb, skb->data_len) ? 0 : -ENOMEM;
}

/**
* skb_linearize - convert paged skb to linear one
* @skb: buffer to linarize
* @gfp: allocation mode
*
* If there is no free memory -ENOMEM is returned, otherwise zero
* is returned and the old skb data released.
*/
extern int __skb_linearize(struct sk_buff *skb, gfp_t gfp);
static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
static inline int skb_linearize(struct sk_buff *skb)
{
return skb_is_nonlinear(skb) ? __skb_linearize(skb) : 0;
}

/**
* skb_linearize_cow - make sure skb is linear and writable
* @skb: buffer to process
*
* If there is no free memory -ENOMEM is returned, otherwise zero
* is returned and the old skb data released.
*/
static inline int skb_linearize_cow(struct sk_buff *skb)
{
return __skb_linearize(skb, gfp);
return skb_is_nonlinear(skb) || skb_cloned(skb) ?
__skb_linearize(skb) : 0;
}

/**
Expand Down
63 changes: 2 additions & 61 deletions trunk/net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1222,64 +1222,6 @@ static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
#define illegal_highdma(dev, skb) (0)
#endif

/* Keep head the same: replace data */
int __skb_linearize(struct sk_buff *skb, gfp_t gfp_mask)
{
unsigned int size;
u8 *data;
long offset;
struct skb_shared_info *ninfo;
int headerlen = skb->data - skb->head;
int expand = (skb->tail + skb->data_len) - skb->end;

if (skb_shared(skb))
BUG();

if (expand <= 0)
expand = 0;

size = skb->end - skb->head + expand;
size = SKB_DATA_ALIGN(size);
data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
if (!data)
return -ENOMEM;

/* Copy entire thing */
if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
BUG();

/* Set up shinfo */
ninfo = (struct skb_shared_info*)(data + size);
atomic_set(&ninfo->dataref, 1);
ninfo->tso_size = skb_shinfo(skb)->tso_size;
ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
ninfo->nr_frags = 0;
ninfo->frag_list = NULL;

/* Offset between the two in bytes */
offset = data - skb->head;

/* Free old data. */
skb_release_data(skb);

skb->head = data;
skb->end = data + size;

/* Set up new pointers */
skb->h.raw += offset;
skb->nh.raw += offset;
skb->mac.raw += offset;
skb->tail += offset;
skb->data += offset;

/* We are no longer a clone, even if we were. */
skb->cloned = 0;

skb->tail += skb->data_len;
skb->data_len = 0;
return 0;
}

#define HARD_TX_LOCK(dev, cpu) { \
if ((dev->features & NETIF_F_LLTX) == 0) { \
netif_tx_lock(dev); \
Expand Down Expand Up @@ -1326,7 +1268,7 @@ int dev_queue_xmit(struct sk_buff *skb)

if (skb_shinfo(skb)->frag_list &&
!(dev->features & NETIF_F_FRAGLIST) &&
__skb_linearize(skb, GFP_ATOMIC))
__skb_linearize(skb))
goto out_kfree_skb;

/* Fragmented skb is linearized if device does not support SG,
Expand All @@ -1335,7 +1277,7 @@ int dev_queue_xmit(struct sk_buff *skb)
*/
if (skb_shinfo(skb)->nr_frags &&
(!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
__skb_linearize(skb, GFP_ATOMIC))
__skb_linearize(skb))
goto out_kfree_skb;

/* If packet is not checksummed and device does not support
Expand Down Expand Up @@ -3473,7 +3415,6 @@ subsys_initcall(net_dev_init);
EXPORT_SYMBOL(__dev_get_by_index);
EXPORT_SYMBOL(__dev_get_by_name);
EXPORT_SYMBOL(__dev_remove_pack);
EXPORT_SYMBOL(__skb_linearize);
EXPORT_SYMBOL(dev_valid_name);
EXPORT_SYMBOL(dev_add_pack);
EXPORT_SYMBOL(dev_alloc_name);
Expand Down
3 changes: 1 addition & 2 deletions trunk/net/decnet/dn_nsp_in.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,8 +801,7 @@ static int dn_nsp_rx_packet(struct sk_buff *skb)
* We linearize everything except data segments here.
*/
if (cb->nsp_flags & ~0x60) {
if (unlikely(skb_is_nonlinear(skb)) &&
skb_linearize(skb, GFP_ATOMIC) != 0)
if (unlikely(skb_linearize(skb)))
goto free_out;
}

Expand Down
3 changes: 1 addition & 2 deletions trunk/net/decnet/dn_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type
padlen);

if (flags & DN_RT_PKT_CNTL) {
if (unlikely(skb_is_nonlinear(skb)) &&
skb_linearize(skb, GFP_ATOMIC) != 0)
if (unlikely(skb_linearize(skb)))
goto dump_it;

switch(flags & DN_RT_CNTL_MSK) {
Expand Down
11 changes: 3 additions & 8 deletions trunk/net/ipv4/ipcomp.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,12 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb)

static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
{
int err = 0;
int err = -ENOMEM;
struct iphdr *iph;
struct ip_comp_hdr *ipch;

if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
skb_linearize(skb, GFP_ATOMIC) != 0) {
err = -ENOMEM;
if (skb_linearize_cow(skb))
goto out;
}

skb->ip_summed = CHECKSUM_NONE;

Expand Down Expand Up @@ -158,10 +155,8 @@ static int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb)
goto out_ok;
}

if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
skb_linearize(skb, GFP_ATOMIC) != 0) {
if (skb_linearize_cow(skb))
goto out_ok;
}

err = ipcomp_compress(x, skb);
iph = skb->nh.iph;
Expand Down
11 changes: 3 additions & 8 deletions trunk/net/ipv6/ipcomp6.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ static LIST_HEAD(ipcomp6_tfms_list);

static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
{
int err = 0;
int err = -ENOMEM;
struct ipv6hdr *iph;
struct ipv6_comp_hdr *ipch;
int plen, dlen;
Expand All @@ -74,11 +74,8 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb)
struct crypto_tfm *tfm;
int cpu;

if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
skb_linearize(skb, GFP_ATOMIC) != 0) {
err = -ENOMEM;
if (skb_linearize_cow(skb))
goto out;
}

skb->ip_summed = CHECKSUM_NONE;

Expand Down Expand Up @@ -142,10 +139,8 @@ static int ipcomp6_output(struct xfrm_state *x, struct sk_buff *skb)
goto out_ok;
}

if ((skb_is_nonlinear(skb) || skb_cloned(skb)) &&
skb_linearize(skb, GFP_ATOMIC) != 0) {
if (skb_linearize_cow(skb))
goto out_ok;
}

/* compression */
plen = skb->len - hdr_len;
Expand Down

0 comments on commit 28a3931

Please sign in to comment.