/* Main transmission queue. */
-/* Main qdisc structure lock.
+/* Main qdisc structure lock.
However, modifications
to data, participating in scheduling must be additionally
write_unlock(&qdisc_tree_lock);
}
-/*
+/*
dev->queue_lock serializes queue accesses for this device
AND dev->qdisc pointer itself.
we do not check dev->tbusy flag here.
Returns: 0 - queue is empty.
- >0 - queue is not empty, but throttled.
+ >0 - queue is not empty, but throttled.
<0 - queue is not empty. Device is throttled, if dev->tbusy != 0.
NOTE: Called under dev->queue_lock with locally disabled BH.
if (!netif_tx_trylock(dev)) {
collision:
/* So, someone grabbed the driver. */
-
+
/* It may be transient configuration error,
when hard_start_xmit() recurses. We detect
it by checking xmit owner and drop the
goto requeue;
}
}
-
+
{
/* And release queue */
spin_unlock(&dev->queue_lock);
int ret;
ret = dev_hard_start_xmit(skb, dev);
- if (ret == NETDEV_TX_OK) {
+ if (ret == NETDEV_TX_OK) {
if (!nolock) {
netif_tx_unlock(dev);
}
}
if (ret == NETDEV_TX_LOCKED && nolock) {
spin_lock(&dev->queue_lock);
- goto collision;
+ goto collision;
}
}
/* NETDEV_TX_BUSY - we need to requeue */
/* Release the driver */
- if (!nolock) {
+ if (!nolock) {
netif_tx_unlock(dev);
- }
+ }
spin_lock(&dev->queue_lock);
q = dev->qdisc;
}
dev->name);
dev->tx_timeout(dev);
}
- if (!mod_timer(&dev->watchdog_timer, jiffies + dev->watchdog_timeo))
+ if (!mod_timer(&dev->watchdog_timer, round_jiffies(jiffies + dev->watchdog_timeo)))
dev_hold(dev);
}
}
.enqueue = noop_enqueue,
.dequeue = noop_dequeue,
.flags = TCQ_F_BUILTIN,
- .ops = &noop_qdisc_ops,
+ .ops = &noop_qdisc_ops,
.list = LIST_HEAD_INIT(noop_qdisc.list),
};
return ERR_PTR(-err);
}
-struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
+struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops,
+ unsigned int parentid)
{
struct Qdisc *sch;
-
+
sch = qdisc_alloc(dev, ops);
if (IS_ERR(sch))
goto errout;
+ sch->parent = parentid;
if (!ops->init || ops->init(sch, NULL) == 0)
return sch;
ops->reset(qdisc);
}
-/* this is the rcu callback function to clean up a qdisc when there
+/* this is the rcu callback function to clean up a qdisc when there
* are no further references to it */
static void __qdisc_destroy(struct rcu_head *head)
if (dev->qdisc_sleeping == &noop_qdisc) {
struct Qdisc *qdisc;
if (dev->tx_queue_len) {
- qdisc = qdisc_create_dflt(dev, &pfifo_fast_ops);
+ qdisc = qdisc_create_dflt(dev, &pfifo_fast_ops,
+ TC_H_ROOT);
if (qdisc == NULL) {
printk(KERN_INFO "%s: activation failed\n", dev->name);
return;
dev->qdisc_sleeping = &noop_qdisc;
qdisc_destroy(qdisc);
#if defined(CONFIG_NET_SCH_INGRESS) || defined(CONFIG_NET_SCH_INGRESS_MODULE)
- if ((qdisc = dev->qdisc_ingress) != NULL) {
+ if ((qdisc = dev->qdisc_ingress) != NULL) {
dev->qdisc_ingress = NULL;
qdisc_destroy(qdisc);
- }
+ }
#endif
BUG_TRAP(!timer_pending(&dev->watchdog_timer));
qdisc_unlock_tree(dev);
}
-EXPORT_SYMBOL(__netdev_watchdog_up);
EXPORT_SYMBOL(netif_carrier_on);
EXPORT_SYMBOL(netif_carrier_off);
EXPORT_SYMBOL(noop_qdisc);
-EXPORT_SYMBOL(noop_qdisc_ops);
EXPORT_SYMBOL(qdisc_create_dflt);
-EXPORT_SYMBOL(qdisc_alloc);
EXPORT_SYMBOL(qdisc_destroy);
EXPORT_SYMBOL(qdisc_reset);
EXPORT_SYMBOL(qdisc_lock_tree);