LCOV - code coverage report
Current view: top level - include/net - sch_generic.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 12 248 4.8 %
Date: 2022-03-28 16:04:14 Functions: 0 13 0.0 %
Branches: 6 206 2.9 %

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

Generated by: LCOV version 1.14