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: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Alexander Duyck 2008-09-12 17:57:23 -07:00 committed by David S. Miller
parent 67333bb567
commit f07d150129
2 changed files with 16 additions and 11 deletions

View File

@ -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
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

View File

@ -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)
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)
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)