|
@@ -110,7 +110,7 @@ static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
|
|
|
|
|
|
/*
|
|
|
* Transmit possibly several skbs, and handle the return status as
|
|
|
- * required. Holding the __QDISC___STATE_RUNNING bit guarantees that
|
|
|
+ * required. Owning running seqcount bit guarantees that
|
|
|
* only one CPU can execute this function.
|
|
|
*
|
|
|
* Returns to the caller:
|
|
@@ -137,10 +137,10 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
|
|
|
|
|
|
HARD_TX_UNLOCK(dev, txq);
|
|
|
} else {
|
|
|
- spin_lock(root_lock);
|
|
|
+ spin_lock_nested(root_lock, SINGLE_DEPTH_NESTING);
|
|
|
return qdisc_qlen(q);
|
|
|
}
|
|
|
- spin_lock(root_lock);
|
|
|
+ spin_lock_nested(root_lock, SINGLE_DEPTH_NESTING);
|
|
|
|
|
|
if (dev_xmit_complete(ret)) {
|
|
|
/* Driver sent out skb successfully or skb was consumed */
|
|
@@ -163,7 +163,7 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
|
|
|
/*
|
|
|
* NOTE: Called under qdisc_lock(q) with locally disabled BH.
|
|
|
*
|
|
|
- * __QDISC___STATE_RUNNING guarantees only one CPU can process
|
|
|
+ * running seqcount guarantees only one CPU can process
|
|
|
* this qdisc at a time. qdisc_lock(q) serializes queue accesses for
|
|
|
* this queue.
|
|
|
*
|
|
@@ -379,6 +379,7 @@ struct Qdisc noop_qdisc = {
|
|
|
.list = LIST_HEAD_INIT(noop_qdisc.list),
|
|
|
.q.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
|
|
|
.dev_queue = &noop_netdev_queue,
|
|
|
+ .running = SEQCNT_ZERO(noop_qdisc.running),
|
|
|
.busylock = __SPIN_LOCK_UNLOCKED(noop_qdisc.busylock),
|
|
|
};
|
|
|
EXPORT_SYMBOL(noop_qdisc);
|
|
@@ -537,6 +538,7 @@ struct Qdisc_ops pfifo_fast_ops __read_mostly = {
|
|
|
EXPORT_SYMBOL(pfifo_fast_ops);
|
|
|
|
|
|
static struct lock_class_key qdisc_tx_busylock;
|
|
|
+static struct lock_class_key qdisc_running_key;
|
|
|
|
|
|
struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
|
|
|
const struct Qdisc_ops *ops)
|
|
@@ -570,6 +572,10 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
|
|
|
lockdep_set_class(&sch->busylock,
|
|
|
dev->qdisc_tx_busylock ?: &qdisc_tx_busylock);
|
|
|
|
|
|
+ seqcount_init(&sch->running);
|
|
|
+ lockdep_set_class(&sch->running,
|
|
|
+ dev->qdisc_running_key ?: &qdisc_running_key);
|
|
|
+
|
|
|
sch->ops = ops;
|
|
|
sch->enqueue = ops->enqueue;
|
|
|
sch->dequeue = ops->dequeue;
|