nfp: abm: remember which Qdisc is root
authorJakub Kicinski <jakub.kicinski@netronome.com>
Mon, 12 Nov 2018 22:58:11 +0000 (14:58 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 14 Nov 2018 16:51:27 +0000 (08:51 -0800)
Keep track of which Qdisc is currently root.  We need to implement
TC_SETUP_ROOT_QDISC handling, and for completeness also clear the
root Qdisc pointer when it's freed.  TC_SETUP_ROOT_QDISC isn't always
sent when device is dismantled.

Remembering the root Qdisc will allow us to build the entire hierarchy
in following patches.

Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: John Hurley <john.hurley@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/netronome/nfp/abm/main.c
drivers/net/ethernet/netronome/nfp/abm/main.h
drivers/net/ethernet/netronome/nfp/abm/qdisc.c

index 35f3a60545694f213c1da12aa279e7d82d77a0c0..da5394886a78ba041f571699d173f04308eb86bb 100644 (file)
@@ -37,6 +37,8 @@ nfp_abm_setup_tc(struct nfp_app *app, struct net_device *netdev,
                return -EOPNOTSUPP;
 
        switch (type) {
+       case TC_SETUP_ROOT_QDISC:
+               return nfp_abm_setup_root(netdev, repr->app_priv, type_data);
        case TC_SETUP_QDISC_MQ:
                return nfp_abm_setup_tc_mq(netdev, repr->app_priv, type_data);
        case TC_SETUP_QDISC_RED:
index 64cb5ebcf80e6cd588f65bb97a9babc37e083277..48d5199898866920ff9e9924c71f351160304790 100644 (file)
@@ -116,6 +116,7 @@ struct nfp_red_qdisc {
  * @parent:    handle of expected parent, i.e. handle of MQ, or TC_H_ROOT
  * @num_qdiscs:        number of currently used qdiscs
  * @red_qdiscs:        array of qdiscs
+ * @root_qdisc:        pointer to the current root of the Qdisc hierarchy
  * @qdiscs:    all qdiscs recorded by major part of the handle
  */
 struct nfp_abm_link {
@@ -127,9 +128,12 @@ struct nfp_abm_link {
        u32 parent;
        unsigned int num_qdiscs;
        struct nfp_red_qdisc *red_qdiscs;
+       struct nfp_qdisc *root_qdisc;
        struct radix_tree_root qdiscs;
 };
 
+int nfp_abm_setup_root(struct net_device *netdev, struct nfp_abm_link *alink,
+                      struct tc_root_qopt_offload *opt);
 int nfp_abm_setup_tc_red(struct net_device *netdev, struct nfp_abm_link *alink,
                         struct tc_red_qopt_offload *opt);
 int nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink,
index a6f95924656dae7932ece90d76a6303f66b11324..ba6ce2d1eda234d238237e56920eb568da62e809 100644 (file)
@@ -143,6 +143,9 @@ nfp_abm_qdisc_destroy(struct net_device *netdev, struct nfp_abm_link *alink,
                return;
 
        nfp_abm_qdisc_free(netdev, alink, qdisc);
+
+       if (alink->root_qdisc == qdisc)
+               alink->root_qdisc = NULL;
 }
 
 static void
@@ -450,3 +453,13 @@ int nfp_abm_setup_tc_mq(struct net_device *netdev, struct nfp_abm_link *alink,
                return -EOPNOTSUPP;
        }
 }
+
+int nfp_abm_setup_root(struct net_device *netdev, struct nfp_abm_link *alink,
+                      struct tc_root_qopt_offload *opt)
+{
+       if (opt->ingress)
+               return -EOPNOTSUPP;
+       alink->root_qdisc = nfp_abm_qdisc_find(alink, opt->handle);
+
+       return 0;
+}