diff options
-rw-r--r-- | include/net/sch_generic.h | 7 | ||||
-rw-r--r-- | net/sched/sch_api.c | 2 | ||||
-rw-r--r-- | net/sched/sch_generic.c | 11 | ||||
-rw-r--r-- | net/sched/sch_mq.c | 4 | ||||
-rw-r--r-- | net/sched/sch_mqprio.c | 4 |
5 files changed, 22 insertions, 6 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 4616f468d599..1540f9c2fcf4 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h | |||
@@ -50,6 +50,13 @@ struct Qdisc { | |||
50 | #define TCQ_F_INGRESS 2 | 50 | #define TCQ_F_INGRESS 2 |
51 | #define TCQ_F_CAN_BYPASS 4 | 51 | #define TCQ_F_CAN_BYPASS 4 |
52 | #define TCQ_F_MQROOT 8 | 52 | #define TCQ_F_MQROOT 8 |
53 | #define TCQ_F_ONETXQUEUE 0x10 /* dequeue_skb() can assume all skbs are for | ||
54 | * q->dev_queue : It can test | ||
55 | * netif_xmit_frozen_or_stopped() before | ||
56 | * dequeueing next packet. | ||
57 | * Its true for MQ/MQPRIO slaves, or non | ||
58 | * multiqueue device. | ||
59 | */ | ||
53 | #define TCQ_F_WARN_NONWC (1 << 16) | 60 | #define TCQ_F_WARN_NONWC (1 << 16) |
54 | int padded; | 61 | int padded; |
55 | const struct Qdisc_ops *ops; | 62 | const struct Qdisc_ops *ops; |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 4799c4840c1a..d84f7e734cd7 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -833,6 +833,8 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, | |||
833 | goto err_out3; | 833 | goto err_out3; |
834 | } | 834 | } |
835 | lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock); | 835 | lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock); |
836 | if (!netif_is_multiqueue(dev)) | ||
837 | sch->flags |= TCQ_F_ONETXQUEUE; | ||
836 | } | 838 | } |
837 | 839 | ||
838 | sch->handle = handle; | 840 | sch->handle = handle; |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index aefc1504dc88..5d81a4478514 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -53,20 +53,19 @@ static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q) | |||
53 | static inline struct sk_buff *dequeue_skb(struct Qdisc *q) | 53 | static inline struct sk_buff *dequeue_skb(struct Qdisc *q) |
54 | { | 54 | { |
55 | struct sk_buff *skb = q->gso_skb; | 55 | struct sk_buff *skb = q->gso_skb; |
56 | const struct netdev_queue *txq = q->dev_queue; | ||
56 | 57 | ||
57 | if (unlikely(skb)) { | 58 | if (unlikely(skb)) { |
58 | struct net_device *dev = qdisc_dev(q); | ||
59 | struct netdev_queue *txq; | ||
60 | |||
61 | /* check the reason of requeuing without tx lock first */ | 59 | /* check the reason of requeuing without tx lock first */ |
62 | txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); | 60 | txq = netdev_get_tx_queue(txq->dev, skb_get_queue_mapping(skb)); |
63 | if (!netif_xmit_frozen_or_stopped(txq)) { | 61 | if (!netif_xmit_frozen_or_stopped(txq)) { |
64 | q->gso_skb = NULL; | 62 | q->gso_skb = NULL; |
65 | q->q.qlen--; | 63 | q->q.qlen--; |
66 | } else | 64 | } else |
67 | skb = NULL; | 65 | skb = NULL; |
68 | } else { | 66 | } else { |
69 | skb = q->dequeue(q); | 67 | if (!(q->flags & TCQ_F_ONETXQUEUE) || !netif_xmit_frozen_or_stopped(txq)) |
68 | skb = q->dequeue(q); | ||
70 | } | 69 | } |
71 | 70 | ||
72 | return skb; | 71 | return skb; |
@@ -686,6 +685,8 @@ static void attach_one_default_qdisc(struct net_device *dev, | |||
686 | netdev_info(dev, "activation failed\n"); | 685 | netdev_info(dev, "activation failed\n"); |
687 | return; | 686 | return; |
688 | } | 687 | } |
688 | if (!netif_is_multiqueue(dev)) | ||
689 | qdisc->flags |= TCQ_F_ONETXQUEUE; | ||
689 | } | 690 | } |
690 | dev_queue->qdisc_sleeping = qdisc; | 691 | dev_queue->qdisc_sleeping = qdisc; |
691 | } | 692 | } |
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index 0a4b2f9a0094..5da78a19ac9a 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c | |||
@@ -63,6 +63,7 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt) | |||
63 | if (qdisc == NULL) | 63 | if (qdisc == NULL) |
64 | goto err; | 64 | goto err; |
65 | priv->qdiscs[ntx] = qdisc; | 65 | priv->qdiscs[ntx] = qdisc; |
66 | qdisc->flags |= TCQ_F_ONETXQUEUE; | ||
66 | } | 67 | } |
67 | 68 | ||
68 | sch->flags |= TCQ_F_MQROOT; | 69 | sch->flags |= TCQ_F_MQROOT; |
@@ -150,7 +151,8 @@ static int mq_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, | |||
150 | dev_deactivate(dev); | 151 | dev_deactivate(dev); |
151 | 152 | ||
152 | *old = dev_graft_qdisc(dev_queue, new); | 153 | *old = dev_graft_qdisc(dev_queue, new); |
153 | 154 | if (new) | |
155 | new->flags |= TCQ_F_ONETXQUEUE; | ||
154 | if (dev->flags & IFF_UP) | 156 | if (dev->flags & IFF_UP) |
155 | dev_activate(dev); | 157 | dev_activate(dev); |
156 | return 0; | 158 | return 0; |
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c index d1831ca966d4..accec33c454c 100644 --- a/net/sched/sch_mqprio.c +++ b/net/sched/sch_mqprio.c | |||
@@ -132,6 +132,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt) | |||
132 | goto err; | 132 | goto err; |
133 | } | 133 | } |
134 | priv->qdiscs[i] = qdisc; | 134 | priv->qdiscs[i] = qdisc; |
135 | qdisc->flags |= TCQ_F_ONETXQUEUE; | ||
135 | } | 136 | } |
136 | 137 | ||
137 | /* If the mqprio options indicate that hardware should own | 138 | /* If the mqprio options indicate that hardware should own |
@@ -205,6 +206,9 @@ static int mqprio_graft(struct Qdisc *sch, unsigned long cl, struct Qdisc *new, | |||
205 | 206 | ||
206 | *old = dev_graft_qdisc(dev_queue, new); | 207 | *old = dev_graft_qdisc(dev_queue, new); |
207 | 208 | ||
209 | if (new) | ||
210 | new->flags |= TCQ_F_ONETXQUEUE; | ||
211 | |||
208 | if (dev->flags & IFF_UP) | 212 | if (dev->flags & IFF_UP) |
209 | dev_activate(dev); | 213 | dev_activate(dev); |
210 | 214 | ||