diff options
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r-- | net/sched/sch_api.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 570cef2a9c5f..2313fa7c97be 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -185,9 +185,10 @@ EXPORT_SYMBOL(unregister_qdisc); | |||
185 | 185 | ||
186 | struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) | 186 | struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) |
187 | { | 187 | { |
188 | struct netdev_queue *dev_queue = &dev->tx_queue; | ||
188 | struct Qdisc *q; | 189 | struct Qdisc *q; |
189 | 190 | ||
190 | list_for_each_entry(q, &dev->qdisc_list, list) { | 191 | list_for_each_entry(q, &dev_queue->qdisc_list, list) { |
191 | if (q->handle == handle) | 192 | if (q->handle == handle) |
192 | return q; | 193 | return q; |
193 | } | 194 | } |
@@ -441,6 +442,7 @@ static u32 qdisc_alloc_handle(struct net_device *dev) | |||
441 | static struct Qdisc * | 442 | static struct Qdisc * |
442 | dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc) | 443 | dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc) |
443 | { | 444 | { |
445 | struct netdev_queue *dev_queue; | ||
444 | struct Qdisc *oqdisc; | 446 | struct Qdisc *oqdisc; |
445 | 447 | ||
446 | if (dev->flags & IFF_UP) | 448 | if (dev->flags & IFF_UP) |
@@ -459,8 +461,8 @@ dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc) | |||
459 | } | 461 | } |
460 | 462 | ||
461 | } else { | 463 | } else { |
462 | 464 | dev_queue = &dev->tx_queue; | |
463 | oqdisc = dev->qdisc_sleeping; | 465 | oqdisc = dev_queue->qdisc_sleeping; |
464 | 466 | ||
465 | /* Prune old scheduler */ | 467 | /* Prune old scheduler */ |
466 | if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) | 468 | if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) |
@@ -469,8 +471,8 @@ dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc) | |||
469 | /* ... and graft new one */ | 471 | /* ... and graft new one */ |
470 | if (qdisc == NULL) | 472 | if (qdisc == NULL) |
471 | qdisc = &noop_qdisc; | 473 | qdisc = &noop_qdisc; |
472 | dev->qdisc_sleeping = qdisc; | 474 | dev_queue->qdisc_sleeping = qdisc; |
473 | dev->qdisc = &noop_qdisc; | 475 | dev_queue->qdisc = &noop_qdisc; |
474 | } | 476 | } |
475 | 477 | ||
476 | qdisc_unlock_tree(dev); | 478 | qdisc_unlock_tree(dev); |
@@ -633,7 +635,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue, | |||
633 | } | 635 | } |
634 | } | 636 | } |
635 | qdisc_lock_tree(dev); | 637 | qdisc_lock_tree(dev); |
636 | list_add_tail(&sch->list, &dev->qdisc_list); | 638 | list_add_tail(&sch->list, &dev_queue->qdisc_list); |
637 | qdisc_unlock_tree(dev); | 639 | qdisc_unlock_tree(dev); |
638 | 640 | ||
639 | return sch; | 641 | return sch; |
@@ -740,7 +742,8 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
740 | q = dev->qdisc_ingress; | 742 | q = dev->qdisc_ingress; |
741 | } | 743 | } |
742 | } else { | 744 | } else { |
743 | q = dev->qdisc_sleeping; | 745 | struct netdev_queue *dev_queue = &dev->tx_queue; |
746 | q = dev_queue->qdisc_sleeping; | ||
744 | } | 747 | } |
745 | if (!q) | 748 | if (!q) |
746 | return -ENOENT; | 749 | return -ENOENT; |
@@ -814,7 +817,8 @@ replay: | |||
814 | q = dev->qdisc_ingress; | 817 | q = dev->qdisc_ingress; |
815 | } | 818 | } |
816 | } else { | 819 | } else { |
817 | q = dev->qdisc_sleeping; | 820 | struct netdev_queue *dev_queue = &dev->tx_queue; |
821 | q = dev_queue->qdisc_sleeping; | ||
818 | } | 822 | } |
819 | 823 | ||
820 | /* It may be default qdisc, ignore it */ | 824 | /* It may be default qdisc, ignore it */ |
@@ -1015,12 +1019,14 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb) | |||
1015 | read_lock(&dev_base_lock); | 1019 | read_lock(&dev_base_lock); |
1016 | idx = 0; | 1020 | idx = 0; |
1017 | for_each_netdev(&init_net, dev) { | 1021 | for_each_netdev(&init_net, dev) { |
1022 | struct netdev_queue *dev_queue; | ||
1018 | if (idx < s_idx) | 1023 | if (idx < s_idx) |
1019 | goto cont; | 1024 | goto cont; |
1020 | if (idx > s_idx) | 1025 | if (idx > s_idx) |
1021 | s_q_idx = 0; | 1026 | s_q_idx = 0; |
1022 | q_idx = 0; | 1027 | q_idx = 0; |
1023 | list_for_each_entry(q, &dev->qdisc_list, list) { | 1028 | dev_queue = &dev->tx_queue; |
1029 | list_for_each_entry(q, &dev_queue->qdisc_list, list) { | ||
1024 | if (q_idx < s_q_idx) { | 1030 | if (q_idx < s_q_idx) { |
1025 | q_idx++; | 1031 | q_idx++; |
1026 | continue; | 1032 | continue; |
@@ -1054,6 +1060,7 @@ done: | |||
1054 | static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | 1060 | static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) |
1055 | { | 1061 | { |
1056 | struct net *net = sock_net(skb->sk); | 1062 | struct net *net = sock_net(skb->sk); |
1063 | struct netdev_queue *dev_queue; | ||
1057 | struct tcmsg *tcm = NLMSG_DATA(n); | 1064 | struct tcmsg *tcm = NLMSG_DATA(n); |
1058 | struct nlattr *tca[TCA_MAX + 1]; | 1065 | struct nlattr *tca[TCA_MAX + 1]; |
1059 | struct net_device *dev; | 1066 | struct net_device *dev; |
@@ -1091,6 +1098,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1091 | 1098 | ||
1092 | /* Step 1. Determine qdisc handle X:0 */ | 1099 | /* Step 1. Determine qdisc handle X:0 */ |
1093 | 1100 | ||
1101 | dev_queue = &dev->tx_queue; | ||
1094 | if (pid != TC_H_ROOT) { | 1102 | if (pid != TC_H_ROOT) { |
1095 | u32 qid1 = TC_H_MAJ(pid); | 1103 | u32 qid1 = TC_H_MAJ(pid); |
1096 | 1104 | ||
@@ -1101,7 +1109,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1101 | } else if (qid1) { | 1109 | } else if (qid1) { |
1102 | qid = qid1; | 1110 | qid = qid1; |
1103 | } else if (qid == 0) | 1111 | } else if (qid == 0) |
1104 | qid = dev->qdisc_sleeping->handle; | 1112 | qid = dev_queue->qdisc_sleeping->handle; |
1105 | 1113 | ||
1106 | /* Now qid is genuine qdisc handle consistent | 1114 | /* Now qid is genuine qdisc handle consistent |
1107 | both with parent and child. | 1115 | both with parent and child. |
@@ -1112,7 +1120,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1112 | pid = TC_H_MAKE(qid, pid); | 1120 | pid = TC_H_MAKE(qid, pid); |
1113 | } else { | 1121 | } else { |
1114 | if (qid == 0) | 1122 | if (qid == 0) |
1115 | qid = dev->qdisc_sleeping->handle; | 1123 | qid = dev_queue->qdisc_sleeping->handle; |
1116 | } | 1124 | } |
1117 | 1125 | ||
1118 | /* OK. Locate qdisc */ | 1126 | /* OK. Locate qdisc */ |
@@ -1248,6 +1256,7 @@ static int qdisc_class_dump(struct Qdisc *q, unsigned long cl, struct qdisc_walk | |||
1248 | static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) | 1256 | static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) |
1249 | { | 1257 | { |
1250 | struct net *net = sock_net(skb->sk); | 1258 | struct net *net = sock_net(skb->sk); |
1259 | struct netdev_queue *dev_queue; | ||
1251 | int t; | 1260 | int t; |
1252 | int s_t; | 1261 | int s_t; |
1253 | struct net_device *dev; | 1262 | struct net_device *dev; |
@@ -1266,7 +1275,8 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb) | |||
1266 | s_t = cb->args[0]; | 1275 | s_t = cb->args[0]; |
1267 | t = 0; | 1276 | t = 0; |
1268 | 1277 | ||
1269 | list_for_each_entry(q, &dev->qdisc_list, list) { | 1278 | dev_queue = &dev->tx_queue; |
1279 | list_for_each_entry(q, &dev_queue->qdisc_list, list) { | ||
1270 | if (t < s_t || !q->ops->cl_ops || | 1280 | if (t < s_t || !q->ops->cl_ops || |
1271 | (tcm->tcm_parent && | 1281 | (tcm->tcm_parent && |
1272 | TC_H_MAJ(tcm->tcm_parent) != q->handle)) { | 1282 | TC_H_MAJ(tcm->tcm_parent) != q->handle)) { |