162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * net/sched/sch_generic.c	Generic packet scheduler routines.
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
662306a36Sopenharmony_ci *              Jamal Hadi Salim, <hadi@cyberus.ca> 990601
762306a36Sopenharmony_ci *              - Ingress support
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/bitops.h>
1162306a36Sopenharmony_ci#include <linux/module.h>
1262306a36Sopenharmony_ci#include <linux/types.h>
1362306a36Sopenharmony_ci#include <linux/kernel.h>
1462306a36Sopenharmony_ci#include <linux/sched.h>
1562306a36Sopenharmony_ci#include <linux/string.h>
1662306a36Sopenharmony_ci#include <linux/errno.h>
1762306a36Sopenharmony_ci#include <linux/netdevice.h>
1862306a36Sopenharmony_ci#include <linux/skbuff.h>
1962306a36Sopenharmony_ci#include <linux/rtnetlink.h>
2062306a36Sopenharmony_ci#include <linux/init.h>
2162306a36Sopenharmony_ci#include <linux/rcupdate.h>
2262306a36Sopenharmony_ci#include <linux/list.h>
2362306a36Sopenharmony_ci#include <linux/slab.h>
2462306a36Sopenharmony_ci#include <linux/if_vlan.h>
2562306a36Sopenharmony_ci#include <linux/skb_array.h>
2662306a36Sopenharmony_ci#include <linux/if_macvlan.h>
2762306a36Sopenharmony_ci#include <net/sch_generic.h>
2862306a36Sopenharmony_ci#include <net/pkt_sched.h>
2962306a36Sopenharmony_ci#include <net/dst.h>
3062306a36Sopenharmony_ci#include <trace/events/qdisc.h>
3162306a36Sopenharmony_ci#include <trace/events/net.h>
3262306a36Sopenharmony_ci#include <net/xfrm.h>
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci/* Qdisc to use by default */
3562306a36Sopenharmony_ciconst struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops;
3662306a36Sopenharmony_ciEXPORT_SYMBOL(default_qdisc_ops);
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistatic void qdisc_maybe_clear_missed(struct Qdisc *q,
3962306a36Sopenharmony_ci				     const struct netdev_queue *txq)
4062306a36Sopenharmony_ci{
4162306a36Sopenharmony_ci	clear_bit(__QDISC_STATE_MISSED, &q->state);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	/* Make sure the below netif_xmit_frozen_or_stopped()
4462306a36Sopenharmony_ci	 * checking happens after clearing STATE_MISSED.
4562306a36Sopenharmony_ci	 */
4662306a36Sopenharmony_ci	smp_mb__after_atomic();
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	/* Checking netif_xmit_frozen_or_stopped() again to
4962306a36Sopenharmony_ci	 * make sure STATE_MISSED is set if the STATE_MISSED
5062306a36Sopenharmony_ci	 * set by netif_tx_wake_queue()'s rescheduling of
5162306a36Sopenharmony_ci	 * net_tx_action() is cleared by the above clear_bit().
5262306a36Sopenharmony_ci	 */
5362306a36Sopenharmony_ci	if (!netif_xmit_frozen_or_stopped(txq))
5462306a36Sopenharmony_ci		set_bit(__QDISC_STATE_MISSED, &q->state);
5562306a36Sopenharmony_ci	else
5662306a36Sopenharmony_ci		set_bit(__QDISC_STATE_DRAINING, &q->state);
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/* Main transmission queue. */
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci/* Modifications to data participating in scheduling must be protected with
6262306a36Sopenharmony_ci * qdisc_lock(qdisc) spinlock.
6362306a36Sopenharmony_ci *
6462306a36Sopenharmony_ci * The idea is the following:
6562306a36Sopenharmony_ci * - enqueue, dequeue are serialized via qdisc root lock
6662306a36Sopenharmony_ci * - ingress filtering is also serialized via qdisc root lock
6762306a36Sopenharmony_ci * - updates to tree and tree walking are only done under the rtnl mutex.
6862306a36Sopenharmony_ci */
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci#define SKB_XOFF_MAGIC ((struct sk_buff *)1UL)
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_cistatic inline struct sk_buff *__skb_dequeue_bad_txq(struct Qdisc *q)
7362306a36Sopenharmony_ci{
7462306a36Sopenharmony_ci	const struct netdev_queue *txq = q->dev_queue;
7562306a36Sopenharmony_ci	spinlock_t *lock = NULL;
7662306a36Sopenharmony_ci	struct sk_buff *skb;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	if (q->flags & TCQ_F_NOLOCK) {
7962306a36Sopenharmony_ci		lock = qdisc_lock(q);
8062306a36Sopenharmony_ci		spin_lock(lock);
8162306a36Sopenharmony_ci	}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	skb = skb_peek(&q->skb_bad_txq);
8462306a36Sopenharmony_ci	if (skb) {
8562306a36Sopenharmony_ci		/* check the reason of requeuing without tx lock first */
8662306a36Sopenharmony_ci		txq = skb_get_tx_queue(txq->dev, skb);
8762306a36Sopenharmony_ci		if (!netif_xmit_frozen_or_stopped(txq)) {
8862306a36Sopenharmony_ci			skb = __skb_dequeue(&q->skb_bad_txq);
8962306a36Sopenharmony_ci			if (qdisc_is_percpu_stats(q)) {
9062306a36Sopenharmony_ci				qdisc_qstats_cpu_backlog_dec(q, skb);
9162306a36Sopenharmony_ci				qdisc_qstats_cpu_qlen_dec(q);
9262306a36Sopenharmony_ci			} else {
9362306a36Sopenharmony_ci				qdisc_qstats_backlog_dec(q, skb);
9462306a36Sopenharmony_ci				q->q.qlen--;
9562306a36Sopenharmony_ci			}
9662306a36Sopenharmony_ci		} else {
9762306a36Sopenharmony_ci			skb = SKB_XOFF_MAGIC;
9862306a36Sopenharmony_ci			qdisc_maybe_clear_missed(q, txq);
9962306a36Sopenharmony_ci		}
10062306a36Sopenharmony_ci	}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	if (lock)
10362306a36Sopenharmony_ci		spin_unlock(lock);
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	return skb;
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_cistatic inline struct sk_buff *qdisc_dequeue_skb_bad_txq(struct Qdisc *q)
10962306a36Sopenharmony_ci{
11062306a36Sopenharmony_ci	struct sk_buff *skb = skb_peek(&q->skb_bad_txq);
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci	if (unlikely(skb))
11362306a36Sopenharmony_ci		skb = __skb_dequeue_bad_txq(q);
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	return skb;
11662306a36Sopenharmony_ci}
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_cistatic inline void qdisc_enqueue_skb_bad_txq(struct Qdisc *q,
11962306a36Sopenharmony_ci					     struct sk_buff *skb)
12062306a36Sopenharmony_ci{
12162306a36Sopenharmony_ci	spinlock_t *lock = NULL;
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	if (q->flags & TCQ_F_NOLOCK) {
12462306a36Sopenharmony_ci		lock = qdisc_lock(q);
12562306a36Sopenharmony_ci		spin_lock(lock);
12662306a36Sopenharmony_ci	}
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci	__skb_queue_tail(&q->skb_bad_txq, skb);
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci	if (qdisc_is_percpu_stats(q)) {
13162306a36Sopenharmony_ci		qdisc_qstats_cpu_backlog_inc(q, skb);
13262306a36Sopenharmony_ci		qdisc_qstats_cpu_qlen_inc(q);
13362306a36Sopenharmony_ci	} else {
13462306a36Sopenharmony_ci		qdisc_qstats_backlog_inc(q, skb);
13562306a36Sopenharmony_ci		q->q.qlen++;
13662306a36Sopenharmony_ci	}
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	if (lock)
13962306a36Sopenharmony_ci		spin_unlock(lock);
14062306a36Sopenharmony_ci}
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistatic inline void dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
14362306a36Sopenharmony_ci{
14462306a36Sopenharmony_ci	spinlock_t *lock = NULL;
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	if (q->flags & TCQ_F_NOLOCK) {
14762306a36Sopenharmony_ci		lock = qdisc_lock(q);
14862306a36Sopenharmony_ci		spin_lock(lock);
14962306a36Sopenharmony_ci	}
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	while (skb) {
15262306a36Sopenharmony_ci		struct sk_buff *next = skb->next;
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci		__skb_queue_tail(&q->gso_skb, skb);
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci		/* it's still part of the queue */
15762306a36Sopenharmony_ci		if (qdisc_is_percpu_stats(q)) {
15862306a36Sopenharmony_ci			qdisc_qstats_cpu_requeues_inc(q);
15962306a36Sopenharmony_ci			qdisc_qstats_cpu_backlog_inc(q, skb);
16062306a36Sopenharmony_ci			qdisc_qstats_cpu_qlen_inc(q);
16162306a36Sopenharmony_ci		} else {
16262306a36Sopenharmony_ci			q->qstats.requeues++;
16362306a36Sopenharmony_ci			qdisc_qstats_backlog_inc(q, skb);
16462306a36Sopenharmony_ci			q->q.qlen++;
16562306a36Sopenharmony_ci		}
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci		skb = next;
16862306a36Sopenharmony_ci	}
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	if (lock) {
17162306a36Sopenharmony_ci		spin_unlock(lock);
17262306a36Sopenharmony_ci		set_bit(__QDISC_STATE_MISSED, &q->state);
17362306a36Sopenharmony_ci	} else {
17462306a36Sopenharmony_ci		__netif_schedule(q);
17562306a36Sopenharmony_ci	}
17662306a36Sopenharmony_ci}
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_cistatic void try_bulk_dequeue_skb(struct Qdisc *q,
17962306a36Sopenharmony_ci				 struct sk_buff *skb,
18062306a36Sopenharmony_ci				 const struct netdev_queue *txq,
18162306a36Sopenharmony_ci				 int *packets)
18262306a36Sopenharmony_ci{
18362306a36Sopenharmony_ci	int bytelimit = qdisc_avail_bulklimit(txq) - skb->len;
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	while (bytelimit > 0) {
18662306a36Sopenharmony_ci		struct sk_buff *nskb = q->dequeue(q);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci		if (!nskb)
18962306a36Sopenharmony_ci			break;
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci		bytelimit -= nskb->len; /* covers GSO len */
19262306a36Sopenharmony_ci		skb->next = nskb;
19362306a36Sopenharmony_ci		skb = nskb;
19462306a36Sopenharmony_ci		(*packets)++; /* GSO counts as one pkt */
19562306a36Sopenharmony_ci	}
19662306a36Sopenharmony_ci	skb_mark_not_on_list(skb);
19762306a36Sopenharmony_ci}
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci/* This variant of try_bulk_dequeue_skb() makes sure
20062306a36Sopenharmony_ci * all skbs in the chain are for the same txq
20162306a36Sopenharmony_ci */
20262306a36Sopenharmony_cistatic void try_bulk_dequeue_skb_slow(struct Qdisc *q,
20362306a36Sopenharmony_ci				      struct sk_buff *skb,
20462306a36Sopenharmony_ci				      int *packets)
20562306a36Sopenharmony_ci{
20662306a36Sopenharmony_ci	int mapping = skb_get_queue_mapping(skb);
20762306a36Sopenharmony_ci	struct sk_buff *nskb;
20862306a36Sopenharmony_ci	int cnt = 0;
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	do {
21162306a36Sopenharmony_ci		nskb = q->dequeue(q);
21262306a36Sopenharmony_ci		if (!nskb)
21362306a36Sopenharmony_ci			break;
21462306a36Sopenharmony_ci		if (unlikely(skb_get_queue_mapping(nskb) != mapping)) {
21562306a36Sopenharmony_ci			qdisc_enqueue_skb_bad_txq(q, nskb);
21662306a36Sopenharmony_ci			break;
21762306a36Sopenharmony_ci		}
21862306a36Sopenharmony_ci		skb->next = nskb;
21962306a36Sopenharmony_ci		skb = nskb;
22062306a36Sopenharmony_ci	} while (++cnt < 8);
22162306a36Sopenharmony_ci	(*packets) += cnt;
22262306a36Sopenharmony_ci	skb_mark_not_on_list(skb);
22362306a36Sopenharmony_ci}
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci/* Note that dequeue_skb can possibly return a SKB list (via skb->next).
22662306a36Sopenharmony_ci * A requeued skb (via q->gso_skb) can also be a SKB list.
22762306a36Sopenharmony_ci */
22862306a36Sopenharmony_cistatic struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
22962306a36Sopenharmony_ci				   int *packets)
23062306a36Sopenharmony_ci{
23162306a36Sopenharmony_ci	const struct netdev_queue *txq = q->dev_queue;
23262306a36Sopenharmony_ci	struct sk_buff *skb = NULL;
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	*packets = 1;
23562306a36Sopenharmony_ci	if (unlikely(!skb_queue_empty(&q->gso_skb))) {
23662306a36Sopenharmony_ci		spinlock_t *lock = NULL;
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci		if (q->flags & TCQ_F_NOLOCK) {
23962306a36Sopenharmony_ci			lock = qdisc_lock(q);
24062306a36Sopenharmony_ci			spin_lock(lock);
24162306a36Sopenharmony_ci		}
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci		skb = skb_peek(&q->gso_skb);
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci		/* skb may be null if another cpu pulls gso_skb off in between
24662306a36Sopenharmony_ci		 * empty check and lock.
24762306a36Sopenharmony_ci		 */
24862306a36Sopenharmony_ci		if (!skb) {
24962306a36Sopenharmony_ci			if (lock)
25062306a36Sopenharmony_ci				spin_unlock(lock);
25162306a36Sopenharmony_ci			goto validate;
25262306a36Sopenharmony_ci		}
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci		/* skb in gso_skb were already validated */
25562306a36Sopenharmony_ci		*validate = false;
25662306a36Sopenharmony_ci		if (xfrm_offload(skb))
25762306a36Sopenharmony_ci			*validate = true;
25862306a36Sopenharmony_ci		/* check the reason of requeuing without tx lock first */
25962306a36Sopenharmony_ci		txq = skb_get_tx_queue(txq->dev, skb);
26062306a36Sopenharmony_ci		if (!netif_xmit_frozen_or_stopped(txq)) {
26162306a36Sopenharmony_ci			skb = __skb_dequeue(&q->gso_skb);
26262306a36Sopenharmony_ci			if (qdisc_is_percpu_stats(q)) {
26362306a36Sopenharmony_ci				qdisc_qstats_cpu_backlog_dec(q, skb);
26462306a36Sopenharmony_ci				qdisc_qstats_cpu_qlen_dec(q);
26562306a36Sopenharmony_ci			} else {
26662306a36Sopenharmony_ci				qdisc_qstats_backlog_dec(q, skb);
26762306a36Sopenharmony_ci				q->q.qlen--;
26862306a36Sopenharmony_ci			}
26962306a36Sopenharmony_ci		} else {
27062306a36Sopenharmony_ci			skb = NULL;
27162306a36Sopenharmony_ci			qdisc_maybe_clear_missed(q, txq);
27262306a36Sopenharmony_ci		}
27362306a36Sopenharmony_ci		if (lock)
27462306a36Sopenharmony_ci			spin_unlock(lock);
27562306a36Sopenharmony_ci		goto trace;
27662306a36Sopenharmony_ci	}
27762306a36Sopenharmony_civalidate:
27862306a36Sopenharmony_ci	*validate = true;
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	if ((q->flags & TCQ_F_ONETXQUEUE) &&
28162306a36Sopenharmony_ci	    netif_xmit_frozen_or_stopped(txq)) {
28262306a36Sopenharmony_ci		qdisc_maybe_clear_missed(q, txq);
28362306a36Sopenharmony_ci		return skb;
28462306a36Sopenharmony_ci	}
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	skb = qdisc_dequeue_skb_bad_txq(q);
28762306a36Sopenharmony_ci	if (unlikely(skb)) {
28862306a36Sopenharmony_ci		if (skb == SKB_XOFF_MAGIC)
28962306a36Sopenharmony_ci			return NULL;
29062306a36Sopenharmony_ci		goto bulk;
29162306a36Sopenharmony_ci	}
29262306a36Sopenharmony_ci	skb = q->dequeue(q);
29362306a36Sopenharmony_ci	if (skb) {
29462306a36Sopenharmony_cibulk:
29562306a36Sopenharmony_ci		if (qdisc_may_bulk(q))
29662306a36Sopenharmony_ci			try_bulk_dequeue_skb(q, skb, txq, packets);
29762306a36Sopenharmony_ci		else
29862306a36Sopenharmony_ci			try_bulk_dequeue_skb_slow(q, skb, packets);
29962306a36Sopenharmony_ci	}
30062306a36Sopenharmony_citrace:
30162306a36Sopenharmony_ci	trace_qdisc_dequeue(q, txq, *packets, skb);
30262306a36Sopenharmony_ci	return skb;
30362306a36Sopenharmony_ci}
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci/*
30662306a36Sopenharmony_ci * Transmit possibly several skbs, and handle the return status as
30762306a36Sopenharmony_ci * required. Owning qdisc running bit guarantees that only one CPU
30862306a36Sopenharmony_ci * can execute this function.
30962306a36Sopenharmony_ci *
31062306a36Sopenharmony_ci * Returns to the caller:
31162306a36Sopenharmony_ci *				false  - hardware queue frozen backoff
31262306a36Sopenharmony_ci *				true   - feel free to send more pkts
31362306a36Sopenharmony_ci */
31462306a36Sopenharmony_cibool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
31562306a36Sopenharmony_ci		     struct net_device *dev, struct netdev_queue *txq,
31662306a36Sopenharmony_ci		     spinlock_t *root_lock, bool validate)
31762306a36Sopenharmony_ci{
31862306a36Sopenharmony_ci	int ret = NETDEV_TX_BUSY;
31962306a36Sopenharmony_ci	bool again = false;
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_ci	/* And release qdisc */
32262306a36Sopenharmony_ci	if (root_lock)
32362306a36Sopenharmony_ci		spin_unlock(root_lock);
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	/* Note that we validate skb (GSO, checksum, ...) outside of locks */
32662306a36Sopenharmony_ci	if (validate)
32762306a36Sopenharmony_ci		skb = validate_xmit_skb_list(skb, dev, &again);
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci#ifdef CONFIG_XFRM_OFFLOAD
33062306a36Sopenharmony_ci	if (unlikely(again)) {
33162306a36Sopenharmony_ci		if (root_lock)
33262306a36Sopenharmony_ci			spin_lock(root_lock);
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci		dev_requeue_skb(skb, q);
33562306a36Sopenharmony_ci		return false;
33662306a36Sopenharmony_ci	}
33762306a36Sopenharmony_ci#endif
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_ci	if (likely(skb)) {
34062306a36Sopenharmony_ci		HARD_TX_LOCK(dev, txq, smp_processor_id());
34162306a36Sopenharmony_ci		if (!netif_xmit_frozen_or_stopped(txq))
34262306a36Sopenharmony_ci			skb = dev_hard_start_xmit(skb, dev, txq, &ret);
34362306a36Sopenharmony_ci		else
34462306a36Sopenharmony_ci			qdisc_maybe_clear_missed(q, txq);
34562306a36Sopenharmony_ci
34662306a36Sopenharmony_ci		HARD_TX_UNLOCK(dev, txq);
34762306a36Sopenharmony_ci	} else {
34862306a36Sopenharmony_ci		if (root_lock)
34962306a36Sopenharmony_ci			spin_lock(root_lock);
35062306a36Sopenharmony_ci		return true;
35162306a36Sopenharmony_ci	}
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	if (root_lock)
35462306a36Sopenharmony_ci		spin_lock(root_lock);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	if (!dev_xmit_complete(ret)) {
35762306a36Sopenharmony_ci		/* Driver returned NETDEV_TX_BUSY - requeue skb */
35862306a36Sopenharmony_ci		if (unlikely(ret != NETDEV_TX_BUSY))
35962306a36Sopenharmony_ci			net_warn_ratelimited("BUG %s code %d qlen %d\n",
36062306a36Sopenharmony_ci					     dev->name, ret, q->q.qlen);
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci		dev_requeue_skb(skb, q);
36362306a36Sopenharmony_ci		return false;
36462306a36Sopenharmony_ci	}
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	return true;
36762306a36Sopenharmony_ci}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci/*
37062306a36Sopenharmony_ci * NOTE: Called under qdisc_lock(q) with locally disabled BH.
37162306a36Sopenharmony_ci *
37262306a36Sopenharmony_ci * running seqcount guarantees only one CPU can process
37362306a36Sopenharmony_ci * this qdisc at a time. qdisc_lock(q) serializes queue accesses for
37462306a36Sopenharmony_ci * this queue.
37562306a36Sopenharmony_ci *
37662306a36Sopenharmony_ci *  netif_tx_lock serializes accesses to device driver.
37762306a36Sopenharmony_ci *
37862306a36Sopenharmony_ci *  qdisc_lock(q) and netif_tx_lock are mutually exclusive,
37962306a36Sopenharmony_ci *  if one is grabbed, another must be free.
38062306a36Sopenharmony_ci *
38162306a36Sopenharmony_ci * Note, that this procedure can be called by a watchdog timer
38262306a36Sopenharmony_ci *
38362306a36Sopenharmony_ci * Returns to the caller:
38462306a36Sopenharmony_ci *				0  - queue is empty or throttled.
38562306a36Sopenharmony_ci *				>0 - queue is not empty.
38662306a36Sopenharmony_ci *
38762306a36Sopenharmony_ci */
38862306a36Sopenharmony_cistatic inline bool qdisc_restart(struct Qdisc *q, int *packets)
38962306a36Sopenharmony_ci{
39062306a36Sopenharmony_ci	spinlock_t *root_lock = NULL;
39162306a36Sopenharmony_ci	struct netdev_queue *txq;
39262306a36Sopenharmony_ci	struct net_device *dev;
39362306a36Sopenharmony_ci	struct sk_buff *skb;
39462306a36Sopenharmony_ci	bool validate;
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	/* Dequeue packet */
39762306a36Sopenharmony_ci	skb = dequeue_skb(q, &validate, packets);
39862306a36Sopenharmony_ci	if (unlikely(!skb))
39962306a36Sopenharmony_ci		return false;
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	if (!(q->flags & TCQ_F_NOLOCK))
40262306a36Sopenharmony_ci		root_lock = qdisc_lock(q);
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	dev = qdisc_dev(q);
40562306a36Sopenharmony_ci	txq = skb_get_tx_queue(dev, skb);
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci	return sch_direct_xmit(skb, q, dev, txq, root_lock, validate);
40862306a36Sopenharmony_ci}
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_civoid __qdisc_run(struct Qdisc *q)
41162306a36Sopenharmony_ci{
41262306a36Sopenharmony_ci	int quota = READ_ONCE(dev_tx_weight);
41362306a36Sopenharmony_ci	int packets;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	while (qdisc_restart(q, &packets)) {
41662306a36Sopenharmony_ci		quota -= packets;
41762306a36Sopenharmony_ci		if (quota <= 0) {
41862306a36Sopenharmony_ci			if (q->flags & TCQ_F_NOLOCK)
41962306a36Sopenharmony_ci				set_bit(__QDISC_STATE_MISSED, &q->state);
42062306a36Sopenharmony_ci			else
42162306a36Sopenharmony_ci				__netif_schedule(q);
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci			break;
42462306a36Sopenharmony_ci		}
42562306a36Sopenharmony_ci	}
42662306a36Sopenharmony_ci}
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ciunsigned long dev_trans_start(struct net_device *dev)
42962306a36Sopenharmony_ci{
43062306a36Sopenharmony_ci	unsigned long res = READ_ONCE(netdev_get_tx_queue(dev, 0)->trans_start);
43162306a36Sopenharmony_ci	unsigned long val;
43262306a36Sopenharmony_ci	unsigned int i;
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci	for (i = 1; i < dev->num_tx_queues; i++) {
43562306a36Sopenharmony_ci		val = READ_ONCE(netdev_get_tx_queue(dev, i)->trans_start);
43662306a36Sopenharmony_ci		if (val && time_after(val, res))
43762306a36Sopenharmony_ci			res = val;
43862306a36Sopenharmony_ci	}
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	return res;
44162306a36Sopenharmony_ci}
44262306a36Sopenharmony_ciEXPORT_SYMBOL(dev_trans_start);
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_cistatic void netif_freeze_queues(struct net_device *dev)
44562306a36Sopenharmony_ci{
44662306a36Sopenharmony_ci	unsigned int i;
44762306a36Sopenharmony_ci	int cpu;
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci	cpu = smp_processor_id();
45062306a36Sopenharmony_ci	for (i = 0; i < dev->num_tx_queues; i++) {
45162306a36Sopenharmony_ci		struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci		/* We are the only thread of execution doing a
45462306a36Sopenharmony_ci		 * freeze, but we have to grab the _xmit_lock in
45562306a36Sopenharmony_ci		 * order to synchronize with threads which are in
45662306a36Sopenharmony_ci		 * the ->hard_start_xmit() handler and already
45762306a36Sopenharmony_ci		 * checked the frozen bit.
45862306a36Sopenharmony_ci		 */
45962306a36Sopenharmony_ci		__netif_tx_lock(txq, cpu);
46062306a36Sopenharmony_ci		set_bit(__QUEUE_STATE_FROZEN, &txq->state);
46162306a36Sopenharmony_ci		__netif_tx_unlock(txq);
46262306a36Sopenharmony_ci	}
46362306a36Sopenharmony_ci}
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_civoid netif_tx_lock(struct net_device *dev)
46662306a36Sopenharmony_ci{
46762306a36Sopenharmony_ci	spin_lock(&dev->tx_global_lock);
46862306a36Sopenharmony_ci	netif_freeze_queues(dev);
46962306a36Sopenharmony_ci}
47062306a36Sopenharmony_ciEXPORT_SYMBOL(netif_tx_lock);
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_cistatic void netif_unfreeze_queues(struct net_device *dev)
47362306a36Sopenharmony_ci{
47462306a36Sopenharmony_ci	unsigned int i;
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	for (i = 0; i < dev->num_tx_queues; i++) {
47762306a36Sopenharmony_ci		struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci		/* No need to grab the _xmit_lock here.  If the
48062306a36Sopenharmony_ci		 * queue is not stopped for another reason, we
48162306a36Sopenharmony_ci		 * force a schedule.
48262306a36Sopenharmony_ci		 */
48362306a36Sopenharmony_ci		clear_bit(__QUEUE_STATE_FROZEN, &txq->state);
48462306a36Sopenharmony_ci		netif_schedule_queue(txq);
48562306a36Sopenharmony_ci	}
48662306a36Sopenharmony_ci}
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_civoid netif_tx_unlock(struct net_device *dev)
48962306a36Sopenharmony_ci{
49062306a36Sopenharmony_ci	netif_unfreeze_queues(dev);
49162306a36Sopenharmony_ci	spin_unlock(&dev->tx_global_lock);
49262306a36Sopenharmony_ci}
49362306a36Sopenharmony_ciEXPORT_SYMBOL(netif_tx_unlock);
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_cistatic void dev_watchdog(struct timer_list *t)
49662306a36Sopenharmony_ci{
49762306a36Sopenharmony_ci	struct net_device *dev = from_timer(dev, t, watchdog_timer);
49862306a36Sopenharmony_ci	bool release = true;
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	spin_lock(&dev->tx_global_lock);
50162306a36Sopenharmony_ci	if (!qdisc_tx_is_noop(dev)) {
50262306a36Sopenharmony_ci		if (netif_device_present(dev) &&
50362306a36Sopenharmony_ci		    netif_running(dev) &&
50462306a36Sopenharmony_ci		    netif_carrier_ok(dev)) {
50562306a36Sopenharmony_ci			unsigned int timedout_ms = 0;
50662306a36Sopenharmony_ci			unsigned int i;
50762306a36Sopenharmony_ci			unsigned long trans_start;
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci			for (i = 0; i < dev->num_tx_queues; i++) {
51062306a36Sopenharmony_ci				struct netdev_queue *txq;
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci				txq = netdev_get_tx_queue(dev, i);
51362306a36Sopenharmony_ci				trans_start = READ_ONCE(txq->trans_start);
51462306a36Sopenharmony_ci				if (netif_xmit_stopped(txq) &&
51562306a36Sopenharmony_ci				    time_after(jiffies, (trans_start +
51662306a36Sopenharmony_ci							 dev->watchdog_timeo))) {
51762306a36Sopenharmony_ci					timedout_ms = jiffies_to_msecs(jiffies - trans_start);
51862306a36Sopenharmony_ci					atomic_long_inc(&txq->trans_timeout);
51962306a36Sopenharmony_ci					break;
52062306a36Sopenharmony_ci				}
52162306a36Sopenharmony_ci			}
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci			if (unlikely(timedout_ms)) {
52462306a36Sopenharmony_ci				trace_net_dev_xmit_timeout(dev, i);
52562306a36Sopenharmony_ci				WARN_ONCE(1, "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out %u ms\n",
52662306a36Sopenharmony_ci					  dev->name, netdev_drivername(dev), i, timedout_ms);
52762306a36Sopenharmony_ci				netif_freeze_queues(dev);
52862306a36Sopenharmony_ci				dev->netdev_ops->ndo_tx_timeout(dev, i);
52962306a36Sopenharmony_ci				netif_unfreeze_queues(dev);
53062306a36Sopenharmony_ci			}
53162306a36Sopenharmony_ci			if (!mod_timer(&dev->watchdog_timer,
53262306a36Sopenharmony_ci				       round_jiffies(jiffies +
53362306a36Sopenharmony_ci						     dev->watchdog_timeo)))
53462306a36Sopenharmony_ci				release = false;
53562306a36Sopenharmony_ci		}
53662306a36Sopenharmony_ci	}
53762306a36Sopenharmony_ci	spin_unlock(&dev->tx_global_lock);
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci	if (release)
54062306a36Sopenharmony_ci		netdev_put(dev, &dev->watchdog_dev_tracker);
54162306a36Sopenharmony_ci}
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_civoid __netdev_watchdog_up(struct net_device *dev)
54462306a36Sopenharmony_ci{
54562306a36Sopenharmony_ci	if (dev->netdev_ops->ndo_tx_timeout) {
54662306a36Sopenharmony_ci		if (dev->watchdog_timeo <= 0)
54762306a36Sopenharmony_ci			dev->watchdog_timeo = 5*HZ;
54862306a36Sopenharmony_ci		if (!mod_timer(&dev->watchdog_timer,
54962306a36Sopenharmony_ci			       round_jiffies(jiffies + dev->watchdog_timeo)))
55062306a36Sopenharmony_ci			netdev_hold(dev, &dev->watchdog_dev_tracker,
55162306a36Sopenharmony_ci				    GFP_ATOMIC);
55262306a36Sopenharmony_ci	}
55362306a36Sopenharmony_ci}
55462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(__netdev_watchdog_up);
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_cistatic void dev_watchdog_up(struct net_device *dev)
55762306a36Sopenharmony_ci{
55862306a36Sopenharmony_ci	__netdev_watchdog_up(dev);
55962306a36Sopenharmony_ci}
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_cistatic void dev_watchdog_down(struct net_device *dev)
56262306a36Sopenharmony_ci{
56362306a36Sopenharmony_ci	netif_tx_lock_bh(dev);
56462306a36Sopenharmony_ci	if (del_timer(&dev->watchdog_timer))
56562306a36Sopenharmony_ci		netdev_put(dev, &dev->watchdog_dev_tracker);
56662306a36Sopenharmony_ci	netif_tx_unlock_bh(dev);
56762306a36Sopenharmony_ci}
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci/**
57062306a36Sopenharmony_ci *	netif_carrier_on - set carrier
57162306a36Sopenharmony_ci *	@dev: network device
57262306a36Sopenharmony_ci *
57362306a36Sopenharmony_ci * Device has detected acquisition of carrier.
57462306a36Sopenharmony_ci */
57562306a36Sopenharmony_civoid netif_carrier_on(struct net_device *dev)
57662306a36Sopenharmony_ci{
57762306a36Sopenharmony_ci	if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) {
57862306a36Sopenharmony_ci		if (dev->reg_state == NETREG_UNINITIALIZED)
57962306a36Sopenharmony_ci			return;
58062306a36Sopenharmony_ci		atomic_inc(&dev->carrier_up_count);
58162306a36Sopenharmony_ci		linkwatch_fire_event(dev);
58262306a36Sopenharmony_ci		if (netif_running(dev))
58362306a36Sopenharmony_ci			__netdev_watchdog_up(dev);
58462306a36Sopenharmony_ci	}
58562306a36Sopenharmony_ci}
58662306a36Sopenharmony_ciEXPORT_SYMBOL(netif_carrier_on);
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci/**
58962306a36Sopenharmony_ci *	netif_carrier_off - clear carrier
59062306a36Sopenharmony_ci *	@dev: network device
59162306a36Sopenharmony_ci *
59262306a36Sopenharmony_ci * Device has detected loss of carrier.
59362306a36Sopenharmony_ci */
59462306a36Sopenharmony_civoid netif_carrier_off(struct net_device *dev)
59562306a36Sopenharmony_ci{
59662306a36Sopenharmony_ci	if (!test_and_set_bit(__LINK_STATE_NOCARRIER, &dev->state)) {
59762306a36Sopenharmony_ci		if (dev->reg_state == NETREG_UNINITIALIZED)
59862306a36Sopenharmony_ci			return;
59962306a36Sopenharmony_ci		atomic_inc(&dev->carrier_down_count);
60062306a36Sopenharmony_ci		linkwatch_fire_event(dev);
60162306a36Sopenharmony_ci	}
60262306a36Sopenharmony_ci}
60362306a36Sopenharmony_ciEXPORT_SYMBOL(netif_carrier_off);
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci/**
60662306a36Sopenharmony_ci *	netif_carrier_event - report carrier state event
60762306a36Sopenharmony_ci *	@dev: network device
60862306a36Sopenharmony_ci *
60962306a36Sopenharmony_ci * Device has detected a carrier event but the carrier state wasn't changed.
61062306a36Sopenharmony_ci * Use in drivers when querying carrier state asynchronously, to avoid missing
61162306a36Sopenharmony_ci * events (link flaps) if link recovers before it's queried.
61262306a36Sopenharmony_ci */
61362306a36Sopenharmony_civoid netif_carrier_event(struct net_device *dev)
61462306a36Sopenharmony_ci{
61562306a36Sopenharmony_ci	if (dev->reg_state == NETREG_UNINITIALIZED)
61662306a36Sopenharmony_ci		return;
61762306a36Sopenharmony_ci	atomic_inc(&dev->carrier_up_count);
61862306a36Sopenharmony_ci	atomic_inc(&dev->carrier_down_count);
61962306a36Sopenharmony_ci	linkwatch_fire_event(dev);
62062306a36Sopenharmony_ci}
62162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(netif_carrier_event);
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci/* "NOOP" scheduler: the best scheduler, recommended for all interfaces
62462306a36Sopenharmony_ci   under all circumstances. It is difficult to invent anything faster or
62562306a36Sopenharmony_ci   cheaper.
62662306a36Sopenharmony_ci */
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_cistatic int noop_enqueue(struct sk_buff *skb, struct Qdisc *qdisc,
62962306a36Sopenharmony_ci			struct sk_buff **to_free)
63062306a36Sopenharmony_ci{
63162306a36Sopenharmony_ci	__qdisc_drop(skb, to_free);
63262306a36Sopenharmony_ci	return NET_XMIT_CN;
63362306a36Sopenharmony_ci}
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_cistatic struct sk_buff *noop_dequeue(struct Qdisc *qdisc)
63662306a36Sopenharmony_ci{
63762306a36Sopenharmony_ci	return NULL;
63862306a36Sopenharmony_ci}
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_cistruct Qdisc_ops noop_qdisc_ops __read_mostly = {
64162306a36Sopenharmony_ci	.id		=	"noop",
64262306a36Sopenharmony_ci	.priv_size	=	0,
64362306a36Sopenharmony_ci	.enqueue	=	noop_enqueue,
64462306a36Sopenharmony_ci	.dequeue	=	noop_dequeue,
64562306a36Sopenharmony_ci	.peek		=	noop_dequeue,
64662306a36Sopenharmony_ci	.owner		=	THIS_MODULE,
64762306a36Sopenharmony_ci};
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_cistatic struct netdev_queue noop_netdev_queue = {
65062306a36Sopenharmony_ci	RCU_POINTER_INITIALIZER(qdisc, &noop_qdisc),
65162306a36Sopenharmony_ci	RCU_POINTER_INITIALIZER(qdisc_sleeping, &noop_qdisc),
65262306a36Sopenharmony_ci};
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_cistruct Qdisc noop_qdisc = {
65562306a36Sopenharmony_ci	.enqueue	=	noop_enqueue,
65662306a36Sopenharmony_ci	.dequeue	=	noop_dequeue,
65762306a36Sopenharmony_ci	.flags		=	TCQ_F_BUILTIN,
65862306a36Sopenharmony_ci	.ops		=	&noop_qdisc_ops,
65962306a36Sopenharmony_ci	.q.lock		=	__SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
66062306a36Sopenharmony_ci	.dev_queue	=	&noop_netdev_queue,
66162306a36Sopenharmony_ci	.busylock	=	__SPIN_LOCK_UNLOCKED(noop_qdisc.busylock),
66262306a36Sopenharmony_ci	.gso_skb = {
66362306a36Sopenharmony_ci		.next = (struct sk_buff *)&noop_qdisc.gso_skb,
66462306a36Sopenharmony_ci		.prev = (struct sk_buff *)&noop_qdisc.gso_skb,
66562306a36Sopenharmony_ci		.qlen = 0,
66662306a36Sopenharmony_ci		.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.gso_skb.lock),
66762306a36Sopenharmony_ci	},
66862306a36Sopenharmony_ci	.skb_bad_txq = {
66962306a36Sopenharmony_ci		.next = (struct sk_buff *)&noop_qdisc.skb_bad_txq,
67062306a36Sopenharmony_ci		.prev = (struct sk_buff *)&noop_qdisc.skb_bad_txq,
67162306a36Sopenharmony_ci		.qlen = 0,
67262306a36Sopenharmony_ci		.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.skb_bad_txq.lock),
67362306a36Sopenharmony_ci	},
67462306a36Sopenharmony_ci};
67562306a36Sopenharmony_ciEXPORT_SYMBOL(noop_qdisc);
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_cistatic int noqueue_init(struct Qdisc *qdisc, struct nlattr *opt,
67862306a36Sopenharmony_ci			struct netlink_ext_ack *extack)
67962306a36Sopenharmony_ci{
68062306a36Sopenharmony_ci	/* register_qdisc() assigns a default of noop_enqueue if unset,
68162306a36Sopenharmony_ci	 * but __dev_queue_xmit() treats noqueue only as such
68262306a36Sopenharmony_ci	 * if this is NULL - so clear it here. */
68362306a36Sopenharmony_ci	qdisc->enqueue = NULL;
68462306a36Sopenharmony_ci	return 0;
68562306a36Sopenharmony_ci}
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_cistruct Qdisc_ops noqueue_qdisc_ops __read_mostly = {
68862306a36Sopenharmony_ci	.id		=	"noqueue",
68962306a36Sopenharmony_ci	.priv_size	=	0,
69062306a36Sopenharmony_ci	.init		=	noqueue_init,
69162306a36Sopenharmony_ci	.enqueue	=	noop_enqueue,
69262306a36Sopenharmony_ci	.dequeue	=	noop_dequeue,
69362306a36Sopenharmony_ci	.peek		=	noop_dequeue,
69462306a36Sopenharmony_ci	.owner		=	THIS_MODULE,
69562306a36Sopenharmony_ci};
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_cistatic const u8 prio2band[TC_PRIO_MAX + 1] = {
69862306a36Sopenharmony_ci	1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1
69962306a36Sopenharmony_ci};
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_ci/* 3-band FIFO queue: old style, but should be a bit faster than
70262306a36Sopenharmony_ci   generic prio+fifo combination.
70362306a36Sopenharmony_ci */
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci#define PFIFO_FAST_BANDS 3
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci/*
70862306a36Sopenharmony_ci * Private data for a pfifo_fast scheduler containing:
70962306a36Sopenharmony_ci *	- rings for priority bands
71062306a36Sopenharmony_ci */
71162306a36Sopenharmony_cistruct pfifo_fast_priv {
71262306a36Sopenharmony_ci	struct skb_array q[PFIFO_FAST_BANDS];
71362306a36Sopenharmony_ci};
71462306a36Sopenharmony_ci
71562306a36Sopenharmony_cistatic inline struct skb_array *band2list(struct pfifo_fast_priv *priv,
71662306a36Sopenharmony_ci					  int band)
71762306a36Sopenharmony_ci{
71862306a36Sopenharmony_ci	return &priv->q[band];
71962306a36Sopenharmony_ci}
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_cistatic int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc,
72262306a36Sopenharmony_ci			      struct sk_buff **to_free)
72362306a36Sopenharmony_ci{
72462306a36Sopenharmony_ci	int band = prio2band[skb->priority & TC_PRIO_MAX];
72562306a36Sopenharmony_ci	struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
72662306a36Sopenharmony_ci	struct skb_array *q = band2list(priv, band);
72762306a36Sopenharmony_ci	unsigned int pkt_len = qdisc_pkt_len(skb);
72862306a36Sopenharmony_ci	int err;
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci	err = skb_array_produce(q, skb);
73162306a36Sopenharmony_ci
73262306a36Sopenharmony_ci	if (unlikely(err)) {
73362306a36Sopenharmony_ci		if (qdisc_is_percpu_stats(qdisc))
73462306a36Sopenharmony_ci			return qdisc_drop_cpu(skb, qdisc, to_free);
73562306a36Sopenharmony_ci		else
73662306a36Sopenharmony_ci			return qdisc_drop(skb, qdisc, to_free);
73762306a36Sopenharmony_ci	}
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci	qdisc_update_stats_at_enqueue(qdisc, pkt_len);
74062306a36Sopenharmony_ci	return NET_XMIT_SUCCESS;
74162306a36Sopenharmony_ci}
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_cistatic struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc)
74462306a36Sopenharmony_ci{
74562306a36Sopenharmony_ci	struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
74662306a36Sopenharmony_ci	struct sk_buff *skb = NULL;
74762306a36Sopenharmony_ci	bool need_retry = true;
74862306a36Sopenharmony_ci	int band;
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ciretry:
75162306a36Sopenharmony_ci	for (band = 0; band < PFIFO_FAST_BANDS && !skb; band++) {
75262306a36Sopenharmony_ci		struct skb_array *q = band2list(priv, band);
75362306a36Sopenharmony_ci
75462306a36Sopenharmony_ci		if (__skb_array_empty(q))
75562306a36Sopenharmony_ci			continue;
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ci		skb = __skb_array_consume(q);
75862306a36Sopenharmony_ci	}
75962306a36Sopenharmony_ci	if (likely(skb)) {
76062306a36Sopenharmony_ci		qdisc_update_stats_at_dequeue(qdisc, skb);
76162306a36Sopenharmony_ci	} else if (need_retry &&
76262306a36Sopenharmony_ci		   READ_ONCE(qdisc->state) & QDISC_STATE_NON_EMPTY) {
76362306a36Sopenharmony_ci		/* Delay clearing the STATE_MISSED here to reduce
76462306a36Sopenharmony_ci		 * the overhead of the second spin_trylock() in
76562306a36Sopenharmony_ci		 * qdisc_run_begin() and __netif_schedule() calling
76662306a36Sopenharmony_ci		 * in qdisc_run_end().
76762306a36Sopenharmony_ci		 */
76862306a36Sopenharmony_ci		clear_bit(__QDISC_STATE_MISSED, &qdisc->state);
76962306a36Sopenharmony_ci		clear_bit(__QDISC_STATE_DRAINING, &qdisc->state);
77062306a36Sopenharmony_ci
77162306a36Sopenharmony_ci		/* Make sure dequeuing happens after clearing
77262306a36Sopenharmony_ci		 * STATE_MISSED.
77362306a36Sopenharmony_ci		 */
77462306a36Sopenharmony_ci		smp_mb__after_atomic();
77562306a36Sopenharmony_ci
77662306a36Sopenharmony_ci		need_retry = false;
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_ci		goto retry;
77962306a36Sopenharmony_ci	}
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_ci	return skb;
78262306a36Sopenharmony_ci}
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_cistatic struct sk_buff *pfifo_fast_peek(struct Qdisc *qdisc)
78562306a36Sopenharmony_ci{
78662306a36Sopenharmony_ci	struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
78762306a36Sopenharmony_ci	struct sk_buff *skb = NULL;
78862306a36Sopenharmony_ci	int band;
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ci	for (band = 0; band < PFIFO_FAST_BANDS && !skb; band++) {
79162306a36Sopenharmony_ci		struct skb_array *q = band2list(priv, band);
79262306a36Sopenharmony_ci
79362306a36Sopenharmony_ci		skb = __skb_array_peek(q);
79462306a36Sopenharmony_ci	}
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci	return skb;
79762306a36Sopenharmony_ci}
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_cistatic void pfifo_fast_reset(struct Qdisc *qdisc)
80062306a36Sopenharmony_ci{
80162306a36Sopenharmony_ci	int i, band;
80262306a36Sopenharmony_ci	struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	for (band = 0; band < PFIFO_FAST_BANDS; band++) {
80562306a36Sopenharmony_ci		struct skb_array *q = band2list(priv, band);
80662306a36Sopenharmony_ci		struct sk_buff *skb;
80762306a36Sopenharmony_ci
80862306a36Sopenharmony_ci		/* NULL ring is possible if destroy path is due to a failed
80962306a36Sopenharmony_ci		 * skb_array_init() in pfifo_fast_init() case.
81062306a36Sopenharmony_ci		 */
81162306a36Sopenharmony_ci		if (!q->ring.queue)
81262306a36Sopenharmony_ci			continue;
81362306a36Sopenharmony_ci
81462306a36Sopenharmony_ci		while ((skb = __skb_array_consume(q)) != NULL)
81562306a36Sopenharmony_ci			kfree_skb(skb);
81662306a36Sopenharmony_ci	}
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	if (qdisc_is_percpu_stats(qdisc)) {
81962306a36Sopenharmony_ci		for_each_possible_cpu(i) {
82062306a36Sopenharmony_ci			struct gnet_stats_queue *q;
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_ci			q = per_cpu_ptr(qdisc->cpu_qstats, i);
82362306a36Sopenharmony_ci			q->backlog = 0;
82462306a36Sopenharmony_ci			q->qlen = 0;
82562306a36Sopenharmony_ci		}
82662306a36Sopenharmony_ci	}
82762306a36Sopenharmony_ci}
82862306a36Sopenharmony_ci
82962306a36Sopenharmony_cistatic int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb)
83062306a36Sopenharmony_ci{
83162306a36Sopenharmony_ci	struct tc_prio_qopt opt = { .bands = PFIFO_FAST_BANDS };
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci	memcpy(&opt.priomap, prio2band, TC_PRIO_MAX + 1);
83462306a36Sopenharmony_ci	if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
83562306a36Sopenharmony_ci		goto nla_put_failure;
83662306a36Sopenharmony_ci	return skb->len;
83762306a36Sopenharmony_ci
83862306a36Sopenharmony_cinla_put_failure:
83962306a36Sopenharmony_ci	return -1;
84062306a36Sopenharmony_ci}
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_cistatic int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt,
84362306a36Sopenharmony_ci			   struct netlink_ext_ack *extack)
84462306a36Sopenharmony_ci{
84562306a36Sopenharmony_ci	unsigned int qlen = qdisc_dev(qdisc)->tx_queue_len;
84662306a36Sopenharmony_ci	struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
84762306a36Sopenharmony_ci	int prio;
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci	/* guard against zero length rings */
85062306a36Sopenharmony_ci	if (!qlen)
85162306a36Sopenharmony_ci		return -EINVAL;
85262306a36Sopenharmony_ci
85362306a36Sopenharmony_ci	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
85462306a36Sopenharmony_ci		struct skb_array *q = band2list(priv, prio);
85562306a36Sopenharmony_ci		int err;
85662306a36Sopenharmony_ci
85762306a36Sopenharmony_ci		err = skb_array_init(q, qlen, GFP_KERNEL);
85862306a36Sopenharmony_ci		if (err)
85962306a36Sopenharmony_ci			return -ENOMEM;
86062306a36Sopenharmony_ci	}
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ci	/* Can by-pass the queue discipline */
86362306a36Sopenharmony_ci	qdisc->flags |= TCQ_F_CAN_BYPASS;
86462306a36Sopenharmony_ci	return 0;
86562306a36Sopenharmony_ci}
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_cistatic void pfifo_fast_destroy(struct Qdisc *sch)
86862306a36Sopenharmony_ci{
86962306a36Sopenharmony_ci	struct pfifo_fast_priv *priv = qdisc_priv(sch);
87062306a36Sopenharmony_ci	int prio;
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_ci	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
87362306a36Sopenharmony_ci		struct skb_array *q = band2list(priv, prio);
87462306a36Sopenharmony_ci
87562306a36Sopenharmony_ci		/* NULL ring is possible if destroy path is due to a failed
87662306a36Sopenharmony_ci		 * skb_array_init() in pfifo_fast_init() case.
87762306a36Sopenharmony_ci		 */
87862306a36Sopenharmony_ci		if (!q->ring.queue)
87962306a36Sopenharmony_ci			continue;
88062306a36Sopenharmony_ci		/* Destroy ring but no need to kfree_skb because a call to
88162306a36Sopenharmony_ci		 * pfifo_fast_reset() has already done that work.
88262306a36Sopenharmony_ci		 */
88362306a36Sopenharmony_ci		ptr_ring_cleanup(&q->ring, NULL);
88462306a36Sopenharmony_ci	}
88562306a36Sopenharmony_ci}
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_cistatic int pfifo_fast_change_tx_queue_len(struct Qdisc *sch,
88862306a36Sopenharmony_ci					  unsigned int new_len)
88962306a36Sopenharmony_ci{
89062306a36Sopenharmony_ci	struct pfifo_fast_priv *priv = qdisc_priv(sch);
89162306a36Sopenharmony_ci	struct skb_array *bands[PFIFO_FAST_BANDS];
89262306a36Sopenharmony_ci	int prio;
89362306a36Sopenharmony_ci
89462306a36Sopenharmony_ci	for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
89562306a36Sopenharmony_ci		struct skb_array *q = band2list(priv, prio);
89662306a36Sopenharmony_ci
89762306a36Sopenharmony_ci		bands[prio] = q;
89862306a36Sopenharmony_ci	}
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ci	return skb_array_resize_multiple(bands, PFIFO_FAST_BANDS, new_len,
90162306a36Sopenharmony_ci					 GFP_KERNEL);
90262306a36Sopenharmony_ci}
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_cistruct Qdisc_ops pfifo_fast_ops __read_mostly = {
90562306a36Sopenharmony_ci	.id		=	"pfifo_fast",
90662306a36Sopenharmony_ci	.priv_size	=	sizeof(struct pfifo_fast_priv),
90762306a36Sopenharmony_ci	.enqueue	=	pfifo_fast_enqueue,
90862306a36Sopenharmony_ci	.dequeue	=	pfifo_fast_dequeue,
90962306a36Sopenharmony_ci	.peek		=	pfifo_fast_peek,
91062306a36Sopenharmony_ci	.init		=	pfifo_fast_init,
91162306a36Sopenharmony_ci	.destroy	=	pfifo_fast_destroy,
91262306a36Sopenharmony_ci	.reset		=	pfifo_fast_reset,
91362306a36Sopenharmony_ci	.dump		=	pfifo_fast_dump,
91462306a36Sopenharmony_ci	.change_tx_queue_len =  pfifo_fast_change_tx_queue_len,
91562306a36Sopenharmony_ci	.owner		=	THIS_MODULE,
91662306a36Sopenharmony_ci	.static_flags	=	TCQ_F_NOLOCK | TCQ_F_CPUSTATS,
91762306a36Sopenharmony_ci};
91862306a36Sopenharmony_ciEXPORT_SYMBOL(pfifo_fast_ops);
91962306a36Sopenharmony_ci
92062306a36Sopenharmony_cistatic struct lock_class_key qdisc_tx_busylock;
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_cistruct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
92362306a36Sopenharmony_ci			  const struct Qdisc_ops *ops,
92462306a36Sopenharmony_ci			  struct netlink_ext_ack *extack)
92562306a36Sopenharmony_ci{
92662306a36Sopenharmony_ci	struct Qdisc *sch;
92762306a36Sopenharmony_ci	unsigned int size = sizeof(*sch) + ops->priv_size;
92862306a36Sopenharmony_ci	int err = -ENOBUFS;
92962306a36Sopenharmony_ci	struct net_device *dev;
93062306a36Sopenharmony_ci
93162306a36Sopenharmony_ci	if (!dev_queue) {
93262306a36Sopenharmony_ci		NL_SET_ERR_MSG(extack, "No device queue given");
93362306a36Sopenharmony_ci		err = -EINVAL;
93462306a36Sopenharmony_ci		goto errout;
93562306a36Sopenharmony_ci	}
93662306a36Sopenharmony_ci
93762306a36Sopenharmony_ci	dev = dev_queue->dev;
93862306a36Sopenharmony_ci	sch = kzalloc_node(size, GFP_KERNEL, netdev_queue_numa_node_read(dev_queue));
93962306a36Sopenharmony_ci
94062306a36Sopenharmony_ci	if (!sch)
94162306a36Sopenharmony_ci		goto errout;
94262306a36Sopenharmony_ci	__skb_queue_head_init(&sch->gso_skb);
94362306a36Sopenharmony_ci	__skb_queue_head_init(&sch->skb_bad_txq);
94462306a36Sopenharmony_ci	gnet_stats_basic_sync_init(&sch->bstats);
94562306a36Sopenharmony_ci	spin_lock_init(&sch->q.lock);
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci	if (ops->static_flags & TCQ_F_CPUSTATS) {
94862306a36Sopenharmony_ci		sch->cpu_bstats =
94962306a36Sopenharmony_ci			netdev_alloc_pcpu_stats(struct gnet_stats_basic_sync);
95062306a36Sopenharmony_ci		if (!sch->cpu_bstats)
95162306a36Sopenharmony_ci			goto errout1;
95262306a36Sopenharmony_ci
95362306a36Sopenharmony_ci		sch->cpu_qstats = alloc_percpu(struct gnet_stats_queue);
95462306a36Sopenharmony_ci		if (!sch->cpu_qstats) {
95562306a36Sopenharmony_ci			free_percpu(sch->cpu_bstats);
95662306a36Sopenharmony_ci			goto errout1;
95762306a36Sopenharmony_ci		}
95862306a36Sopenharmony_ci	}
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci	spin_lock_init(&sch->busylock);
96162306a36Sopenharmony_ci	lockdep_set_class(&sch->busylock,
96262306a36Sopenharmony_ci			  dev->qdisc_tx_busylock ?: &qdisc_tx_busylock);
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci	/* seqlock has the same scope of busylock, for NOLOCK qdisc */
96562306a36Sopenharmony_ci	spin_lock_init(&sch->seqlock);
96662306a36Sopenharmony_ci	lockdep_set_class(&sch->seqlock,
96762306a36Sopenharmony_ci			  dev->qdisc_tx_busylock ?: &qdisc_tx_busylock);
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci	sch->ops = ops;
97062306a36Sopenharmony_ci	sch->flags = ops->static_flags;
97162306a36Sopenharmony_ci	sch->enqueue = ops->enqueue;
97262306a36Sopenharmony_ci	sch->dequeue = ops->dequeue;
97362306a36Sopenharmony_ci	sch->dev_queue = dev_queue;
97462306a36Sopenharmony_ci	netdev_hold(dev, &sch->dev_tracker, GFP_KERNEL);
97562306a36Sopenharmony_ci	refcount_set(&sch->refcnt, 1);
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_ci	return sch;
97862306a36Sopenharmony_cierrout1:
97962306a36Sopenharmony_ci	kfree(sch);
98062306a36Sopenharmony_cierrout:
98162306a36Sopenharmony_ci	return ERR_PTR(err);
98262306a36Sopenharmony_ci}
98362306a36Sopenharmony_ci
98462306a36Sopenharmony_cistruct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
98562306a36Sopenharmony_ci				const struct Qdisc_ops *ops,
98662306a36Sopenharmony_ci				unsigned int parentid,
98762306a36Sopenharmony_ci				struct netlink_ext_ack *extack)
98862306a36Sopenharmony_ci{
98962306a36Sopenharmony_ci	struct Qdisc *sch;
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci	if (!try_module_get(ops->owner)) {
99262306a36Sopenharmony_ci		NL_SET_ERR_MSG(extack, "Failed to increase module reference counter");
99362306a36Sopenharmony_ci		return NULL;
99462306a36Sopenharmony_ci	}
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci	sch = qdisc_alloc(dev_queue, ops, extack);
99762306a36Sopenharmony_ci	if (IS_ERR(sch)) {
99862306a36Sopenharmony_ci		module_put(ops->owner);
99962306a36Sopenharmony_ci		return NULL;
100062306a36Sopenharmony_ci	}
100162306a36Sopenharmony_ci	sch->parent = parentid;
100262306a36Sopenharmony_ci
100362306a36Sopenharmony_ci	if (!ops->init || ops->init(sch, NULL, extack) == 0) {
100462306a36Sopenharmony_ci		trace_qdisc_create(ops, dev_queue->dev, parentid);
100562306a36Sopenharmony_ci		return sch;
100662306a36Sopenharmony_ci	}
100762306a36Sopenharmony_ci
100862306a36Sopenharmony_ci	qdisc_put(sch);
100962306a36Sopenharmony_ci	return NULL;
101062306a36Sopenharmony_ci}
101162306a36Sopenharmony_ciEXPORT_SYMBOL(qdisc_create_dflt);
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ci/* Under qdisc_lock(qdisc) and BH! */
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_civoid qdisc_reset(struct Qdisc *qdisc)
101662306a36Sopenharmony_ci{
101762306a36Sopenharmony_ci	const struct Qdisc_ops *ops = qdisc->ops;
101862306a36Sopenharmony_ci
101962306a36Sopenharmony_ci	trace_qdisc_reset(qdisc);
102062306a36Sopenharmony_ci
102162306a36Sopenharmony_ci	if (ops->reset)
102262306a36Sopenharmony_ci		ops->reset(qdisc);
102362306a36Sopenharmony_ci
102462306a36Sopenharmony_ci	__skb_queue_purge(&qdisc->gso_skb);
102562306a36Sopenharmony_ci	__skb_queue_purge(&qdisc->skb_bad_txq);
102662306a36Sopenharmony_ci
102762306a36Sopenharmony_ci	qdisc->q.qlen = 0;
102862306a36Sopenharmony_ci	qdisc->qstats.backlog = 0;
102962306a36Sopenharmony_ci}
103062306a36Sopenharmony_ciEXPORT_SYMBOL(qdisc_reset);
103162306a36Sopenharmony_ci
103262306a36Sopenharmony_civoid qdisc_free(struct Qdisc *qdisc)
103362306a36Sopenharmony_ci{
103462306a36Sopenharmony_ci	if (qdisc_is_percpu_stats(qdisc)) {
103562306a36Sopenharmony_ci		free_percpu(qdisc->cpu_bstats);
103662306a36Sopenharmony_ci		free_percpu(qdisc->cpu_qstats);
103762306a36Sopenharmony_ci	}
103862306a36Sopenharmony_ci
103962306a36Sopenharmony_ci	kfree(qdisc);
104062306a36Sopenharmony_ci}
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_cistatic void qdisc_free_cb(struct rcu_head *head)
104362306a36Sopenharmony_ci{
104462306a36Sopenharmony_ci	struct Qdisc *q = container_of(head, struct Qdisc, rcu);
104562306a36Sopenharmony_ci
104662306a36Sopenharmony_ci	qdisc_free(q);
104762306a36Sopenharmony_ci}
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_cistatic void __qdisc_destroy(struct Qdisc *qdisc)
105062306a36Sopenharmony_ci{
105162306a36Sopenharmony_ci	const struct Qdisc_ops  *ops = qdisc->ops;
105262306a36Sopenharmony_ci
105362306a36Sopenharmony_ci#ifdef CONFIG_NET_SCHED
105462306a36Sopenharmony_ci	qdisc_hash_del(qdisc);
105562306a36Sopenharmony_ci
105662306a36Sopenharmony_ci	qdisc_put_stab(rtnl_dereference(qdisc->stab));
105762306a36Sopenharmony_ci#endif
105862306a36Sopenharmony_ci	gen_kill_estimator(&qdisc->rate_est);
105962306a36Sopenharmony_ci
106062306a36Sopenharmony_ci	qdisc_reset(qdisc);
106162306a36Sopenharmony_ci
106262306a36Sopenharmony_ci	if (ops->destroy)
106362306a36Sopenharmony_ci		ops->destroy(qdisc);
106462306a36Sopenharmony_ci
106562306a36Sopenharmony_ci	module_put(ops->owner);
106662306a36Sopenharmony_ci	netdev_put(qdisc_dev(qdisc), &qdisc->dev_tracker);
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_ci	trace_qdisc_destroy(qdisc);
106962306a36Sopenharmony_ci
107062306a36Sopenharmony_ci	call_rcu(&qdisc->rcu, qdisc_free_cb);
107162306a36Sopenharmony_ci}
107262306a36Sopenharmony_ci
107362306a36Sopenharmony_civoid qdisc_destroy(struct Qdisc *qdisc)
107462306a36Sopenharmony_ci{
107562306a36Sopenharmony_ci	if (qdisc->flags & TCQ_F_BUILTIN)
107662306a36Sopenharmony_ci		return;
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_ci	__qdisc_destroy(qdisc);
107962306a36Sopenharmony_ci}
108062306a36Sopenharmony_ci
108162306a36Sopenharmony_civoid qdisc_put(struct Qdisc *qdisc)
108262306a36Sopenharmony_ci{
108362306a36Sopenharmony_ci	if (!qdisc)
108462306a36Sopenharmony_ci		return;
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_ci	if (qdisc->flags & TCQ_F_BUILTIN ||
108762306a36Sopenharmony_ci	    !refcount_dec_and_test(&qdisc->refcnt))
108862306a36Sopenharmony_ci		return;
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ci	__qdisc_destroy(qdisc);
109162306a36Sopenharmony_ci}
109262306a36Sopenharmony_ciEXPORT_SYMBOL(qdisc_put);
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci/* Version of qdisc_put() that is called with rtnl mutex unlocked.
109562306a36Sopenharmony_ci * Intended to be used as optimization, this function only takes rtnl lock if
109662306a36Sopenharmony_ci * qdisc reference counter reached zero.
109762306a36Sopenharmony_ci */
109862306a36Sopenharmony_ci
109962306a36Sopenharmony_civoid qdisc_put_unlocked(struct Qdisc *qdisc)
110062306a36Sopenharmony_ci{
110162306a36Sopenharmony_ci	if (qdisc->flags & TCQ_F_BUILTIN ||
110262306a36Sopenharmony_ci	    !refcount_dec_and_rtnl_lock(&qdisc->refcnt))
110362306a36Sopenharmony_ci		return;
110462306a36Sopenharmony_ci
110562306a36Sopenharmony_ci	__qdisc_destroy(qdisc);
110662306a36Sopenharmony_ci	rtnl_unlock();
110762306a36Sopenharmony_ci}
110862306a36Sopenharmony_ciEXPORT_SYMBOL(qdisc_put_unlocked);
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_ci/* Attach toplevel qdisc to device queue. */
111162306a36Sopenharmony_cistruct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
111262306a36Sopenharmony_ci			      struct Qdisc *qdisc)
111362306a36Sopenharmony_ci{
111462306a36Sopenharmony_ci	struct Qdisc *oqdisc = rtnl_dereference(dev_queue->qdisc_sleeping);
111562306a36Sopenharmony_ci	spinlock_t *root_lock;
111662306a36Sopenharmony_ci
111762306a36Sopenharmony_ci	root_lock = qdisc_lock(oqdisc);
111862306a36Sopenharmony_ci	spin_lock_bh(root_lock);
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci	/* ... and graft new one */
112162306a36Sopenharmony_ci	if (qdisc == NULL)
112262306a36Sopenharmony_ci		qdisc = &noop_qdisc;
112362306a36Sopenharmony_ci	rcu_assign_pointer(dev_queue->qdisc_sleeping, qdisc);
112462306a36Sopenharmony_ci	rcu_assign_pointer(dev_queue->qdisc, &noop_qdisc);
112562306a36Sopenharmony_ci
112662306a36Sopenharmony_ci	spin_unlock_bh(root_lock);
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_ci	return oqdisc;
112962306a36Sopenharmony_ci}
113062306a36Sopenharmony_ciEXPORT_SYMBOL(dev_graft_qdisc);
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_cistatic void shutdown_scheduler_queue(struct net_device *dev,
113362306a36Sopenharmony_ci				     struct netdev_queue *dev_queue,
113462306a36Sopenharmony_ci				     void *_qdisc_default)
113562306a36Sopenharmony_ci{
113662306a36Sopenharmony_ci	struct Qdisc *qdisc = rtnl_dereference(dev_queue->qdisc_sleeping);
113762306a36Sopenharmony_ci	struct Qdisc *qdisc_default = _qdisc_default;
113862306a36Sopenharmony_ci
113962306a36Sopenharmony_ci	if (qdisc) {
114062306a36Sopenharmony_ci		rcu_assign_pointer(dev_queue->qdisc, qdisc_default);
114162306a36Sopenharmony_ci		rcu_assign_pointer(dev_queue->qdisc_sleeping, qdisc_default);
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_ci		qdisc_put(qdisc);
114462306a36Sopenharmony_ci	}
114562306a36Sopenharmony_ci}
114662306a36Sopenharmony_ci
114762306a36Sopenharmony_cistatic void attach_one_default_qdisc(struct net_device *dev,
114862306a36Sopenharmony_ci				     struct netdev_queue *dev_queue,
114962306a36Sopenharmony_ci				     void *_unused)
115062306a36Sopenharmony_ci{
115162306a36Sopenharmony_ci	struct Qdisc *qdisc;
115262306a36Sopenharmony_ci	const struct Qdisc_ops *ops = default_qdisc_ops;
115362306a36Sopenharmony_ci
115462306a36Sopenharmony_ci	if (dev->priv_flags & IFF_NO_QUEUE)
115562306a36Sopenharmony_ci		ops = &noqueue_qdisc_ops;
115662306a36Sopenharmony_ci	else if(dev->type == ARPHRD_CAN)
115762306a36Sopenharmony_ci		ops = &pfifo_fast_ops;
115862306a36Sopenharmony_ci
115962306a36Sopenharmony_ci	qdisc = qdisc_create_dflt(dev_queue, ops, TC_H_ROOT, NULL);
116062306a36Sopenharmony_ci	if (!qdisc)
116162306a36Sopenharmony_ci		return;
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_ci	if (!netif_is_multiqueue(dev))
116462306a36Sopenharmony_ci		qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
116562306a36Sopenharmony_ci	rcu_assign_pointer(dev_queue->qdisc_sleeping, qdisc);
116662306a36Sopenharmony_ci}
116762306a36Sopenharmony_ci
116862306a36Sopenharmony_cistatic void attach_default_qdiscs(struct net_device *dev)
116962306a36Sopenharmony_ci{
117062306a36Sopenharmony_ci	struct netdev_queue *txq;
117162306a36Sopenharmony_ci	struct Qdisc *qdisc;
117262306a36Sopenharmony_ci
117362306a36Sopenharmony_ci	txq = netdev_get_tx_queue(dev, 0);
117462306a36Sopenharmony_ci
117562306a36Sopenharmony_ci	if (!netif_is_multiqueue(dev) ||
117662306a36Sopenharmony_ci	    dev->priv_flags & IFF_NO_QUEUE) {
117762306a36Sopenharmony_ci		netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
117862306a36Sopenharmony_ci		qdisc = rtnl_dereference(txq->qdisc_sleeping);
117962306a36Sopenharmony_ci		rcu_assign_pointer(dev->qdisc, qdisc);
118062306a36Sopenharmony_ci		qdisc_refcount_inc(qdisc);
118162306a36Sopenharmony_ci	} else {
118262306a36Sopenharmony_ci		qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT, NULL);
118362306a36Sopenharmony_ci		if (qdisc) {
118462306a36Sopenharmony_ci			rcu_assign_pointer(dev->qdisc, qdisc);
118562306a36Sopenharmony_ci			qdisc->ops->attach(qdisc);
118662306a36Sopenharmony_ci		}
118762306a36Sopenharmony_ci	}
118862306a36Sopenharmony_ci	qdisc = rtnl_dereference(dev->qdisc);
118962306a36Sopenharmony_ci
119062306a36Sopenharmony_ci	/* Detect default qdisc setup/init failed and fallback to "noqueue" */
119162306a36Sopenharmony_ci	if (qdisc == &noop_qdisc) {
119262306a36Sopenharmony_ci		netdev_warn(dev, "default qdisc (%s) fail, fallback to %s\n",
119362306a36Sopenharmony_ci			    default_qdisc_ops->id, noqueue_qdisc_ops.id);
119462306a36Sopenharmony_ci		netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc);
119562306a36Sopenharmony_ci		dev->priv_flags |= IFF_NO_QUEUE;
119662306a36Sopenharmony_ci		netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
119762306a36Sopenharmony_ci		qdisc = rtnl_dereference(txq->qdisc_sleeping);
119862306a36Sopenharmony_ci		rcu_assign_pointer(dev->qdisc, qdisc);
119962306a36Sopenharmony_ci		qdisc_refcount_inc(qdisc);
120062306a36Sopenharmony_ci		dev->priv_flags ^= IFF_NO_QUEUE;
120162306a36Sopenharmony_ci	}
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci#ifdef CONFIG_NET_SCHED
120462306a36Sopenharmony_ci	if (qdisc != &noop_qdisc)
120562306a36Sopenharmony_ci		qdisc_hash_add(qdisc, false);
120662306a36Sopenharmony_ci#endif
120762306a36Sopenharmony_ci}
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_cistatic void transition_one_qdisc(struct net_device *dev,
121062306a36Sopenharmony_ci				 struct netdev_queue *dev_queue,
121162306a36Sopenharmony_ci				 void *_need_watchdog)
121262306a36Sopenharmony_ci{
121362306a36Sopenharmony_ci	struct Qdisc *new_qdisc = rtnl_dereference(dev_queue->qdisc_sleeping);
121462306a36Sopenharmony_ci	int *need_watchdog_p = _need_watchdog;
121562306a36Sopenharmony_ci
121662306a36Sopenharmony_ci	if (!(new_qdisc->flags & TCQ_F_BUILTIN))
121762306a36Sopenharmony_ci		clear_bit(__QDISC_STATE_DEACTIVATED, &new_qdisc->state);
121862306a36Sopenharmony_ci
121962306a36Sopenharmony_ci	rcu_assign_pointer(dev_queue->qdisc, new_qdisc);
122062306a36Sopenharmony_ci	if (need_watchdog_p) {
122162306a36Sopenharmony_ci		WRITE_ONCE(dev_queue->trans_start, 0);
122262306a36Sopenharmony_ci		*need_watchdog_p = 1;
122362306a36Sopenharmony_ci	}
122462306a36Sopenharmony_ci}
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_civoid dev_activate(struct net_device *dev)
122762306a36Sopenharmony_ci{
122862306a36Sopenharmony_ci	int need_watchdog;
122962306a36Sopenharmony_ci
123062306a36Sopenharmony_ci	/* No queueing discipline is attached to device;
123162306a36Sopenharmony_ci	 * create default one for devices, which need queueing
123262306a36Sopenharmony_ci	 * and noqueue_qdisc for virtual interfaces
123362306a36Sopenharmony_ci	 */
123462306a36Sopenharmony_ci
123562306a36Sopenharmony_ci	if (rtnl_dereference(dev->qdisc) == &noop_qdisc)
123662306a36Sopenharmony_ci		attach_default_qdiscs(dev);
123762306a36Sopenharmony_ci
123862306a36Sopenharmony_ci	if (!netif_carrier_ok(dev))
123962306a36Sopenharmony_ci		/* Delay activation until next carrier-on event */
124062306a36Sopenharmony_ci		return;
124162306a36Sopenharmony_ci
124262306a36Sopenharmony_ci	need_watchdog = 0;
124362306a36Sopenharmony_ci	netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog);
124462306a36Sopenharmony_ci	if (dev_ingress_queue(dev))
124562306a36Sopenharmony_ci		transition_one_qdisc(dev, dev_ingress_queue(dev), NULL);
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci	if (need_watchdog) {
124862306a36Sopenharmony_ci		netif_trans_update(dev);
124962306a36Sopenharmony_ci		dev_watchdog_up(dev);
125062306a36Sopenharmony_ci	}
125162306a36Sopenharmony_ci}
125262306a36Sopenharmony_ciEXPORT_SYMBOL(dev_activate);
125362306a36Sopenharmony_ci
125462306a36Sopenharmony_cistatic void qdisc_deactivate(struct Qdisc *qdisc)
125562306a36Sopenharmony_ci{
125662306a36Sopenharmony_ci	if (qdisc->flags & TCQ_F_BUILTIN)
125762306a36Sopenharmony_ci		return;
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci	set_bit(__QDISC_STATE_DEACTIVATED, &qdisc->state);
126062306a36Sopenharmony_ci}
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_cistatic void dev_deactivate_queue(struct net_device *dev,
126362306a36Sopenharmony_ci				 struct netdev_queue *dev_queue,
126462306a36Sopenharmony_ci				 void *_qdisc_default)
126562306a36Sopenharmony_ci{
126662306a36Sopenharmony_ci	struct Qdisc *qdisc_default = _qdisc_default;
126762306a36Sopenharmony_ci	struct Qdisc *qdisc;
126862306a36Sopenharmony_ci
126962306a36Sopenharmony_ci	qdisc = rtnl_dereference(dev_queue->qdisc);
127062306a36Sopenharmony_ci	if (qdisc) {
127162306a36Sopenharmony_ci		qdisc_deactivate(qdisc);
127262306a36Sopenharmony_ci		rcu_assign_pointer(dev_queue->qdisc, qdisc_default);
127362306a36Sopenharmony_ci	}
127462306a36Sopenharmony_ci}
127562306a36Sopenharmony_ci
127662306a36Sopenharmony_cistatic void dev_reset_queue(struct net_device *dev,
127762306a36Sopenharmony_ci			    struct netdev_queue *dev_queue,
127862306a36Sopenharmony_ci			    void *_unused)
127962306a36Sopenharmony_ci{
128062306a36Sopenharmony_ci	struct Qdisc *qdisc;
128162306a36Sopenharmony_ci	bool nolock;
128262306a36Sopenharmony_ci
128362306a36Sopenharmony_ci	qdisc = rtnl_dereference(dev_queue->qdisc_sleeping);
128462306a36Sopenharmony_ci	if (!qdisc)
128562306a36Sopenharmony_ci		return;
128662306a36Sopenharmony_ci
128762306a36Sopenharmony_ci	nolock = qdisc->flags & TCQ_F_NOLOCK;
128862306a36Sopenharmony_ci
128962306a36Sopenharmony_ci	if (nolock)
129062306a36Sopenharmony_ci		spin_lock_bh(&qdisc->seqlock);
129162306a36Sopenharmony_ci	spin_lock_bh(qdisc_lock(qdisc));
129262306a36Sopenharmony_ci
129362306a36Sopenharmony_ci	qdisc_reset(qdisc);
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci	spin_unlock_bh(qdisc_lock(qdisc));
129662306a36Sopenharmony_ci	if (nolock) {
129762306a36Sopenharmony_ci		clear_bit(__QDISC_STATE_MISSED, &qdisc->state);
129862306a36Sopenharmony_ci		clear_bit(__QDISC_STATE_DRAINING, &qdisc->state);
129962306a36Sopenharmony_ci		spin_unlock_bh(&qdisc->seqlock);
130062306a36Sopenharmony_ci	}
130162306a36Sopenharmony_ci}
130262306a36Sopenharmony_ci
130362306a36Sopenharmony_cistatic bool some_qdisc_is_busy(struct net_device *dev)
130462306a36Sopenharmony_ci{
130562306a36Sopenharmony_ci	unsigned int i;
130662306a36Sopenharmony_ci
130762306a36Sopenharmony_ci	for (i = 0; i < dev->num_tx_queues; i++) {
130862306a36Sopenharmony_ci		struct netdev_queue *dev_queue;
130962306a36Sopenharmony_ci		spinlock_t *root_lock;
131062306a36Sopenharmony_ci		struct Qdisc *q;
131162306a36Sopenharmony_ci		int val;
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci		dev_queue = netdev_get_tx_queue(dev, i);
131462306a36Sopenharmony_ci		q = rtnl_dereference(dev_queue->qdisc_sleeping);
131562306a36Sopenharmony_ci
131662306a36Sopenharmony_ci		root_lock = qdisc_lock(q);
131762306a36Sopenharmony_ci		spin_lock_bh(root_lock);
131862306a36Sopenharmony_ci
131962306a36Sopenharmony_ci		val = (qdisc_is_running(q) ||
132062306a36Sopenharmony_ci		       test_bit(__QDISC_STATE_SCHED, &q->state));
132162306a36Sopenharmony_ci
132262306a36Sopenharmony_ci		spin_unlock_bh(root_lock);
132362306a36Sopenharmony_ci
132462306a36Sopenharmony_ci		if (val)
132562306a36Sopenharmony_ci			return true;
132662306a36Sopenharmony_ci	}
132762306a36Sopenharmony_ci	return false;
132862306a36Sopenharmony_ci}
132962306a36Sopenharmony_ci
133062306a36Sopenharmony_ci/**
133162306a36Sopenharmony_ci * 	dev_deactivate_many - deactivate transmissions on several devices
133262306a36Sopenharmony_ci * 	@head: list of devices to deactivate
133362306a36Sopenharmony_ci *
133462306a36Sopenharmony_ci *	This function returns only when all outstanding transmissions
133562306a36Sopenharmony_ci *	have completed, unless all devices are in dismantle phase.
133662306a36Sopenharmony_ci */
133762306a36Sopenharmony_civoid dev_deactivate_many(struct list_head *head)
133862306a36Sopenharmony_ci{
133962306a36Sopenharmony_ci	struct net_device *dev;
134062306a36Sopenharmony_ci
134162306a36Sopenharmony_ci	list_for_each_entry(dev, head, close_list) {
134262306a36Sopenharmony_ci		netdev_for_each_tx_queue(dev, dev_deactivate_queue,
134362306a36Sopenharmony_ci					 &noop_qdisc);
134462306a36Sopenharmony_ci		if (dev_ingress_queue(dev))
134562306a36Sopenharmony_ci			dev_deactivate_queue(dev, dev_ingress_queue(dev),
134662306a36Sopenharmony_ci					     &noop_qdisc);
134762306a36Sopenharmony_ci
134862306a36Sopenharmony_ci		dev_watchdog_down(dev);
134962306a36Sopenharmony_ci	}
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	/* Wait for outstanding qdisc-less dev_queue_xmit calls or
135262306a36Sopenharmony_ci	 * outstanding qdisc enqueuing calls.
135362306a36Sopenharmony_ci	 * This is avoided if all devices are in dismantle phase :
135462306a36Sopenharmony_ci	 * Caller will call synchronize_net() for us
135562306a36Sopenharmony_ci	 */
135662306a36Sopenharmony_ci	synchronize_net();
135762306a36Sopenharmony_ci
135862306a36Sopenharmony_ci	list_for_each_entry(dev, head, close_list) {
135962306a36Sopenharmony_ci		netdev_for_each_tx_queue(dev, dev_reset_queue, NULL);
136062306a36Sopenharmony_ci
136162306a36Sopenharmony_ci		if (dev_ingress_queue(dev))
136262306a36Sopenharmony_ci			dev_reset_queue(dev, dev_ingress_queue(dev), NULL);
136362306a36Sopenharmony_ci	}
136462306a36Sopenharmony_ci
136562306a36Sopenharmony_ci	/* Wait for outstanding qdisc_run calls. */
136662306a36Sopenharmony_ci	list_for_each_entry(dev, head, close_list) {
136762306a36Sopenharmony_ci		while (some_qdisc_is_busy(dev)) {
136862306a36Sopenharmony_ci			/* wait_event() would avoid this sleep-loop but would
136962306a36Sopenharmony_ci			 * require expensive checks in the fast paths of packet
137062306a36Sopenharmony_ci			 * processing which isn't worth it.
137162306a36Sopenharmony_ci			 */
137262306a36Sopenharmony_ci			schedule_timeout_uninterruptible(1);
137362306a36Sopenharmony_ci		}
137462306a36Sopenharmony_ci	}
137562306a36Sopenharmony_ci}
137662306a36Sopenharmony_ci
137762306a36Sopenharmony_civoid dev_deactivate(struct net_device *dev)
137862306a36Sopenharmony_ci{
137962306a36Sopenharmony_ci	LIST_HEAD(single);
138062306a36Sopenharmony_ci
138162306a36Sopenharmony_ci	list_add(&dev->close_list, &single);
138262306a36Sopenharmony_ci	dev_deactivate_many(&single);
138362306a36Sopenharmony_ci	list_del(&single);
138462306a36Sopenharmony_ci}
138562306a36Sopenharmony_ciEXPORT_SYMBOL(dev_deactivate);
138662306a36Sopenharmony_ci
138762306a36Sopenharmony_cistatic int qdisc_change_tx_queue_len(struct net_device *dev,
138862306a36Sopenharmony_ci				     struct netdev_queue *dev_queue)
138962306a36Sopenharmony_ci{
139062306a36Sopenharmony_ci	struct Qdisc *qdisc = rtnl_dereference(dev_queue->qdisc_sleeping);
139162306a36Sopenharmony_ci	const struct Qdisc_ops *ops = qdisc->ops;
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_ci	if (ops->change_tx_queue_len)
139462306a36Sopenharmony_ci		return ops->change_tx_queue_len(qdisc, dev->tx_queue_len);
139562306a36Sopenharmony_ci	return 0;
139662306a36Sopenharmony_ci}
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_civoid dev_qdisc_change_real_num_tx(struct net_device *dev,
139962306a36Sopenharmony_ci				  unsigned int new_real_tx)
140062306a36Sopenharmony_ci{
140162306a36Sopenharmony_ci	struct Qdisc *qdisc = rtnl_dereference(dev->qdisc);
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci	if (qdisc->ops->change_real_num_tx)
140462306a36Sopenharmony_ci		qdisc->ops->change_real_num_tx(qdisc, new_real_tx);
140562306a36Sopenharmony_ci}
140662306a36Sopenharmony_ci
140762306a36Sopenharmony_civoid mq_change_real_num_tx(struct Qdisc *sch, unsigned int new_real_tx)
140862306a36Sopenharmony_ci{
140962306a36Sopenharmony_ci#ifdef CONFIG_NET_SCHED
141062306a36Sopenharmony_ci	struct net_device *dev = qdisc_dev(sch);
141162306a36Sopenharmony_ci	struct Qdisc *qdisc;
141262306a36Sopenharmony_ci	unsigned int i;
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_ci	for (i = new_real_tx; i < dev->real_num_tx_queues; i++) {
141562306a36Sopenharmony_ci		qdisc = rtnl_dereference(netdev_get_tx_queue(dev, i)->qdisc_sleeping);
141662306a36Sopenharmony_ci		/* Only update the default qdiscs we created,
141762306a36Sopenharmony_ci		 * qdiscs with handles are always hashed.
141862306a36Sopenharmony_ci		 */
141962306a36Sopenharmony_ci		if (qdisc != &noop_qdisc && !qdisc->handle)
142062306a36Sopenharmony_ci			qdisc_hash_del(qdisc);
142162306a36Sopenharmony_ci	}
142262306a36Sopenharmony_ci	for (i = dev->real_num_tx_queues; i < new_real_tx; i++) {
142362306a36Sopenharmony_ci		qdisc = rtnl_dereference(netdev_get_tx_queue(dev, i)->qdisc_sleeping);
142462306a36Sopenharmony_ci		if (qdisc != &noop_qdisc && !qdisc->handle)
142562306a36Sopenharmony_ci			qdisc_hash_add(qdisc, false);
142662306a36Sopenharmony_ci	}
142762306a36Sopenharmony_ci#endif
142862306a36Sopenharmony_ci}
142962306a36Sopenharmony_ciEXPORT_SYMBOL(mq_change_real_num_tx);
143062306a36Sopenharmony_ci
143162306a36Sopenharmony_ciint dev_qdisc_change_tx_queue_len(struct net_device *dev)
143262306a36Sopenharmony_ci{
143362306a36Sopenharmony_ci	bool up = dev->flags & IFF_UP;
143462306a36Sopenharmony_ci	unsigned int i;
143562306a36Sopenharmony_ci	int ret = 0;
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci	if (up)
143862306a36Sopenharmony_ci		dev_deactivate(dev);
143962306a36Sopenharmony_ci
144062306a36Sopenharmony_ci	for (i = 0; i < dev->num_tx_queues; i++) {
144162306a36Sopenharmony_ci		ret = qdisc_change_tx_queue_len(dev, &dev->_tx[i]);
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_ci		/* TODO: revert changes on a partial failure */
144462306a36Sopenharmony_ci		if (ret)
144562306a36Sopenharmony_ci			break;
144662306a36Sopenharmony_ci	}
144762306a36Sopenharmony_ci
144862306a36Sopenharmony_ci	if (up)
144962306a36Sopenharmony_ci		dev_activate(dev);
145062306a36Sopenharmony_ci	return ret;
145162306a36Sopenharmony_ci}
145262306a36Sopenharmony_ci
145362306a36Sopenharmony_cistatic void dev_init_scheduler_queue(struct net_device *dev,
145462306a36Sopenharmony_ci				     struct netdev_queue *dev_queue,
145562306a36Sopenharmony_ci				     void *_qdisc)
145662306a36Sopenharmony_ci{
145762306a36Sopenharmony_ci	struct Qdisc *qdisc = _qdisc;
145862306a36Sopenharmony_ci
145962306a36Sopenharmony_ci	rcu_assign_pointer(dev_queue->qdisc, qdisc);
146062306a36Sopenharmony_ci	rcu_assign_pointer(dev_queue->qdisc_sleeping, qdisc);
146162306a36Sopenharmony_ci}
146262306a36Sopenharmony_ci
146362306a36Sopenharmony_civoid dev_init_scheduler(struct net_device *dev)
146462306a36Sopenharmony_ci{
146562306a36Sopenharmony_ci	rcu_assign_pointer(dev->qdisc, &noop_qdisc);
146662306a36Sopenharmony_ci	netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc);
146762306a36Sopenharmony_ci	if (dev_ingress_queue(dev))
146862306a36Sopenharmony_ci		dev_init_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc);
146962306a36Sopenharmony_ci
147062306a36Sopenharmony_ci	timer_setup(&dev->watchdog_timer, dev_watchdog, 0);
147162306a36Sopenharmony_ci}
147262306a36Sopenharmony_ci
147362306a36Sopenharmony_civoid dev_shutdown(struct net_device *dev)
147462306a36Sopenharmony_ci{
147562306a36Sopenharmony_ci	netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc);
147662306a36Sopenharmony_ci	if (dev_ingress_queue(dev))
147762306a36Sopenharmony_ci		shutdown_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc);
147862306a36Sopenharmony_ci	qdisc_put(rtnl_dereference(dev->qdisc));
147962306a36Sopenharmony_ci	rcu_assign_pointer(dev->qdisc, &noop_qdisc);
148062306a36Sopenharmony_ci
148162306a36Sopenharmony_ci	WARN_ON(timer_pending(&dev->watchdog_timer));
148262306a36Sopenharmony_ci}
148362306a36Sopenharmony_ci
148462306a36Sopenharmony_ci/**
148562306a36Sopenharmony_ci * psched_ratecfg_precompute__() - Pre-compute values for reciprocal division
148662306a36Sopenharmony_ci * @rate:   Rate to compute reciprocal division values of
148762306a36Sopenharmony_ci * @mult:   Multiplier for reciprocal division
148862306a36Sopenharmony_ci * @shift:  Shift for reciprocal division
148962306a36Sopenharmony_ci *
149062306a36Sopenharmony_ci * The multiplier and shift for reciprocal division by rate are stored
149162306a36Sopenharmony_ci * in mult and shift.
149262306a36Sopenharmony_ci *
149362306a36Sopenharmony_ci * The deal here is to replace a divide by a reciprocal one
149462306a36Sopenharmony_ci * in fast path (a reciprocal divide is a multiply and a shift)
149562306a36Sopenharmony_ci *
149662306a36Sopenharmony_ci * Normal formula would be :
149762306a36Sopenharmony_ci *  time_in_ns = (NSEC_PER_SEC * len) / rate_bps
149862306a36Sopenharmony_ci *
149962306a36Sopenharmony_ci * We compute mult/shift to use instead :
150062306a36Sopenharmony_ci *  time_in_ns = (len * mult) >> shift;
150162306a36Sopenharmony_ci *
150262306a36Sopenharmony_ci * We try to get the highest possible mult value for accuracy,
150362306a36Sopenharmony_ci * but have to make sure no overflows will ever happen.
150462306a36Sopenharmony_ci *
150562306a36Sopenharmony_ci * reciprocal_value() is not used here it doesn't handle 64-bit values.
150662306a36Sopenharmony_ci */
150762306a36Sopenharmony_cistatic void psched_ratecfg_precompute__(u64 rate, u32 *mult, u8 *shift)
150862306a36Sopenharmony_ci{
150962306a36Sopenharmony_ci	u64 factor = NSEC_PER_SEC;
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_ci	*mult = 1;
151262306a36Sopenharmony_ci	*shift = 0;
151362306a36Sopenharmony_ci
151462306a36Sopenharmony_ci	if (rate <= 0)
151562306a36Sopenharmony_ci		return;
151662306a36Sopenharmony_ci
151762306a36Sopenharmony_ci	for (;;) {
151862306a36Sopenharmony_ci		*mult = div64_u64(factor, rate);
151962306a36Sopenharmony_ci		if (*mult & (1U << 31) || factor & (1ULL << 63))
152062306a36Sopenharmony_ci			break;
152162306a36Sopenharmony_ci		factor <<= 1;
152262306a36Sopenharmony_ci		(*shift)++;
152362306a36Sopenharmony_ci	}
152462306a36Sopenharmony_ci}
152562306a36Sopenharmony_ci
152662306a36Sopenharmony_civoid psched_ratecfg_precompute(struct psched_ratecfg *r,
152762306a36Sopenharmony_ci			       const struct tc_ratespec *conf,
152862306a36Sopenharmony_ci			       u64 rate64)
152962306a36Sopenharmony_ci{
153062306a36Sopenharmony_ci	memset(r, 0, sizeof(*r));
153162306a36Sopenharmony_ci	r->overhead = conf->overhead;
153262306a36Sopenharmony_ci	r->mpu = conf->mpu;
153362306a36Sopenharmony_ci	r->rate_bytes_ps = max_t(u64, conf->rate, rate64);
153462306a36Sopenharmony_ci	r->linklayer = (conf->linklayer & TC_LINKLAYER_MASK);
153562306a36Sopenharmony_ci	psched_ratecfg_precompute__(r->rate_bytes_ps, &r->mult, &r->shift);
153662306a36Sopenharmony_ci}
153762306a36Sopenharmony_ciEXPORT_SYMBOL(psched_ratecfg_precompute);
153862306a36Sopenharmony_ci
153962306a36Sopenharmony_civoid psched_ppscfg_precompute(struct psched_pktrate *r, u64 pktrate64)
154062306a36Sopenharmony_ci{
154162306a36Sopenharmony_ci	r->rate_pkts_ps = pktrate64;
154262306a36Sopenharmony_ci	psched_ratecfg_precompute__(r->rate_pkts_ps, &r->mult, &r->shift);
154362306a36Sopenharmony_ci}
154462306a36Sopenharmony_ciEXPORT_SYMBOL(psched_ppscfg_precompute);
154562306a36Sopenharmony_ci
154662306a36Sopenharmony_civoid mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp,
154762306a36Sopenharmony_ci			  struct tcf_proto *tp_head)
154862306a36Sopenharmony_ci{
154962306a36Sopenharmony_ci	/* Protected with chain0->filter_chain_lock.
155062306a36Sopenharmony_ci	 * Can't access chain directly because tp_head can be NULL.
155162306a36Sopenharmony_ci	 */
155262306a36Sopenharmony_ci	struct mini_Qdisc *miniq_old =
155362306a36Sopenharmony_ci		rcu_dereference_protected(*miniqp->p_miniq, 1);
155462306a36Sopenharmony_ci	struct mini_Qdisc *miniq;
155562306a36Sopenharmony_ci
155662306a36Sopenharmony_ci	if (!tp_head) {
155762306a36Sopenharmony_ci		RCU_INIT_POINTER(*miniqp->p_miniq, NULL);
155862306a36Sopenharmony_ci	} else {
155962306a36Sopenharmony_ci		miniq = miniq_old != &miniqp->miniq1 ?
156062306a36Sopenharmony_ci			&miniqp->miniq1 : &miniqp->miniq2;
156162306a36Sopenharmony_ci
156262306a36Sopenharmony_ci		/* We need to make sure that readers won't see the miniq
156362306a36Sopenharmony_ci		 * we are about to modify. So ensure that at least one RCU
156462306a36Sopenharmony_ci		 * grace period has elapsed since the miniq was made
156562306a36Sopenharmony_ci		 * inactive.
156662306a36Sopenharmony_ci		 */
156762306a36Sopenharmony_ci		if (IS_ENABLED(CONFIG_PREEMPT_RT))
156862306a36Sopenharmony_ci			cond_synchronize_rcu(miniq->rcu_state);
156962306a36Sopenharmony_ci		else if (!poll_state_synchronize_rcu(miniq->rcu_state))
157062306a36Sopenharmony_ci			synchronize_rcu_expedited();
157162306a36Sopenharmony_ci
157262306a36Sopenharmony_ci		miniq->filter_list = tp_head;
157362306a36Sopenharmony_ci		rcu_assign_pointer(*miniqp->p_miniq, miniq);
157462306a36Sopenharmony_ci	}
157562306a36Sopenharmony_ci
157662306a36Sopenharmony_ci	if (miniq_old)
157762306a36Sopenharmony_ci		/* This is counterpart of the rcu sync above. We need to
157862306a36Sopenharmony_ci		 * block potential new user of miniq_old until all readers
157962306a36Sopenharmony_ci		 * are not seeing it.
158062306a36Sopenharmony_ci		 */
158162306a36Sopenharmony_ci		miniq_old->rcu_state = start_poll_synchronize_rcu();
158262306a36Sopenharmony_ci}
158362306a36Sopenharmony_ciEXPORT_SYMBOL(mini_qdisc_pair_swap);
158462306a36Sopenharmony_ci
158562306a36Sopenharmony_civoid mini_qdisc_pair_block_init(struct mini_Qdisc_pair *miniqp,
158662306a36Sopenharmony_ci				struct tcf_block *block)
158762306a36Sopenharmony_ci{
158862306a36Sopenharmony_ci	miniqp->miniq1.block = block;
158962306a36Sopenharmony_ci	miniqp->miniq2.block = block;
159062306a36Sopenharmony_ci}
159162306a36Sopenharmony_ciEXPORT_SYMBOL(mini_qdisc_pair_block_init);
159262306a36Sopenharmony_ci
159362306a36Sopenharmony_civoid mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc,
159462306a36Sopenharmony_ci			  struct mini_Qdisc __rcu **p_miniq)
159562306a36Sopenharmony_ci{
159662306a36Sopenharmony_ci	miniqp->miniq1.cpu_bstats = qdisc->cpu_bstats;
159762306a36Sopenharmony_ci	miniqp->miniq1.cpu_qstats = qdisc->cpu_qstats;
159862306a36Sopenharmony_ci	miniqp->miniq2.cpu_bstats = qdisc->cpu_bstats;
159962306a36Sopenharmony_ci	miniqp->miniq2.cpu_qstats = qdisc->cpu_qstats;
160062306a36Sopenharmony_ci	miniqp->miniq1.rcu_state = get_state_synchronize_rcu();
160162306a36Sopenharmony_ci	miniqp->miniq2.rcu_state = miniqp->miniq1.rcu_state;
160262306a36Sopenharmony_ci	miniqp->p_miniq = p_miniq;
160362306a36Sopenharmony_ci}
160462306a36Sopenharmony_ciEXPORT_SYMBOL(mini_qdisc_pair_init);
1605