|
@@ -29,6 +29,7 @@
|
|
#include <linux/hrtimer.h>
|
|
#include <linux/hrtimer.h>
|
|
#include <linux/lockdep.h>
|
|
#include <linux/lockdep.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/slab.h>
|
|
|
|
+#include <linux/hashtable.h>
|
|
|
|
|
|
#include <net/net_namespace.h>
|
|
#include <net/net_namespace.h>
|
|
#include <net/sock.h>
|
|
#include <net/sock.h>
|
|
@@ -263,33 +264,33 @@ static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
|
|
root->handle == handle)
|
|
root->handle == handle)
|
|
return root;
|
|
return root;
|
|
|
|
|
|
- list_for_each_entry_rcu(q, &root->list, list) {
|
|
|
|
|
|
+ hash_for_each_possible_rcu(qdisc_dev(root)->qdisc_hash, q, hash, handle) {
|
|
if (q->handle == handle)
|
|
if (q->handle == handle)
|
|
return q;
|
|
return q;
|
|
}
|
|
}
|
|
return NULL;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
|
|
-void qdisc_list_add(struct Qdisc *q)
|
|
|
|
|
|
+void qdisc_hash_add(struct Qdisc *q)
|
|
{
|
|
{
|
|
if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
|
|
if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
|
|
struct Qdisc *root = qdisc_dev(q)->qdisc;
|
|
struct Qdisc *root = qdisc_dev(q)->qdisc;
|
|
|
|
|
|
WARN_ON_ONCE(root == &noop_qdisc);
|
|
WARN_ON_ONCE(root == &noop_qdisc);
|
|
ASSERT_RTNL();
|
|
ASSERT_RTNL();
|
|
- list_add_tail_rcu(&q->list, &root->list);
|
|
|
|
|
|
+ hash_add_rcu(qdisc_dev(q)->qdisc_hash, &q->hash, q->handle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL(qdisc_list_add);
|
|
|
|
|
|
+EXPORT_SYMBOL(qdisc_hash_add);
|
|
|
|
|
|
-void qdisc_list_del(struct Qdisc *q)
|
|
|
|
|
|
+void qdisc_hash_del(struct Qdisc *q)
|
|
{
|
|
{
|
|
if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
|
|
if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
|
|
ASSERT_RTNL();
|
|
ASSERT_RTNL();
|
|
- list_del_rcu(&q->list);
|
|
|
|
|
|
+ hash_del_rcu(&q->hash);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL(qdisc_list_del);
|
|
|
|
|
|
+EXPORT_SYMBOL(qdisc_hash_del);
|
|
|
|
|
|
struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
|
|
struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
|
|
{
|
|
{
|
|
@@ -998,7 +999,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
|
|
goto err_out4;
|
|
goto err_out4;
|
|
}
|
|
}
|
|
|
|
|
|
- qdisc_list_add(sch);
|
|
|
|
|
|
+ qdisc_hash_add(sch);
|
|
|
|
|
|
return sch;
|
|
return sch;
|
|
}
|
|
}
|
|
@@ -1435,6 +1436,7 @@ static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
|
|
{
|
|
{
|
|
int ret = 0, q_idx = *q_idx_p;
|
|
int ret = 0, q_idx = *q_idx_p;
|
|
struct Qdisc *q;
|
|
struct Qdisc *q;
|
|
|
|
+ int b;
|
|
|
|
|
|
if (!root)
|
|
if (!root)
|
|
return 0;
|
|
return 0;
|
|
@@ -1449,7 +1451,7 @@ static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
|
|
goto done;
|
|
goto done;
|
|
q_idx++;
|
|
q_idx++;
|
|
}
|
|
}
|
|
- list_for_each_entry(q, &root->list, list) {
|
|
|
|
|
|
+ hash_for_each(qdisc_dev(root)->qdisc_hash, b, q, hash) {
|
|
if (q_idx < s_q_idx) {
|
|
if (q_idx < s_q_idx) {
|
|
q_idx++;
|
|
q_idx++;
|
|
continue;
|
|
continue;
|
|
@@ -1765,6 +1767,7 @@ static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb,
|
|
int *t_p, int s_t)
|
|
int *t_p, int s_t)
|
|
{
|
|
{
|
|
struct Qdisc *q;
|
|
struct Qdisc *q;
|
|
|
|
+ int b;
|
|
|
|
|
|
if (!root)
|
|
if (!root)
|
|
return 0;
|
|
return 0;
|
|
@@ -1772,7 +1775,7 @@ static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb,
|
|
if (tc_dump_tclass_qdisc(root, skb, tcm, cb, t_p, s_t) < 0)
|
|
if (tc_dump_tclass_qdisc(root, skb, tcm, cb, t_p, s_t) < 0)
|
|
return -1;
|
|
return -1;
|
|
|
|
|
|
- list_for_each_entry(q, &root->list, list) {
|
|
|
|
|
|
+ hash_for_each(qdisc_dev(root)->qdisc_hash, b, q, hash) {
|
|
if (tc_dump_tclass_qdisc(q, skb, tcm, cb, t_p, s_t) < 0)
|
|
if (tc_dump_tclass_qdisc(q, skb, tcm, cb, t_p, s_t) < 0)
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|