From 8df643ef312f2f35b2f0b82c6627459f1d7659be Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 16 Apr 2010 12:18:22 +0000 Subject: [PATCH] --- yaml --- r: 194287 b: refs/heads/master c: fc6055a5ba31e2c14e36e8939f9bf2b6d586a7f5 h: refs/heads/master i: 194285: 72cc2270b449533512274378a37b95c500f5b588 194283: b3ce6dc0e89aa2049d7a60ae132871aae7543ad7 194279: 399f210b7cefbc65ff94393f6b6f49c381163959 194271: 4fe50bb0d04904bbb5265a2077751d69942c4caa v: v3 --- [refs] | 2 +- trunk/net/core/dev.c | 27 +++++++++++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/[refs] b/[refs] index 98f2f82184d3..ef22924c1579 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 9958da0501fced47c1ac5c5a3a7731c87e45472c +refs/heads/master: fc6055a5ba31e2c14e36e8939f9bf2b6d586a7f5 diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 8092f01713fb..8eb50e2292fb 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1880,6 +1880,17 @@ 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) { @@ -1904,23 +1915,10 @@ 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); + skb_orphan_try(skb); rc = ops->ndo_start_xmit(skb, dev); if (rc == NETDEV_TX_OK) txq_trans_update(txq); - /* - * TODO: if skb_orphan() was called by - * dev->hard_start_xmit() (for example, the unmodified - * igb driver does that; bnx2 doesn't), then - * skb_tx_software_timestamp() will be unable to send - * back the time stamp. - * - * How can this be prevented? Always create another - * reference to the socket before calling - * dev->hard_start_xmit()? Prevent that skb_orphan() - * does anything in dev->hard_start_xmit() by clearing - * the skb destructor before the call and restoring it - * afterwards, then doing the skb_orphan() ourselves? - */ return rc; } @@ -1938,6 +1936,7 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev, if (dev->priv_flags & IFF_XMIT_DST_RELEASE) skb_dst_drop(nskb); + skb_orphan_try(nskb); rc = ops->ndo_start_xmit(nskb, dev); if (unlikely(rc != NETDEV_TX_OK)) { if (rc & ~NETDEV_TX_MASK)