| Submitter | David Miller |
|---|---|
| Date | April 22, 2010, 7:41 a.m. |
| Message ID | <20100422.004136.151480121.davem@davemloft.net> |
| Download | mbox | patch |
| Permalink | /patch/50695/ |
| State | Accepted |
| Delegated to: | David Miller |
| Headers | show |
Comments
Le jeudi 22 avril 2010 à 00:41 -0700, David Miller a écrit : > From: Eric Dumazet <eric.dumazet@gmail.com> > Date: Thu, 22 Apr 2010 09:33:57 +0200 > > > Le jeudi 22 avril 2010 à 00:26 -0700, David Miller a écrit : > >> @@ -1865,6 +1865,7 @@ static int dev_gso_segment(struct sk_buff *skb) > >> int features = dev->features & ~(illegal_highdma(dev, skb) ? > >> NETIF_F_SG : 0); > >> > >> + skb_orphan_try(skb); > >> segs = skb_gso_segment(skb, features); > >> > >> /* Verifying header integrity only. */ > > > > Yes, it seems better. > > > > What about the > > > > if (dev->priv_flags & IFF_XMIT_DST_RELEASE) > > skb_dst_drop(skb); > > > > This thing might also be moved before the split, since split probably > > clone all dst ? > > Good catch, agreed. > > diff --git a/net/core/dev.c b/net/core/dev.c > index 3ba774b..4f897e2 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -1851,6 +1851,17 @@ static void dev_gso_skb_destructor(struct sk_buff *skb) > cb->destructor(skb); > } > > +/* > + * Try to orphan skb early, right before transmission by the device. > + * We cannot orphan skb if tx timestamp is requested, since > + * drivers need to call skb_tstamp_tx() to send the timestamp. > + */ > +static inline void skb_orphan_try(struct sk_buff *skb) > +{ > + if (!skb_tx(skb)->flags) > + skb_orphan(skb); > +} > + > /** > * dev_gso_segment - Perform emulated hardware segmentation on skb. > * @skb: buffer to segment > @@ -1865,6 +1876,7 @@ static int dev_gso_segment(struct sk_buff *skb) > int features = dev->features & ~(illegal_highdma(dev, skb) ? > NETIF_F_SG : 0); > > + skb_orphan_try(skb); > segs = skb_gso_segment(skb, features); > > /* Verifying header integrity only. */ > @@ -1881,17 +1893,6 @@ static int dev_gso_segment(struct sk_buff *skb) > return 0; > } > > -/* > - * Try to orphan skb early, right before transmission by the device. > - * We cannot orphan skb if tx timestamp is requested, since > - * drivers need to call skb_tstamp_tx() to send the timestamp. > - */ > -static inline void skb_orphan_try(struct sk_buff *skb) > -{ > - if (!skb_tx(skb)->flags) > - skb_orphan(skb); > -} > - > int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, > struct netdev_queue *txq) > { > @@ -1902,13 +1903,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, > if (!list_empty(&ptype_all)) > dev_queue_xmit_nit(skb, dev); > > - if (netif_needs_gso(dev, skb)) { > - if (unlikely(dev_gso_segment(skb))) > - goto out_kfree_skb; > - if (skb->next) > - goto gso; > - } > - > /* > * If device doesnt need skb->dst, release it right now while > * its hot in this cpu cache > @@ -1916,6 +1910,13 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, > if (dev->priv_flags & IFF_XMIT_DST_RELEASE) > skb_dst_drop(skb); > > + if (netif_needs_gso(dev, skb)) { > + if (unlikely(dev_gso_segment(skb))) > + goto out_kfree_skb; > + if (skb->next) > + goto gso; > + } > + > skb_orphan_try(skb); > rc = ops->ndo_start_xmit(skb, dev); > if (rc == NETDEV_TX_OK) You could have one skb_orphan_try() call before the if (netif_needs_gso(dev, skb)) { and remove it from dev_gso_segment() ? -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Patch
diff --git a/net/core/dev.c b/net/core/dev.c index 3ba774b..4f897e2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1851,6 +1851,17 @@ static void dev_gso_skb_destructor(struct sk_buff *skb) cb->destructor(skb); } +/* + * Try to orphan skb early, right before transmission by the device. + * We cannot orphan skb if tx timestamp is requested, since + * drivers need to call skb_tstamp_tx() to send the timestamp. + */ +static inline void skb_orphan_try(struct sk_buff *skb) +{ + if (!skb_tx(skb)->flags) + skb_orphan(skb); +} + /** * dev_gso_segment - Perform emulated hardware segmentation on skb. * @skb: buffer to segment @@ -1865,6 +1876,7 @@ static int dev_gso_segment(struct sk_buff *skb) int features = dev->features & ~(illegal_highdma(dev, skb) ? NETIF_F_SG : 0); + skb_orphan_try(skb); segs = skb_gso_segment(skb, features); /* Verifying header integrity only. */ @@ -1881,17 +1893,6 @@ static int dev_gso_segment(struct sk_buff *skb) return 0; } -/* - * Try to orphan skb early, right before transmission by the device. - * We cannot orphan skb if tx timestamp is requested, since - * drivers need to call skb_tstamp_tx() to send the timestamp. - */ -static inline void skb_orphan_try(struct sk_buff *skb) -{ - if (!skb_tx(skb)->flags) - skb_orphan(skb); -} - int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, struct netdev_queue *txq) { @@ -1902,13 +1903,6 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, if (!list_empty(&ptype_all)) dev_queue_xmit_nit(skb, dev); - if (netif_needs_gso(dev, skb)) { - if (unlikely(dev_gso_segment(skb))) - goto out_kfree_skb; - if (skb->next) - goto gso; - } - /* * If device doesnt need skb->dst, release it right now while * its hot in this cpu cache @@ -1916,6 +1910,13 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, if (dev->priv_flags & IFF_XMIT_DST_RELEASE) skb_dst_drop(skb); + if (netif_needs_gso(dev, skb)) { + if (unlikely(dev_gso_segment(skb))) + goto out_kfree_skb; + if (skb->next) + goto gso; + } + skb_orphan_try(skb); rc = ops->ndo_start_xmit(skb, dev); if (rc == NETDEV_TX_OK)