Staging: octeon-ethernet: Fix race freeing transmit buffers.
[linux-2.6.git] / drivers / staging / octeon / ethernet-tx.h
index 5106236..c0bebf7 100644 (file)
@@ -30,3 +30,28 @@ int cvm_oct_xmit_pow(struct sk_buff *skb, struct net_device *dev);
 int cvm_oct_transmit_qos(struct net_device *dev, void *work_queue_entry,
                         int do_free, int qos);
 void cvm_oct_tx_shutdown(struct net_device *dev);
+
+/**
+ * Free dead transmit skbs.
+ *
+ * @priv:              The driver data
+ * @skb_to_free:       The number of SKBs to free (free none if negative).
+ * @qos:               The queue to free from.
+ * @take_lock:         If true, acquire the skb list lock.
+ */
+static inline void cvm_oct_free_tx_skbs(struct octeon_ethernet *priv,
+                                       int skb_to_free,
+                                       int qos, int take_lock)
+{
+       /* Free skbuffs not in use by the hardware.  */
+       if (skb_to_free > 0) {
+               if (take_lock)
+                       spin_lock(&priv->tx_free_list[qos].lock);
+               while (skb_to_free > 0) {
+                       dev_kfree_skb(__skb_dequeue(&priv->tx_free_list[qos]));
+                       skb_to_free--;
+               }
+               if (take_lock)
+                       spin_unlock(&priv->tx_free_list[qos].lock);
+       }
+}