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