2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2024-12-15 00:34:10 +08:00

net: sched: a dflt qdisc may be used with per cpu stats

Enable dflt qdisc support for per cpu stats before this patch a dflt
qdisc was required to use the global statistics qstats and bstats.

This adds a static flags field to qdisc_ops that is propagated
into qdisc->flags in qdisc allocate call. This allows the allocation
block to completely allocate the qdisc object so we don't have
dangling allocations after qdisc init.

Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
John Fastabend 2017-12-07 09:55:26 -08:00 committed by David S. Miller
parent 40bd036219
commit d59f5ffa59
2 changed files with 17 additions and 0 deletions

View File

@ -180,6 +180,7 @@ struct Qdisc_ops {
const struct Qdisc_class_ops *cl_ops; const struct Qdisc_class_ops *cl_ops;
char id[IFNAMSIZ]; char id[IFNAMSIZ];
int priv_size; int priv_size;
unsigned int static_flags;
int (*enqueue)(struct sk_buff *skb, int (*enqueue)(struct sk_buff *skb,
struct Qdisc *sch, struct Qdisc *sch,

View File

@ -632,6 +632,19 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
qdisc_skb_head_init(&sch->q); qdisc_skb_head_init(&sch->q);
spin_lock_init(&sch->q.lock); 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); spin_lock_init(&sch->busylock);
lockdep_set_class(&sch->busylock, lockdep_set_class(&sch->busylock,
dev->qdisc_tx_busylock ?: &qdisc_tx_busylock); dev->qdisc_tx_busylock ?: &qdisc_tx_busylock);
@ -641,6 +654,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
dev->qdisc_running_key ?: &qdisc_running_key); dev->qdisc_running_key ?: &qdisc_running_key);
sch->ops = ops; sch->ops = ops;
sch->flags = ops->static_flags;
sch->enqueue = ops->enqueue; sch->enqueue = ops->enqueue;
sch->dequeue = ops->dequeue; sch->dequeue = ops->dequeue;
sch->dev_queue = dev_queue; sch->dev_queue = dev_queue;
@ -648,6 +662,8 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
refcount_set(&sch->refcnt, 1); refcount_set(&sch->refcnt, 1);
return sch; return sch;
errout1:
kfree(p);
errout: errout:
return ERR_PTR(err); return ERR_PTR(err);
} }