Commit f07d1501 authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller

multiq: Further multiqueue cleanup

This patch resolves a few issues found with multiq including wording
suggestions and a problem seen in the allocation of queues.
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 67333bb5
...@@ -29,15 +29,15 @@ Section 2: Qdisc support for multiqueue devices ...@@ -29,15 +29,15 @@ Section 2: Qdisc support for multiqueue devices
----------------------------------------------- -----------------------------------------------
Currently two qdiscs support multiqueue devices. The first is the default Currently two qdiscs are optimized for multiqueue devices. The first is the
pfifo_fast qdisc. This qdisc supports one qdisc per hardware queue. A new default pfifo_fast qdisc. This qdisc supports one qdisc per hardware queue.
round-robin qdisc, sch_multiq also supports multiple hardware queues. The A new round-robin qdisc, sch_multiq also supports multiple hardware queues. The
qdisc is responsible for classifying the skb's and then directing the skb's to qdisc is responsible for classifying the skb's and then directing the skb's to
bands and queues based on the value in skb->queue_mapping. Use this field in bands and queues based on the value in skb->queue_mapping. Use this field in
the base driver to determine which queue to send the skb to. the base driver to determine which queue to send the skb to.
sch_multiq has been added for hardware that wishes to avoid unnecessary sch_multiq has been added for hardware that wishes to avoid head-of-line
requeuing. It will cycle though the bands and verify that the hardware queue blocking. It will cycle though the bands and verify that the hardware queue
associated with the band is not stopped prior to dequeuing a packet. associated with the band is not stopped prior to dequeuing a packet.
On qdisc load, the number of bands is based on the number of queues on the On qdisc load, the number of bands is based on the number of queues on the
...@@ -63,8 +63,8 @@ band 1 => queue 1 ...@@ -63,8 +63,8 @@ band 1 => queue 1
band 2 => queue 2 band 2 => queue 2
band 3 => queue 3 band 3 => queue 3
Traffic will begin flowing through each queue if your base device has either Traffic will begin flowing through each queue based on either the simple_tx_hash
the default simple_tx_hash or a custom netdev->select_queue() defined. function or based on netdev->select_queue() if you have it defined.
The behavior of tc filters remains the same. However a new tc action, The behavior of tc filters remains the same. However a new tc action,
skbedit, has been added. Assuming you wanted to route all traffic to a skbedit, has been added. Assuming you wanted to route all traffic to a
......
...@@ -214,8 +214,8 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt) ...@@ -214,8 +214,8 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
sch_tree_lock(sch); sch_tree_lock(sch);
q->bands = qopt->bands; q->bands = qopt->bands;
for (i = q->bands; i < q->max_bands; i++) { for (i = q->bands; i < q->max_bands; i++) {
struct Qdisc *child = xchg(&q->queues[i], &noop_qdisc); if (q->queues[i] != &noop_qdisc) {
if (child != &noop_qdisc) { struct Qdisc *child = xchg(&q->queues[i], &noop_qdisc);
qdisc_tree_decrease_qlen(child, child->q.qlen); qdisc_tree_decrease_qlen(child, child->q.qlen);
qdisc_destroy(child); qdisc_destroy(child);
} }
...@@ -250,7 +250,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt) ...@@ -250,7 +250,7 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
static int multiq_init(struct Qdisc *sch, struct nlattr *opt) static int multiq_init(struct Qdisc *sch, struct nlattr *opt)
{ {
struct multiq_sched_data *q = qdisc_priv(sch); struct multiq_sched_data *q = qdisc_priv(sch);
int i; int i, err;
q->queues = NULL; q->queues = NULL;
...@@ -265,7 +265,12 @@ static int multiq_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -265,7 +265,12 @@ static int multiq_init(struct Qdisc *sch, struct nlattr *opt)
for (i = 0; i < q->max_bands; i++) for (i = 0; i < q->max_bands; i++)
q->queues[i] = &noop_qdisc; q->queues[i] = &noop_qdisc;
return multiq_tune(sch, opt); err = multiq_tune(sch,opt);
if (err)
kfree(q->queues);
return err;
} }
static int multiq_dump(struct Qdisc *sch, struct sk_buff *skb) static int multiq_dump(struct Qdisc *sch, struct sk_buff *skb)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment