Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 203122
b: refs/heads/master
c: 6afff0c
h: refs/heads/master
v: v3
  • Loading branch information
John Fastabend authored and David S. Miller committed Jun 23, 2010
1 parent 87dfcf7 commit 81c9e3e
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 37 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: 1dc8d8c06d4002be4d1373fc06f25cd589be47e1
refs/heads/master: 6afff0caa721211e8c04bdc7627ee3bff95bcb95
68 changes: 32 additions & 36 deletions trunk/net/core/dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,22 @@ static inline void skb_orphan_try(struct sk_buff *skb)
skb_orphan(skb);
}

/*
* Returns true if either:
* 1. skb has frag_list and the device doesn't support FRAGLIST, or
* 2. skb is fragmented and the device does not support SG, or if
* at least one of fragments is in highmem and device does not
* support DMA from it.
*/
static inline int skb_needs_linearize(struct sk_buff *skb,
struct net_device *dev)
{
return skb_is_nonlinear(skb) &&
((skb_has_frags(skb) && !(dev->features & NETIF_F_FRAGLIST)) ||
(skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) ||
illegal_highdma(dev, skb))));
}

int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq)
{
Expand All @@ -1919,6 +1935,22 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
goto out_kfree_skb;
if (skb->next)
goto gso;
} else {
if (skb_needs_linearize(skb, dev) &&
__skb_linearize(skb))
goto out_kfree_skb;

/* If packet is not checksummed and device does not
* support checksumming for this protocol, complete
* checksumming here.
*/
if (skb->ip_summed == CHECKSUM_PARTIAL) {
skb_set_transport_header(skb, skb->csum_start -
skb_headroom(skb));
if (!dev_can_checksum(dev, skb) &&
skb_checksum_help(skb))
goto out_kfree_skb;
}
}

rc = ops->ndo_start_xmit(skb, dev);
Expand Down Expand Up @@ -2089,22 +2121,6 @@ static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
return rc;
}

/*
* Returns true if either:
* 1. skb has frag_list and the device doesn't support FRAGLIST, or
* 2. skb is fragmented and the device does not support SG, or if
* at least one of fragments is in highmem and device does not
* support DMA from it.
*/
static inline int skb_needs_linearize(struct sk_buff *skb,
struct net_device *dev)
{
return skb_is_nonlinear(skb) &&
((skb_has_frags(skb) && !(dev->features & NETIF_F_FRAGLIST)) ||
(skb_shinfo(skb)->nr_frags && (!(dev->features & NETIF_F_SG) ||
illegal_highdma(dev, skb))));
}

/**
* dev_queue_xmit - transmit a buffer
* @skb: buffer to transmit
Expand Down Expand Up @@ -2137,25 +2153,6 @@ int dev_queue_xmit(struct sk_buff *skb)
struct Qdisc *q;
int rc = -ENOMEM;

/* GSO will handle the following emulations directly. */
if (netif_needs_gso(dev, skb))
goto gso;

/* Convert a paged skb to linear, if required */
if (skb_needs_linearize(skb, dev) && __skb_linearize(skb))
goto out_kfree_skb;

/* If packet is not checksummed and device does not support
* checksumming for this protocol, complete checksumming here.
*/
if (skb->ip_summed == CHECKSUM_PARTIAL) {
skb_set_transport_header(skb, skb->csum_start -
skb_headroom(skb));
if (!dev_can_checksum(dev, skb) && skb_checksum_help(skb))
goto out_kfree_skb;
}

gso:
/* Disable soft irqs for various locks below. Also
* stops preemption for RCU.
*/
Expand Down Expand Up @@ -2214,7 +2211,6 @@ int dev_queue_xmit(struct sk_buff *skb)
rc = -ENETDOWN;
rcu_read_unlock_bh();

out_kfree_skb:
kfree_skb(skb);
return rc;
out:
Expand Down

0 comments on commit 81c9e3e

Please sign in to comment.