cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sch_generic.h (33965B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef __NET_SCHED_GENERIC_H
      3#define __NET_SCHED_GENERIC_H
      4
      5#include <linux/netdevice.h>
      6#include <linux/types.h>
      7#include <linux/rcupdate.h>
      8#include <linux/pkt_sched.h>
      9#include <linux/pkt_cls.h>
     10#include <linux/percpu.h>
     11#include <linux/dynamic_queue_limits.h>
     12#include <linux/list.h>
     13#include <linux/refcount.h>
     14#include <linux/workqueue.h>
     15#include <linux/mutex.h>
     16#include <linux/rwsem.h>
     17#include <linux/atomic.h>
     18#include <linux/hashtable.h>
     19#include <net/gen_stats.h>
     20#include <net/rtnetlink.h>
     21#include <net/flow_offload.h>
     22
     23struct Qdisc_ops;
     24struct qdisc_walker;
     25struct tcf_walker;
     26struct module;
     27struct bpf_flow_keys;
     28
     29struct qdisc_rate_table {
     30	struct tc_ratespec rate;
     31	u32		data[256];
     32	struct qdisc_rate_table *next;
     33	int		refcnt;
     34};
     35
     36enum qdisc_state_t {
     37	__QDISC_STATE_SCHED,
     38	__QDISC_STATE_DEACTIVATED,
     39	__QDISC_STATE_MISSED,
     40	__QDISC_STATE_DRAINING,
     41};
     42
     43enum qdisc_state2_t {
     44	/* Only for !TCQ_F_NOLOCK qdisc. Never access it directly.
     45	 * Use qdisc_run_begin/end() or qdisc_is_running() instead.
     46	 */
     47	__QDISC_STATE2_RUNNING,
     48};
     49
     50#define QDISC_STATE_MISSED	BIT(__QDISC_STATE_MISSED)
     51#define QDISC_STATE_DRAINING	BIT(__QDISC_STATE_DRAINING)
     52
     53#define QDISC_STATE_NON_EMPTY	(QDISC_STATE_MISSED | \
     54					QDISC_STATE_DRAINING)
     55
     56struct qdisc_size_table {
     57	struct rcu_head		rcu;
     58	struct list_head	list;
     59	struct tc_sizespec	szopts;
     60	int			refcnt;
     61	u16			data[];
     62};
     63
     64/* similar to sk_buff_head, but skb->prev pointer is undefined. */
     65struct qdisc_skb_head {
     66	struct sk_buff	*head;
     67	struct sk_buff	*tail;
     68	__u32		qlen;
     69	spinlock_t	lock;
     70};
     71
     72struct Qdisc {
     73	int 			(*enqueue)(struct sk_buff *skb,
     74					   struct Qdisc *sch,
     75					   struct sk_buff **to_free);
     76	struct sk_buff *	(*dequeue)(struct Qdisc *sch);
     77	unsigned int		flags;
     78#define TCQ_F_BUILTIN		1
     79#define TCQ_F_INGRESS		2
     80#define TCQ_F_CAN_BYPASS	4
     81#define TCQ_F_MQROOT		8
     82#define TCQ_F_ONETXQUEUE	0x10 /* dequeue_skb() can assume all skbs are for
     83				      * q->dev_queue : It can test
     84				      * netif_xmit_frozen_or_stopped() before
     85				      * dequeueing next packet.
     86				      * Its true for MQ/MQPRIO slaves, or non
     87				      * multiqueue device.
     88				      */
     89#define TCQ_F_WARN_NONWC	(1 << 16)
     90#define TCQ_F_CPUSTATS		0x20 /* run using percpu statistics */
     91#define TCQ_F_NOPARENT		0x40 /* root of its hierarchy :
     92				      * qdisc_tree_decrease_qlen() should stop.
     93				      */
     94#define TCQ_F_INVISIBLE		0x80 /* invisible by default in dump */
     95#define TCQ_F_NOLOCK		0x100 /* qdisc does not require locking */
     96#define TCQ_F_OFFLOADED		0x200 /* qdisc is offloaded to HW */
     97	u32			limit;
     98	const struct Qdisc_ops	*ops;
     99	struct qdisc_size_table	__rcu *stab;
    100	struct hlist_node       hash;
    101	u32			handle;
    102	u32			parent;
    103
    104	struct netdev_queue	*dev_queue;
    105
    106	struct net_rate_estimator __rcu *rate_est;
    107	struct gnet_stats_basic_sync __percpu *cpu_bstats;
    108	struct gnet_stats_queue	__percpu *cpu_qstats;
    109	int			pad;
    110	refcount_t		refcnt;
    111
    112	/*
    113	 * For performance sake on SMP, we put highly modified fields at the end
    114	 */
    115	struct sk_buff_head	gso_skb ____cacheline_aligned_in_smp;
    116	struct qdisc_skb_head	q;
    117	struct gnet_stats_basic_sync bstats;
    118	struct gnet_stats_queue	qstats;
    119	unsigned long		state;
    120	unsigned long		state2; /* must be written under qdisc spinlock */
    121	struct Qdisc            *next_sched;
    122	struct sk_buff_head	skb_bad_txq;
    123
    124	spinlock_t		busylock ____cacheline_aligned_in_smp;
    125	spinlock_t		seqlock;
    126
    127	struct rcu_head		rcu;
    128	netdevice_tracker	dev_tracker;
    129	/* private data */
    130	long privdata[] ____cacheline_aligned;
    131};
    132
    133static inline void qdisc_refcount_inc(struct Qdisc *qdisc)
    134{
    135	if (qdisc->flags & TCQ_F_BUILTIN)
    136		return;
    137	refcount_inc(&qdisc->refcnt);
    138}
    139
    140/* Intended to be used by unlocked users, when concurrent qdisc release is
    141 * possible.
    142 */
    143
    144static inline struct Qdisc *qdisc_refcount_inc_nz(struct Qdisc *qdisc)
    145{
    146	if (qdisc->flags & TCQ_F_BUILTIN)
    147		return qdisc;
    148	if (refcount_inc_not_zero(&qdisc->refcnt))
    149		return qdisc;
    150	return NULL;
    151}
    152
    153/* For !TCQ_F_NOLOCK qdisc: callers must either call this within a qdisc
    154 * root_lock section, or provide their own memory barriers -- ordering
    155 * against qdisc_run_begin/end() atomic bit operations.
    156 */
    157static inline bool qdisc_is_running(struct Qdisc *qdisc)
    158{
    159	if (qdisc->flags & TCQ_F_NOLOCK)
    160		return spin_is_locked(&qdisc->seqlock);
    161	return test_bit(__QDISC_STATE2_RUNNING, &qdisc->state2);
    162}
    163
    164static inline bool nolock_qdisc_is_empty(const struct Qdisc *qdisc)
    165{
    166	return !(READ_ONCE(qdisc->state) & QDISC_STATE_NON_EMPTY);
    167}
    168
    169static inline bool qdisc_is_percpu_stats(const struct Qdisc *q)
    170{
    171	return q->flags & TCQ_F_CPUSTATS;
    172}
    173
    174static inline bool qdisc_is_empty(const struct Qdisc *qdisc)
    175{
    176	if (qdisc_is_percpu_stats(qdisc))
    177		return nolock_qdisc_is_empty(qdisc);
    178	return !READ_ONCE(qdisc->q.qlen);
    179}
    180
    181/* For !TCQ_F_NOLOCK qdisc, qdisc_run_begin/end() must be invoked with
    182 * the qdisc root lock acquired.
    183 */
    184static inline bool qdisc_run_begin(struct Qdisc *qdisc)
    185{
    186	if (qdisc->flags & TCQ_F_NOLOCK) {
    187		if (spin_trylock(&qdisc->seqlock))
    188			return true;
    189
    190		/* No need to insist if the MISSED flag was already set.
    191		 * Note that test_and_set_bit() also gives us memory ordering
    192		 * guarantees wrt potential earlier enqueue() and below
    193		 * spin_trylock(), both of which are necessary to prevent races
    194		 */
    195		if (test_and_set_bit(__QDISC_STATE_MISSED, &qdisc->state))
    196			return false;
    197
    198		/* Try to take the lock again to make sure that we will either
    199		 * grab it or the CPU that still has it will see MISSED set
    200		 * when testing it in qdisc_run_end()
    201		 */
    202		return spin_trylock(&qdisc->seqlock);
    203	}
    204	return !__test_and_set_bit(__QDISC_STATE2_RUNNING, &qdisc->state2);
    205}
    206
    207static inline void qdisc_run_end(struct Qdisc *qdisc)
    208{
    209	if (qdisc->flags & TCQ_F_NOLOCK) {
    210		spin_unlock(&qdisc->seqlock);
    211
    212		/* spin_unlock() only has store-release semantic. The unlock
    213		 * and test_bit() ordering is a store-load ordering, so a full
    214		 * memory barrier is needed here.
    215		 */
    216		smp_mb();
    217
    218		if (unlikely(test_bit(__QDISC_STATE_MISSED,
    219				      &qdisc->state)))
    220			__netif_schedule(qdisc);
    221	} else {
    222		__clear_bit(__QDISC_STATE2_RUNNING, &qdisc->state2);
    223	}
    224}
    225
    226static inline bool qdisc_may_bulk(const struct Qdisc *qdisc)
    227{
    228	return qdisc->flags & TCQ_F_ONETXQUEUE;
    229}
    230
    231static inline int qdisc_avail_bulklimit(const struct netdev_queue *txq)
    232{
    233#ifdef CONFIG_BQL
    234	/* Non-BQL migrated drivers will return 0, too. */
    235	return dql_avail(&txq->dql);
    236#else
    237	return 0;
    238#endif
    239}
    240
    241struct Qdisc_class_ops {
    242	unsigned int		flags;
    243	/* Child qdisc manipulation */
    244	struct netdev_queue *	(*select_queue)(struct Qdisc *, struct tcmsg *);
    245	int			(*graft)(struct Qdisc *, unsigned long cl,
    246					struct Qdisc *, struct Qdisc **,
    247					struct netlink_ext_ack *extack);
    248	struct Qdisc *		(*leaf)(struct Qdisc *, unsigned long cl);
    249	void			(*qlen_notify)(struct Qdisc *, unsigned long);
    250
    251	/* Class manipulation routines */
    252	unsigned long		(*find)(struct Qdisc *, u32 classid);
    253	int			(*change)(struct Qdisc *, u32, u32,
    254					struct nlattr **, unsigned long *,
    255					struct netlink_ext_ack *);
    256	int			(*delete)(struct Qdisc *, unsigned long,
    257					  struct netlink_ext_ack *);
    258	void			(*walk)(struct Qdisc *, struct qdisc_walker * arg);
    259
    260	/* Filter manipulation */
    261	struct tcf_block *	(*tcf_block)(struct Qdisc *sch,
    262					     unsigned long arg,
    263					     struct netlink_ext_ack *extack);
    264	unsigned long		(*bind_tcf)(struct Qdisc *, unsigned long,
    265					u32 classid);
    266	void			(*unbind_tcf)(struct Qdisc *, unsigned long);
    267
    268	/* rtnetlink specific */
    269	int			(*dump)(struct Qdisc *, unsigned long,
    270					struct sk_buff *skb, struct tcmsg*);
    271	int			(*dump_stats)(struct Qdisc *, unsigned long,
    272					struct gnet_dump *);
    273};
    274
    275/* Qdisc_class_ops flag values */
    276
    277/* Implements API that doesn't require rtnl lock */
    278enum qdisc_class_ops_flags {
    279	QDISC_CLASS_OPS_DOIT_UNLOCKED = 1,
    280};
    281
    282struct Qdisc_ops {
    283	struct Qdisc_ops	*next;
    284	const struct Qdisc_class_ops	*cl_ops;
    285	char			id[IFNAMSIZ];
    286	int			priv_size;
    287	unsigned int		static_flags;
    288
    289	int 			(*enqueue)(struct sk_buff *skb,
    290					   struct Qdisc *sch,
    291					   struct sk_buff **to_free);
    292	struct sk_buff *	(*dequeue)(struct Qdisc *);
    293	struct sk_buff *	(*peek)(struct Qdisc *);
    294
    295	int			(*init)(struct Qdisc *sch, struct nlattr *arg,
    296					struct netlink_ext_ack *extack);
    297	void			(*reset)(struct Qdisc *);
    298	void			(*destroy)(struct Qdisc *);
    299	int			(*change)(struct Qdisc *sch,
    300					  struct nlattr *arg,
    301					  struct netlink_ext_ack *extack);
    302	void			(*attach)(struct Qdisc *sch);
    303	int			(*change_tx_queue_len)(struct Qdisc *, unsigned int);
    304	void			(*change_real_num_tx)(struct Qdisc *sch,
    305						      unsigned int new_real_tx);
    306
    307	int			(*dump)(struct Qdisc *, struct sk_buff *);
    308	int			(*dump_stats)(struct Qdisc *, struct gnet_dump *);
    309
    310	void			(*ingress_block_set)(struct Qdisc *sch,
    311						     u32 block_index);
    312	void			(*egress_block_set)(struct Qdisc *sch,
    313						    u32 block_index);
    314	u32			(*ingress_block_get)(struct Qdisc *sch);
    315	u32			(*egress_block_get)(struct Qdisc *sch);
    316
    317	struct module		*owner;
    318};
    319
    320
    321struct tcf_result {
    322	union {
    323		struct {
    324			unsigned long	class;
    325			u32		classid;
    326		};
    327		const struct tcf_proto *goto_tp;
    328
    329		/* used in the skb_tc_reinsert function */
    330		struct {
    331			bool		ingress;
    332			struct gnet_stats_queue *qstats;
    333		};
    334	};
    335};
    336
    337struct tcf_chain;
    338
    339struct tcf_proto_ops {
    340	struct list_head	head;
    341	char			kind[IFNAMSIZ];
    342
    343	int			(*classify)(struct sk_buff *,
    344					    const struct tcf_proto *,
    345					    struct tcf_result *);
    346	int			(*init)(struct tcf_proto*);
    347	void			(*destroy)(struct tcf_proto *tp, bool rtnl_held,
    348					   struct netlink_ext_ack *extack);
    349
    350	void*			(*get)(struct tcf_proto*, u32 handle);
    351	void			(*put)(struct tcf_proto *tp, void *f);
    352	int			(*change)(struct net *net, struct sk_buff *,
    353					struct tcf_proto*, unsigned long,
    354					u32 handle, struct nlattr **,
    355					void **, u32,
    356					struct netlink_ext_ack *);
    357	int			(*delete)(struct tcf_proto *tp, void *arg,
    358					  bool *last, bool rtnl_held,
    359					  struct netlink_ext_ack *);
    360	bool			(*delete_empty)(struct tcf_proto *tp);
    361	void			(*walk)(struct tcf_proto *tp,
    362					struct tcf_walker *arg, bool rtnl_held);
    363	int			(*reoffload)(struct tcf_proto *tp, bool add,
    364					     flow_setup_cb_t *cb, void *cb_priv,
    365					     struct netlink_ext_ack *extack);
    366	void			(*hw_add)(struct tcf_proto *tp,
    367					  void *type_data);
    368	void			(*hw_del)(struct tcf_proto *tp,
    369					  void *type_data);
    370	void			(*bind_class)(void *, u32, unsigned long,
    371					      void *, unsigned long);
    372	void *			(*tmplt_create)(struct net *net,
    373						struct tcf_chain *chain,
    374						struct nlattr **tca,
    375						struct netlink_ext_ack *extack);
    376	void			(*tmplt_destroy)(void *tmplt_priv);
    377
    378	/* rtnetlink specific */
    379	int			(*dump)(struct net*, struct tcf_proto*, void *,
    380					struct sk_buff *skb, struct tcmsg*,
    381					bool);
    382	int			(*terse_dump)(struct net *net,
    383					      struct tcf_proto *tp, void *fh,
    384					      struct sk_buff *skb,
    385					      struct tcmsg *t, bool rtnl_held);
    386	int			(*tmplt_dump)(struct sk_buff *skb,
    387					      struct net *net,
    388					      void *tmplt_priv);
    389
    390	struct module		*owner;
    391	int			flags;
    392};
    393
    394/* Classifiers setting TCF_PROTO_OPS_DOIT_UNLOCKED in tcf_proto_ops->flags
    395 * are expected to implement tcf_proto_ops->delete_empty(), otherwise race
    396 * conditions can occur when filters are inserted/deleted simultaneously.
    397 */
    398enum tcf_proto_ops_flags {
    399	TCF_PROTO_OPS_DOIT_UNLOCKED = 1,
    400};
    401
    402struct tcf_proto {
    403	/* Fast access part */
    404	struct tcf_proto __rcu	*next;
    405	void __rcu		*root;
    406
    407	/* called under RCU BH lock*/
    408	int			(*classify)(struct sk_buff *,
    409					    const struct tcf_proto *,
    410					    struct tcf_result *);
    411	__be16			protocol;
    412
    413	/* All the rest */
    414	u32			prio;
    415	void			*data;
    416	const struct tcf_proto_ops	*ops;
    417	struct tcf_chain	*chain;
    418	/* Lock protects tcf_proto shared state and can be used by unlocked
    419	 * classifiers to protect their private data.
    420	 */
    421	spinlock_t		lock;
    422	bool			deleting;
    423	refcount_t		refcnt;
    424	struct rcu_head		rcu;
    425	struct hlist_node	destroy_ht_node;
    426};
    427
    428struct qdisc_skb_cb {
    429	struct {
    430		unsigned int		pkt_len;
    431		u16			slave_dev_queue_mapping;
    432		u16			tc_classid;
    433	};
    434#define QDISC_CB_PRIV_LEN 20
    435	unsigned char		data[QDISC_CB_PRIV_LEN];
    436};
    437
    438typedef void tcf_chain_head_change_t(struct tcf_proto *tp_head, void *priv);
    439
    440struct tcf_chain {
    441	/* Protects filter_chain. */
    442	struct mutex filter_chain_lock;
    443	struct tcf_proto __rcu *filter_chain;
    444	struct list_head list;
    445	struct tcf_block *block;
    446	u32 index; /* chain index */
    447	unsigned int refcnt;
    448	unsigned int action_refcnt;
    449	bool explicitly_created;
    450	bool flushing;
    451	const struct tcf_proto_ops *tmplt_ops;
    452	void *tmplt_priv;
    453	struct rcu_head rcu;
    454};
    455
    456struct tcf_block {
    457	/* Lock protects tcf_block and lifetime-management data of chains
    458	 * attached to the block (refcnt, action_refcnt, explicitly_created).
    459	 */
    460	struct mutex lock;
    461	struct list_head chain_list;
    462	u32 index; /* block index for shared blocks */
    463	u32 classid; /* which class this block belongs to */
    464	refcount_t refcnt;
    465	struct net *net;
    466	struct Qdisc *q;
    467	struct rw_semaphore cb_lock; /* protects cb_list and offload counters */
    468	struct flow_block flow_block;
    469	struct list_head owner_list;
    470	bool keep_dst;
    471	atomic_t offloadcnt; /* Number of oddloaded filters */
    472	unsigned int nooffloaddevcnt; /* Number of devs unable to do offload */
    473	unsigned int lockeddevcnt; /* Number of devs that require rtnl lock. */
    474	struct {
    475		struct tcf_chain *chain;
    476		struct list_head filter_chain_list;
    477	} chain0;
    478	struct rcu_head rcu;
    479	DECLARE_HASHTABLE(proto_destroy_ht, 7);
    480	struct mutex proto_destroy_lock; /* Lock for proto_destroy hashtable. */
    481};
    482
    483static inline bool lockdep_tcf_chain_is_locked(struct tcf_chain *chain)
    484{
    485	return lockdep_is_held(&chain->filter_chain_lock);
    486}
    487
    488static inline bool lockdep_tcf_proto_is_locked(struct tcf_proto *tp)
    489{
    490	return lockdep_is_held(&tp->lock);
    491}
    492
    493#define tcf_chain_dereference(p, chain)					\
    494	rcu_dereference_protected(p, lockdep_tcf_chain_is_locked(chain))
    495
    496#define tcf_proto_dereference(p, tp)					\
    497	rcu_dereference_protected(p, lockdep_tcf_proto_is_locked(tp))
    498
    499static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
    500{
    501	struct qdisc_skb_cb *qcb;
    502
    503	BUILD_BUG_ON(sizeof(skb->cb) < sizeof(*qcb));
    504	BUILD_BUG_ON(sizeof(qcb->data) < sz);
    505}
    506
    507static inline int qdisc_qlen(const struct Qdisc *q)
    508{
    509	return q->q.qlen;
    510}
    511
    512static inline int qdisc_qlen_sum(const struct Qdisc *q)
    513{
    514	__u32 qlen = q->qstats.qlen;
    515	int i;
    516
    517	if (qdisc_is_percpu_stats(q)) {
    518		for_each_possible_cpu(i)
    519			qlen += per_cpu_ptr(q->cpu_qstats, i)->qlen;
    520	} else {
    521		qlen += q->q.qlen;
    522	}
    523
    524	return qlen;
    525}
    526
    527static inline struct qdisc_skb_cb *qdisc_skb_cb(const struct sk_buff *skb)
    528{
    529	return (struct qdisc_skb_cb *)skb->cb;
    530}
    531
    532static inline spinlock_t *qdisc_lock(struct Qdisc *qdisc)
    533{
    534	return &qdisc->q.lock;
    535}
    536
    537static inline struct Qdisc *qdisc_root(const struct Qdisc *qdisc)
    538{
    539	struct Qdisc *q = rcu_dereference_rtnl(qdisc->dev_queue->qdisc);
    540
    541	return q;
    542}
    543
    544static inline struct Qdisc *qdisc_root_bh(const struct Qdisc *qdisc)
    545{
    546	return rcu_dereference_bh(qdisc->dev_queue->qdisc);
    547}
    548
    549static inline struct Qdisc *qdisc_root_sleeping(const struct Qdisc *qdisc)
    550{
    551	return qdisc->dev_queue->qdisc_sleeping;
    552}
    553
    554/* The qdisc root lock is a mechanism by which to top level
    555 * of a qdisc tree can be locked from any qdisc node in the
    556 * forest.  This allows changing the configuration of some
    557 * aspect of the qdisc tree while blocking out asynchronous
    558 * qdisc access in the packet processing paths.
    559 *
    560 * It is only legal to do this when the root will not change
    561 * on us.  Otherwise we'll potentially lock the wrong qdisc
    562 * root.  This is enforced by holding the RTNL semaphore, which
    563 * all users of this lock accessor must do.
    564 */
    565static inline spinlock_t *qdisc_root_lock(const struct Qdisc *qdisc)
    566{
    567	struct Qdisc *root = qdisc_root(qdisc);
    568
    569	ASSERT_RTNL();
    570	return qdisc_lock(root);
    571}
    572
    573static inline spinlock_t *qdisc_root_sleeping_lock(const struct Qdisc *qdisc)
    574{
    575	struct Qdisc *root = qdisc_root_sleeping(qdisc);
    576
    577	ASSERT_RTNL();
    578	return qdisc_lock(root);
    579}
    580
    581static inline struct net_device *qdisc_dev(const struct Qdisc *qdisc)
    582{
    583	return qdisc->dev_queue->dev;
    584}
    585
    586static inline void sch_tree_lock(struct Qdisc *q)
    587{
    588	if (q->flags & TCQ_F_MQROOT)
    589		spin_lock_bh(qdisc_lock(q));
    590	else
    591		spin_lock_bh(qdisc_root_sleeping_lock(q));
    592}
    593
    594static inline void sch_tree_unlock(struct Qdisc *q)
    595{
    596	if (q->flags & TCQ_F_MQROOT)
    597		spin_unlock_bh(qdisc_lock(q));
    598	else
    599		spin_unlock_bh(qdisc_root_sleeping_lock(q));
    600}
    601
    602extern struct Qdisc noop_qdisc;
    603extern struct Qdisc_ops noop_qdisc_ops;
    604extern struct Qdisc_ops pfifo_fast_ops;
    605extern struct Qdisc_ops mq_qdisc_ops;
    606extern struct Qdisc_ops noqueue_qdisc_ops;
    607extern const struct Qdisc_ops *default_qdisc_ops;
    608static inline const struct Qdisc_ops *
    609get_default_qdisc_ops(const struct net_device *dev, int ntx)
    610{
    611	return ntx < dev->real_num_tx_queues ?
    612			default_qdisc_ops : &pfifo_fast_ops;
    613}
    614
    615struct Qdisc_class_common {
    616	u32			classid;
    617	struct hlist_node	hnode;
    618};
    619
    620struct Qdisc_class_hash {
    621	struct hlist_head	*hash;
    622	unsigned int		hashsize;
    623	unsigned int		hashmask;
    624	unsigned int		hashelems;
    625};
    626
    627static inline unsigned int qdisc_class_hash(u32 id, u32 mask)
    628{
    629	id ^= id >> 8;
    630	id ^= id >> 4;
    631	return id & mask;
    632}
    633
    634static inline struct Qdisc_class_common *
    635qdisc_class_find(const struct Qdisc_class_hash *hash, u32 id)
    636{
    637	struct Qdisc_class_common *cl;
    638	unsigned int h;
    639
    640	if (!id)
    641		return NULL;
    642
    643	h = qdisc_class_hash(id, hash->hashmask);
    644	hlist_for_each_entry(cl, &hash->hash[h], hnode) {
    645		if (cl->classid == id)
    646			return cl;
    647	}
    648	return NULL;
    649}
    650
    651static inline int tc_classid_to_hwtc(struct net_device *dev, u32 classid)
    652{
    653	u32 hwtc = TC_H_MIN(classid) - TC_H_MIN_PRIORITY;
    654
    655	return (hwtc < netdev_get_num_tc(dev)) ? hwtc : -EINVAL;
    656}
    657
    658int qdisc_class_hash_init(struct Qdisc_class_hash *);
    659void qdisc_class_hash_insert(struct Qdisc_class_hash *,
    660			     struct Qdisc_class_common *);
    661void qdisc_class_hash_remove(struct Qdisc_class_hash *,
    662			     struct Qdisc_class_common *);
    663void qdisc_class_hash_grow(struct Qdisc *, struct Qdisc_class_hash *);
    664void qdisc_class_hash_destroy(struct Qdisc_class_hash *);
    665
    666int dev_qdisc_change_tx_queue_len(struct net_device *dev);
    667void dev_qdisc_change_real_num_tx(struct net_device *dev,
    668				  unsigned int new_real_tx);
    669void dev_init_scheduler(struct net_device *dev);
    670void dev_shutdown(struct net_device *dev);
    671void dev_activate(struct net_device *dev);
    672void dev_deactivate(struct net_device *dev);
    673void dev_deactivate_many(struct list_head *head);
    674struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
    675			      struct Qdisc *qdisc);
    676void qdisc_reset(struct Qdisc *qdisc);
    677void qdisc_put(struct Qdisc *qdisc);
    678void qdisc_put_unlocked(struct Qdisc *qdisc);
    679void qdisc_tree_reduce_backlog(struct Qdisc *qdisc, int n, int len);
    680#ifdef CONFIG_NET_SCHED
    681int qdisc_offload_dump_helper(struct Qdisc *q, enum tc_setup_type type,
    682			      void *type_data);
    683void qdisc_offload_graft_helper(struct net_device *dev, struct Qdisc *sch,
    684				struct Qdisc *new, struct Qdisc *old,
    685				enum tc_setup_type type, void *type_data,
    686				struct netlink_ext_ack *extack);
    687#else
    688static inline int
    689qdisc_offload_dump_helper(struct Qdisc *q, enum tc_setup_type type,
    690			  void *type_data)
    691{
    692	q->flags &= ~TCQ_F_OFFLOADED;
    693	return 0;
    694}
    695
    696static inline void
    697qdisc_offload_graft_helper(struct net_device *dev, struct Qdisc *sch,
    698			   struct Qdisc *new, struct Qdisc *old,
    699			   enum tc_setup_type type, void *type_data,
    700			   struct netlink_ext_ack *extack)
    701{
    702}
    703#endif
    704struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
    705			  const struct Qdisc_ops *ops,
    706			  struct netlink_ext_ack *extack);
    707void qdisc_free(struct Qdisc *qdisc);
    708struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
    709				const struct Qdisc_ops *ops, u32 parentid,
    710				struct netlink_ext_ack *extack);
    711void __qdisc_calculate_pkt_len(struct sk_buff *skb,
    712			       const struct qdisc_size_table *stab);
    713int skb_do_redirect(struct sk_buff *);
    714
    715static inline bool skb_at_tc_ingress(const struct sk_buff *skb)
    716{
    717#ifdef CONFIG_NET_CLS_ACT
    718	return skb->tc_at_ingress;
    719#else
    720	return false;
    721#endif
    722}
    723
    724static inline bool skb_skip_tc_classify(struct sk_buff *skb)
    725{
    726#ifdef CONFIG_NET_CLS_ACT
    727	if (skb->tc_skip_classify) {
    728		skb->tc_skip_classify = 0;
    729		return true;
    730	}
    731#endif
    732	return false;
    733}
    734
    735/* Reset all TX qdiscs greater than index of a device.  */
    736static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i)
    737{
    738	struct Qdisc *qdisc;
    739
    740	for (; i < dev->num_tx_queues; i++) {
    741		qdisc = rtnl_dereference(netdev_get_tx_queue(dev, i)->qdisc);
    742		if (qdisc) {
    743			spin_lock_bh(qdisc_lock(qdisc));
    744			qdisc_reset(qdisc);
    745			spin_unlock_bh(qdisc_lock(qdisc));
    746		}
    747	}
    748}
    749
    750/* Are all TX queues of the device empty?  */
    751static inline bool qdisc_all_tx_empty(const struct net_device *dev)
    752{
    753	unsigned int i;
    754
    755	rcu_read_lock();
    756	for (i = 0; i < dev->num_tx_queues; i++) {
    757		struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
    758		const struct Qdisc *q = rcu_dereference(txq->qdisc);
    759
    760		if (!qdisc_is_empty(q)) {
    761			rcu_read_unlock();
    762			return false;
    763		}
    764	}
    765	rcu_read_unlock();
    766	return true;
    767}
    768
    769/* Are any of the TX qdiscs changing?  */
    770static inline bool qdisc_tx_changing(const struct net_device *dev)
    771{
    772	unsigned int i;
    773
    774	for (i = 0; i < dev->num_tx_queues; i++) {
    775		struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
    776		if (rcu_access_pointer(txq->qdisc) != txq->qdisc_sleeping)
    777			return true;
    778	}
    779	return false;
    780}
    781
    782/* Is the device using the noop qdisc on all queues?  */
    783static inline bool qdisc_tx_is_noop(const struct net_device *dev)
    784{
    785	unsigned int i;
    786
    787	for (i = 0; i < dev->num_tx_queues; i++) {
    788		struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
    789		if (rcu_access_pointer(txq->qdisc) != &noop_qdisc)
    790			return false;
    791	}
    792	return true;
    793}
    794
    795static inline unsigned int qdisc_pkt_len(const struct sk_buff *skb)
    796{
    797	return qdisc_skb_cb(skb)->pkt_len;
    798}
    799
    800/* additional qdisc xmit flags (NET_XMIT_MASK in linux/netdevice.h) */
    801enum net_xmit_qdisc_t {
    802	__NET_XMIT_STOLEN = 0x00010000,
    803	__NET_XMIT_BYPASS = 0x00020000,
    804};
    805
    806#ifdef CONFIG_NET_CLS_ACT
    807#define net_xmit_drop_count(e)	((e) & __NET_XMIT_STOLEN ? 0 : 1)
    808#else
    809#define net_xmit_drop_count(e)	(1)
    810#endif
    811
    812static inline void qdisc_calculate_pkt_len(struct sk_buff *skb,
    813					   const struct Qdisc *sch)
    814{
    815#ifdef CONFIG_NET_SCHED
    816	struct qdisc_size_table *stab = rcu_dereference_bh(sch->stab);
    817
    818	if (stab)
    819		__qdisc_calculate_pkt_len(skb, stab);
    820#endif
    821}
    822
    823static inline int qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
    824				struct sk_buff **to_free)
    825{
    826	qdisc_calculate_pkt_len(skb, sch);
    827	return sch->enqueue(skb, sch, to_free);
    828}
    829
    830static inline void _bstats_update(struct gnet_stats_basic_sync *bstats,
    831				  __u64 bytes, __u32 packets)
    832{
    833	u64_stats_update_begin(&bstats->syncp);
    834	u64_stats_add(&bstats->bytes, bytes);
    835	u64_stats_add(&bstats->packets, packets);
    836	u64_stats_update_end(&bstats->syncp);
    837}
    838
    839static inline void bstats_update(struct gnet_stats_basic_sync *bstats,
    840				 const struct sk_buff *skb)
    841{
    842	_bstats_update(bstats,
    843		       qdisc_pkt_len(skb),
    844		       skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1);
    845}
    846
    847static inline void qdisc_bstats_cpu_update(struct Qdisc *sch,
    848					   const struct sk_buff *skb)
    849{
    850	bstats_update(this_cpu_ptr(sch->cpu_bstats), skb);
    851}
    852
    853static inline void qdisc_bstats_update(struct Qdisc *sch,
    854				       const struct sk_buff *skb)
    855{
    856	bstats_update(&sch->bstats, skb);
    857}
    858
    859static inline void qdisc_qstats_backlog_dec(struct Qdisc *sch,
    860					    const struct sk_buff *skb)
    861{
    862	sch->qstats.backlog -= qdisc_pkt_len(skb);
    863}
    864
    865static inline void qdisc_qstats_cpu_backlog_dec(struct Qdisc *sch,
    866						const struct sk_buff *skb)
    867{
    868	this_cpu_sub(sch->cpu_qstats->backlog, qdisc_pkt_len(skb));
    869}
    870
    871static inline void qdisc_qstats_backlog_inc(struct Qdisc *sch,
    872					    const struct sk_buff *skb)
    873{
    874	sch->qstats.backlog += qdisc_pkt_len(skb);
    875}
    876
    877static inline void qdisc_qstats_cpu_backlog_inc(struct Qdisc *sch,
    878						const struct sk_buff *skb)
    879{
    880	this_cpu_add(sch->cpu_qstats->backlog, qdisc_pkt_len(skb));
    881}
    882
    883static inline void qdisc_qstats_cpu_qlen_inc(struct Qdisc *sch)
    884{
    885	this_cpu_inc(sch->cpu_qstats->qlen);
    886}
    887
    888static inline void qdisc_qstats_cpu_qlen_dec(struct Qdisc *sch)
    889{
    890	this_cpu_dec(sch->cpu_qstats->qlen);
    891}
    892
    893static inline void qdisc_qstats_cpu_requeues_inc(struct Qdisc *sch)
    894{
    895	this_cpu_inc(sch->cpu_qstats->requeues);
    896}
    897
    898static inline void __qdisc_qstats_drop(struct Qdisc *sch, int count)
    899{
    900	sch->qstats.drops += count;
    901}
    902
    903static inline void qstats_drop_inc(struct gnet_stats_queue *qstats)
    904{
    905	qstats->drops++;
    906}
    907
    908static inline void qstats_overlimit_inc(struct gnet_stats_queue *qstats)
    909{
    910	qstats->overlimits++;
    911}
    912
    913static inline void qdisc_qstats_drop(struct Qdisc *sch)
    914{
    915	qstats_drop_inc(&sch->qstats);
    916}
    917
    918static inline void qdisc_qstats_cpu_drop(struct Qdisc *sch)
    919{
    920	this_cpu_inc(sch->cpu_qstats->drops);
    921}
    922
    923static inline void qdisc_qstats_overlimit(struct Qdisc *sch)
    924{
    925	sch->qstats.overlimits++;
    926}
    927
    928static inline int qdisc_qstats_copy(struct gnet_dump *d, struct Qdisc *sch)
    929{
    930	__u32 qlen = qdisc_qlen_sum(sch);
    931
    932	return gnet_stats_copy_queue(d, sch->cpu_qstats, &sch->qstats, qlen);
    933}
    934
    935static inline void qdisc_qstats_qlen_backlog(struct Qdisc *sch,  __u32 *qlen,
    936					     __u32 *backlog)
    937{
    938	struct gnet_stats_queue qstats = { 0 };
    939
    940	gnet_stats_add_queue(&qstats, sch->cpu_qstats, &sch->qstats);
    941	*qlen = qstats.qlen + qdisc_qlen(sch);
    942	*backlog = qstats.backlog;
    943}
    944
    945static inline void qdisc_tree_flush_backlog(struct Qdisc *sch)
    946{
    947	__u32 qlen, backlog;
    948
    949	qdisc_qstats_qlen_backlog(sch, &qlen, &backlog);
    950	qdisc_tree_reduce_backlog(sch, qlen, backlog);
    951}
    952
    953static inline void qdisc_purge_queue(struct Qdisc *sch)
    954{
    955	__u32 qlen, backlog;
    956
    957	qdisc_qstats_qlen_backlog(sch, &qlen, &backlog);
    958	qdisc_reset(sch);
    959	qdisc_tree_reduce_backlog(sch, qlen, backlog);
    960}
    961
    962static inline void qdisc_skb_head_init(struct qdisc_skb_head *qh)
    963{
    964	qh->head = NULL;
    965	qh->tail = NULL;
    966	qh->qlen = 0;
    967}
    968
    969static inline void __qdisc_enqueue_tail(struct sk_buff *skb,
    970					struct qdisc_skb_head *qh)
    971{
    972	struct sk_buff *last = qh->tail;
    973
    974	if (last) {
    975		skb->next = NULL;
    976		last->next = skb;
    977		qh->tail = skb;
    978	} else {
    979		qh->tail = skb;
    980		qh->head = skb;
    981	}
    982	qh->qlen++;
    983}
    984
    985static inline int qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch)
    986{
    987	__qdisc_enqueue_tail(skb, &sch->q);
    988	qdisc_qstats_backlog_inc(sch, skb);
    989	return NET_XMIT_SUCCESS;
    990}
    991
    992static inline void __qdisc_enqueue_head(struct sk_buff *skb,
    993					struct qdisc_skb_head *qh)
    994{
    995	skb->next = qh->head;
    996
    997	if (!qh->head)
    998		qh->tail = skb;
    999	qh->head = skb;
   1000	qh->qlen++;
   1001}
   1002
   1003static inline struct sk_buff *__qdisc_dequeue_head(struct qdisc_skb_head *qh)
   1004{
   1005	struct sk_buff *skb = qh->head;
   1006
   1007	if (likely(skb != NULL)) {
   1008		qh->head = skb->next;
   1009		qh->qlen--;
   1010		if (qh->head == NULL)
   1011			qh->tail = NULL;
   1012		skb->next = NULL;
   1013	}
   1014
   1015	return skb;
   1016}
   1017
   1018static inline struct sk_buff *qdisc_dequeue_head(struct Qdisc *sch)
   1019{
   1020	struct sk_buff *skb = __qdisc_dequeue_head(&sch->q);
   1021
   1022	if (likely(skb != NULL)) {
   1023		qdisc_qstats_backlog_dec(sch, skb);
   1024		qdisc_bstats_update(sch, skb);
   1025	}
   1026
   1027	return skb;
   1028}
   1029
   1030/* Instead of calling kfree_skb() while root qdisc lock is held,
   1031 * queue the skb for future freeing at end of __dev_xmit_skb()
   1032 */
   1033static inline void __qdisc_drop(struct sk_buff *skb, struct sk_buff **to_free)
   1034{
   1035	skb->next = *to_free;
   1036	*to_free = skb;
   1037}
   1038
   1039static inline void __qdisc_drop_all(struct sk_buff *skb,
   1040				    struct sk_buff **to_free)
   1041{
   1042	if (skb->prev)
   1043		skb->prev->next = *to_free;
   1044	else
   1045		skb->next = *to_free;
   1046	*to_free = skb;
   1047}
   1048
   1049static inline unsigned int __qdisc_queue_drop_head(struct Qdisc *sch,
   1050						   struct qdisc_skb_head *qh,
   1051						   struct sk_buff **to_free)
   1052{
   1053	struct sk_buff *skb = __qdisc_dequeue_head(qh);
   1054
   1055	if (likely(skb != NULL)) {
   1056		unsigned int len = qdisc_pkt_len(skb);
   1057
   1058		qdisc_qstats_backlog_dec(sch, skb);
   1059		__qdisc_drop(skb, to_free);
   1060		return len;
   1061	}
   1062
   1063	return 0;
   1064}
   1065
   1066static inline struct sk_buff *qdisc_peek_head(struct Qdisc *sch)
   1067{
   1068	const struct qdisc_skb_head *qh = &sch->q;
   1069
   1070	return qh->head;
   1071}
   1072
   1073/* generic pseudo peek method for non-work-conserving qdisc */
   1074static inline struct sk_buff *qdisc_peek_dequeued(struct Qdisc *sch)
   1075{
   1076	struct sk_buff *skb = skb_peek(&sch->gso_skb);
   1077
   1078	/* we can reuse ->gso_skb because peek isn't called for root qdiscs */
   1079	if (!skb) {
   1080		skb = sch->dequeue(sch);
   1081
   1082		if (skb) {
   1083			__skb_queue_head(&sch->gso_skb, skb);
   1084			/* it's still part of the queue */
   1085			qdisc_qstats_backlog_inc(sch, skb);
   1086			sch->q.qlen++;
   1087		}
   1088	}
   1089
   1090	return skb;
   1091}
   1092
   1093static inline void qdisc_update_stats_at_dequeue(struct Qdisc *sch,
   1094						 struct sk_buff *skb)
   1095{
   1096	if (qdisc_is_percpu_stats(sch)) {
   1097		qdisc_qstats_cpu_backlog_dec(sch, skb);
   1098		qdisc_bstats_cpu_update(sch, skb);
   1099		qdisc_qstats_cpu_qlen_dec(sch);
   1100	} else {
   1101		qdisc_qstats_backlog_dec(sch, skb);
   1102		qdisc_bstats_update(sch, skb);
   1103		sch->q.qlen--;
   1104	}
   1105}
   1106
   1107static inline void qdisc_update_stats_at_enqueue(struct Qdisc *sch,
   1108						 unsigned int pkt_len)
   1109{
   1110	if (qdisc_is_percpu_stats(sch)) {
   1111		qdisc_qstats_cpu_qlen_inc(sch);
   1112		this_cpu_add(sch->cpu_qstats->backlog, pkt_len);
   1113	} else {
   1114		sch->qstats.backlog += pkt_len;
   1115		sch->q.qlen++;
   1116	}
   1117}
   1118
   1119/* use instead of qdisc->dequeue() for all qdiscs queried with ->peek() */
   1120static inline struct sk_buff *qdisc_dequeue_peeked(struct Qdisc *sch)
   1121{
   1122	struct sk_buff *skb = skb_peek(&sch->gso_skb);
   1123
   1124	if (skb) {
   1125		skb = __skb_dequeue(&sch->gso_skb);
   1126		if (qdisc_is_percpu_stats(sch)) {
   1127			qdisc_qstats_cpu_backlog_dec(sch, skb);
   1128			qdisc_qstats_cpu_qlen_dec(sch);
   1129		} else {
   1130			qdisc_qstats_backlog_dec(sch, skb);
   1131			sch->q.qlen--;
   1132		}
   1133	} else {
   1134		skb = sch->dequeue(sch);
   1135	}
   1136
   1137	return skb;
   1138}
   1139
   1140static inline void __qdisc_reset_queue(struct qdisc_skb_head *qh)
   1141{
   1142	/*
   1143	 * We do not know the backlog in bytes of this list, it
   1144	 * is up to the caller to correct it
   1145	 */
   1146	ASSERT_RTNL();
   1147	if (qh->qlen) {
   1148		rtnl_kfree_skbs(qh->head, qh->tail);
   1149
   1150		qh->head = NULL;
   1151		qh->tail = NULL;
   1152		qh->qlen = 0;
   1153	}
   1154}
   1155
   1156static inline void qdisc_reset_queue(struct Qdisc *sch)
   1157{
   1158	__qdisc_reset_queue(&sch->q);
   1159	sch->qstats.backlog = 0;
   1160}
   1161
   1162static inline struct Qdisc *qdisc_replace(struct Qdisc *sch, struct Qdisc *new,
   1163					  struct Qdisc **pold)
   1164{
   1165	struct Qdisc *old;
   1166
   1167	sch_tree_lock(sch);
   1168	old = *pold;
   1169	*pold = new;
   1170	if (old != NULL)
   1171		qdisc_purge_queue(old);
   1172	sch_tree_unlock(sch);
   1173
   1174	return old;
   1175}
   1176
   1177static inline void rtnl_qdisc_drop(struct sk_buff *skb, struct Qdisc *sch)
   1178{
   1179	rtnl_kfree_skbs(skb, skb);
   1180	qdisc_qstats_drop(sch);
   1181}
   1182
   1183static inline int qdisc_drop_cpu(struct sk_buff *skb, struct Qdisc *sch,
   1184				 struct sk_buff **to_free)
   1185{
   1186	__qdisc_drop(skb, to_free);
   1187	qdisc_qstats_cpu_drop(sch);
   1188
   1189	return NET_XMIT_DROP;
   1190}
   1191
   1192static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch,
   1193			     struct sk_buff **to_free)
   1194{
   1195	__qdisc_drop(skb, to_free);
   1196	qdisc_qstats_drop(sch);
   1197
   1198	return NET_XMIT_DROP;
   1199}
   1200
   1201static inline int qdisc_drop_all(struct sk_buff *skb, struct Qdisc *sch,
   1202				 struct sk_buff **to_free)
   1203{
   1204	__qdisc_drop_all(skb, to_free);
   1205	qdisc_qstats_drop(sch);
   1206
   1207	return NET_XMIT_DROP;
   1208}
   1209
   1210/* Length to Time (L2T) lookup in a qdisc_rate_table, to determine how
   1211   long it will take to send a packet given its size.
   1212 */
   1213static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen)
   1214{
   1215	int slot = pktlen + rtab->rate.cell_align + rtab->rate.overhead;
   1216	if (slot < 0)
   1217		slot = 0;
   1218	slot >>= rtab->rate.cell_log;
   1219	if (slot > 255)
   1220		return rtab->data[255]*(slot >> 8) + rtab->data[slot & 0xFF];
   1221	return rtab->data[slot];
   1222}
   1223
   1224struct psched_ratecfg {
   1225	u64	rate_bytes_ps; /* bytes per second */
   1226	u32	mult;
   1227	u16	overhead;
   1228	u16	mpu;
   1229	u8	linklayer;
   1230	u8	shift;
   1231};
   1232
   1233static inline u64 psched_l2t_ns(const struct psched_ratecfg *r,
   1234				unsigned int len)
   1235{
   1236	len += r->overhead;
   1237
   1238	if (len < r->mpu)
   1239		len = r->mpu;
   1240
   1241	if (unlikely(r->linklayer == TC_LINKLAYER_ATM))
   1242		return ((u64)(DIV_ROUND_UP(len,48)*53) * r->mult) >> r->shift;
   1243
   1244	return ((u64)len * r->mult) >> r->shift;
   1245}
   1246
   1247void psched_ratecfg_precompute(struct psched_ratecfg *r,
   1248			       const struct tc_ratespec *conf,
   1249			       u64 rate64);
   1250
   1251static inline void psched_ratecfg_getrate(struct tc_ratespec *res,
   1252					  const struct psched_ratecfg *r)
   1253{
   1254	memset(res, 0, sizeof(*res));
   1255
   1256	/* legacy struct tc_ratespec has a 32bit @rate field
   1257	 * Qdisc using 64bit rate should add new attributes
   1258	 * in order to maintain compatibility.
   1259	 */
   1260	res->rate = min_t(u64, r->rate_bytes_ps, ~0U);
   1261
   1262	res->overhead = r->overhead;
   1263	res->mpu = r->mpu;
   1264	res->linklayer = (r->linklayer & TC_LINKLAYER_MASK);
   1265}
   1266
   1267struct psched_pktrate {
   1268	u64	rate_pkts_ps; /* packets per second */
   1269	u32	mult;
   1270	u8	shift;
   1271};
   1272
   1273static inline u64 psched_pkt2t_ns(const struct psched_pktrate *r,
   1274				  unsigned int pkt_num)
   1275{
   1276	return ((u64)pkt_num * r->mult) >> r->shift;
   1277}
   1278
   1279void psched_ppscfg_precompute(struct psched_pktrate *r, u64 pktrate64);
   1280
   1281/* Mini Qdisc serves for specific needs of ingress/clsact Qdisc.
   1282 * The fast path only needs to access filter list and to update stats
   1283 */
   1284struct mini_Qdisc {
   1285	struct tcf_proto *filter_list;
   1286	struct tcf_block *block;
   1287	struct gnet_stats_basic_sync __percpu *cpu_bstats;
   1288	struct gnet_stats_queue	__percpu *cpu_qstats;
   1289	unsigned long rcu_state;
   1290};
   1291
   1292static inline void mini_qdisc_bstats_cpu_update(struct mini_Qdisc *miniq,
   1293						const struct sk_buff *skb)
   1294{
   1295	bstats_update(this_cpu_ptr(miniq->cpu_bstats), skb);
   1296}
   1297
   1298static inline void mini_qdisc_qstats_cpu_drop(struct mini_Qdisc *miniq)
   1299{
   1300	this_cpu_inc(miniq->cpu_qstats->drops);
   1301}
   1302
   1303struct mini_Qdisc_pair {
   1304	struct mini_Qdisc miniq1;
   1305	struct mini_Qdisc miniq2;
   1306	struct mini_Qdisc __rcu **p_miniq;
   1307};
   1308
   1309void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp,
   1310			  struct tcf_proto *tp_head);
   1311void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc,
   1312			  struct mini_Qdisc __rcu **p_miniq);
   1313void mini_qdisc_pair_block_init(struct mini_Qdisc_pair *miniqp,
   1314				struct tcf_block *block);
   1315
   1316void mq_change_real_num_tx(struct Qdisc *sch, unsigned int new_real_tx);
   1317
   1318int sch_frag_xmit_hook(struct sk_buff *skb, int (*xmit)(struct sk_buff *skb));
   1319
   1320#endif