Hi Daniel,

On 01/16/2018 02:20 AM, Daniel Borkmann via iovisor-dev wrote:
> 
> Basically like this for net to reduce merge churn later on:
> 
>  include/net/sch_generic.h |  2 ++
>  net/sched/sch_api.c       | 15 +--------------
>  net/sched/sch_generic.c   | 18 +++++++++++++++++-
>  net/sched/sch_ingress.c   | 19 ++++---------------
>  4 files changed, 24 insertions(+), 30 deletions(-)
> 
> diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
> index 83a3e47..becf86a 100644
> --- a/include/net/sch_generic.h
> +++ b/include/net/sch_generic.h
> @@ -179,6 +179,7 @@ struct Qdisc_ops {
>       const struct Qdisc_class_ops    *cl_ops;
>       char                    id[IFNAMSIZ];
>       int                     priv_size;
> +     unsigned int            static_flags;
> 
>       int                     (*enqueue)(struct sk_buff *skb,
>                                          struct Qdisc *sch,
> @@ -444,6 +445,7 @@ void qdisc_tree_reduce_backlog(struct Qdisc *qdisc, 
> unsigned int n,
>                              unsigned int len);
>  struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
>                         const struct Qdisc_ops *ops);
> +void qdisc_free(struct Qdisc *qdisc);
>  struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
>                               const struct Qdisc_ops *ops, u32 parentid);
>  void __qdisc_calculate_pkt_len(struct sk_buff *skb,
> diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> index 0f1eab9..52529b7 100644
> --- a/net/sched/sch_api.c
> +++ b/net/sched/sch_api.c
> @@ -1063,17 +1063,6 @@ static struct Qdisc *qdisc_create(struct net_device 
> *dev,
>       }
> 
>       if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS])) == 0) {
> -             if (qdisc_is_percpu_stats(sch)) {
> -                     sch->cpu_bstats =
> -                             netdev_alloc_pcpu_stats(struct 
> gnet_stats_basic_cpu);
> -                     if (!sch->cpu_bstats)
> -                             goto err_out4;
> -
> -                     sch->cpu_qstats = alloc_percpu(struct gnet_stats_queue);
> -                     if (!sch->cpu_qstats)
> -                             goto err_out4;
> -             }
> -
>               if (tca[TCA_STAB]) {
>                       stab = qdisc_get_stab(tca[TCA_STAB]);
>                       if (IS_ERR(stab)) {
> @@ -1115,7 +1104,7 @@ static struct Qdisc *qdisc_create(struct net_device 
> *dev,
>               ops->destroy(sch);
>  err_out3:
>       dev_put(dev);
> -     kfree((char *) sch - sch->padded);
> +     qdisc_free(sch);
>  err_out2:
>       module_put(ops->owner);
>  err_out:
> @@ -1123,8 +1112,6 @@ static struct Qdisc *qdisc_create(struct net_device 
> *dev,
>       return NULL;
> 
>  err_out4:
> -     free_percpu(sch->cpu_bstats);
> -     free_percpu(sch->cpu_qstats);
>       /*
>        * Any broken qdiscs that would require a ops->reset() here?
>        * The qdisc was never in action so it shouldn't be necessary.
> diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
> index 661c714..cac003f 100644
> --- a/net/sched/sch_generic.c
> +++ b/net/sched/sch_generic.c
> @@ -633,6 +633,19 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
>       qdisc_skb_head_init(&sch->q);
>       spin_lock_init(&sch->q.lock);
> 
> +     if (ops->static_flags & TCQ_F_CPUSTATS) {
> +             sch->cpu_bstats =
> +                     netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
> +             if (!sch->cpu_bstats)
> +                     goto errout1;
> +
> +             sch->cpu_qstats = alloc_percpu(struct gnet_stats_queue);
> +             if (!sch->cpu_qstats) {
> +                     free_percpu(sch->cpu_bstats);
> +                     goto errout1;
> +             }
> +     }
> +
>       spin_lock_init(&sch->busylock);
>       lockdep_set_class(&sch->busylock,
>                         dev->qdisc_tx_busylock ?: &qdisc_tx_busylock);
> @@ -642,6 +655,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
>                         dev->qdisc_running_key ?: &qdisc_running_key);
> 
>       sch->ops = ops;
> +     sch->flags = ops->static_flags;
>       sch->enqueue = ops->enqueue;
>       sch->dequeue = ops->dequeue;
>       sch->dev_queue = dev_queue;
> @@ -649,6 +663,8 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
>       refcount_set(&sch->refcnt, 1);
> 
>       return sch;
> +errout1:
> +     kfree(p);
>  errout:
>       return ERR_PTR(err);
>  }
> @@ -698,7 +714,7 @@ void qdisc_reset(struct Qdisc *qdisc)
>  }
>  EXPORT_SYMBOL(qdisc_reset);
> 
> -static void qdisc_free(struct Qdisc *qdisc)
> +void qdisc_free(struct Qdisc *qdisc)
>  {
>       if (qdisc_is_percpu_stats(qdisc)) {
>               free_percpu(qdisc->cpu_bstats);
> diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
> index fc1286f..003e1b0 100644
> --- a/net/sched/sch_ingress.c
> +++ b/net/sched/sch_ingress.c
> @@ -66,7 +66,6 @@ static int ingress_init(struct Qdisc *sch, struct nlattr 
> *opt)
>  {
>       struct ingress_sched_data *q = qdisc_priv(sch);
>       struct net_device *dev = qdisc_dev(sch);
> -     int err;
> 
>       net_inc_ingress_queue();
> 
> @@ -76,13 +75,7 @@ static int ingress_init(struct Qdisc *sch, struct nlattr 
> *opt)
>       q->block_info.chain_head_change = clsact_chain_head_change;
>       q->block_info.chain_head_change_priv = &q->miniqp;
> 
> -     err = tcf_block_get_ext(&q->block, sch, &q->block_info);
> -     if (err)
> -             return err;
> -
> -     sch->flags |= TCQ_F_CPUSTATS;
> -
> -     return 0;
> +     return tcf_block_get_ext(&q->block, sch, &q->block_info);
>  }
> 
>  static void ingress_destroy(struct Qdisc *sch)
> @@ -121,6 +114,7 @@ static struct Qdisc_ops ingress_qdisc_ops __read_mostly = 
> {
>       .cl_ops         =       &ingress_class_ops,
>       .id             =       "ingress",
>       .priv_size      =       sizeof(struct ingress_sched_data),
> +     .static_flags   =       TCQ_F_CPUSTATS,
>       .init           =       ingress_init,
>       .destroy        =       ingress_destroy,
>       .dump           =       ingress_dump,
> @@ -192,13 +186,7 @@ static int clsact_init(struct Qdisc *sch, struct nlattr 
> *opt)
>       q->egress_block_info.chain_head_change = clsact_chain_head_change;
>       q->egress_block_info.chain_head_change_priv = &q->miniqp_egress;
> 
> -     err = tcf_block_get_ext(&q->egress_block, sch, &q->egress_block_info);
> -     if (err)
> -             return err;
> -
> -     sch->flags |= TCQ_F_CPUSTATS;
> -
> -     return 0;
> +     return tcf_block_get_ext(&q->egress_block, sch, &q->egress_block_info);
>  }
> 
>  static void clsact_destroy(struct Qdisc *sch)
> @@ -225,6 +213,7 @@ static struct Qdisc_ops clsact_qdisc_ops __read_mostly = {
>       .cl_ops         =       &clsact_class_ops,
>       .id             =       "clsact",
>       .priv_size      =       sizeof(struct clsact_sched_data),
> +     .static_flags   =       TCQ_F_CPUSTATS,
>       .init           =       clsact_init,
>       .destroy        =       clsact_destroy,
>       .dump           =       ingress_dump,
> 

I applied this on top of v4.15-rc8 from Linus' tree and 'test_xlate' is now
passing again on ppc64le systems. Thanks for the patch.

--
With Regards,
Sandipan

_______________________________________________
iovisor-dev mailing list
[email protected]
https://lists.iovisor.org/mailman/listinfo/iovisor-dev

Reply via email to