--- a/drivers/net/imq.c +++ b/drivers/net/imq.c @@ -178,10 +178,11 @@ static int imq_nf_queue(struct nf_queue_ struct sk_buff *skb2 = NULL; struct Qdisc *q; unsigned int index = entry->skb->imq_flags & IMQ_F_IFMASK; - int ret = -1; + struct netdev_queue *txq; + int ret = -EINVAL; if (index > numdevs) - return -1; + return ret; /* check for imq device by index from cache */ dev = imq_devs_cache[index]; @@ -194,7 +195,7 @@ static int imq_nf_queue(struct nf_queue_ if (!dev) { /* not found ?!*/ BUG(); - return -1; + return ret; } imq_devs_cache[index] = dev; @@ -212,17 +213,19 @@ static int imq_nf_queue(struct nf_queue_ skb2 = entry->skb; entry->skb = skb_clone(entry->skb, GFP_ATOMIC); if (!entry->skb) - return -1; + return -ENOMEM; } entry->skb->nf_queue_entry = entry; dev->stats.rx_bytes += entry->skb->len; dev->stats.rx_packets++; - spin_lock_bh(&dev->queue_lock); - q = dev->qdisc; + txq = netdev_get_tx_queue(dev, 0); + __netif_tx_lock_bh(txq); + q = txq->qdisc; + if (q->enqueue) { - q->enqueue(skb_get(entry->skb), q); + qdisc_enqueue_root(skb_get(entry->skb), q); if (skb_shared(entry->skb)) { entry->skb->destructor = imq_skb_destructor; kfree_skb(entry->skb); @@ -231,7 +234,7 @@ static int imq_nf_queue(struct nf_queue_ } if (!test_and_set_bit(1, &priv->tasklet_pending)) tasklet_schedule(&priv->tasklet); - spin_unlock_bh(&dev->queue_lock); + __netif_tx_unlock_bh(txq); if (skb2) kfree_skb(ret ? entry->skb : skb2); @@ -248,11 +251,13 @@ static void qdisc_run_tasklet(unsigned l { struct net_device *dev = (struct net_device *)arg; struct imq_private *priv = netdev_priv(dev); + struct netdev_queue *txq; - spin_lock(&dev->queue_lock); - qdisc_run(dev); + netif_tx_lock(dev); + txq = netdev_get_tx_queue(dev, 0); + qdisc_run(txq->qdisc); clear_bit(1, &priv->tasklet_pending); - spin_unlock(&dev->queue_lock); + netif_tx_unlock(dev); } static unsigned int imq_nf_hook(unsigned int hook, struct sk_buff *pskb,