diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/tx.c | 15 |
1 files changed, 4 insertions, 11 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 925c39f4099e..cf7141452b0f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -2072,30 +2072,23 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
2072 | 2072 | ||
2073 | if (unlikely(!multicast && skb->sk && | 2073 | if (unlikely(!multicast && skb->sk && |
2074 | skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) { | 2074 | skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) { |
2075 | struct sk_buff *orig_skb = skb; | 2075 | struct sk_buff *ack_skb = skb_clone_sk(skb); |
2076 | 2076 | ||
2077 | skb = skb_clone(skb, GFP_ATOMIC); | 2077 | if (ack_skb) { |
2078 | if (skb) { | ||
2079 | unsigned long flags; | 2078 | unsigned long flags; |
2080 | int id; | 2079 | int id; |
2081 | 2080 | ||
2082 | spin_lock_irqsave(&local->ack_status_lock, flags); | 2081 | spin_lock_irqsave(&local->ack_status_lock, flags); |
2083 | id = idr_alloc(&local->ack_status_frames, orig_skb, | 2082 | id = idr_alloc(&local->ack_status_frames, ack_skb, |
2084 | 1, 0x10000, GFP_ATOMIC); | 2083 | 1, 0x10000, GFP_ATOMIC); |
2085 | spin_unlock_irqrestore(&local->ack_status_lock, flags); | 2084 | spin_unlock_irqrestore(&local->ack_status_lock, flags); |
2086 | 2085 | ||
2087 | if (id >= 0) { | 2086 | if (id >= 0) { |
2088 | info_id = id; | 2087 | info_id = id; |
2089 | info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | 2088 | info_flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; |
2090 | } else if (skb_shared(skb)) { | ||
2091 | kfree_skb(orig_skb); | ||
2092 | } else { | 2089 | } else { |
2093 | kfree_skb(skb); | 2090 | kfree_skb(ack_skb); |
2094 | skb = orig_skb; | ||
2095 | } | 2091 | } |
2096 | } else { | ||
2097 | /* couldn't clone -- lose tx status ... */ | ||
2098 | skb = orig_skb; | ||
2099 | } | 2092 | } |
2100 | } | 2093 | } |
2101 | 2094 | ||