aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/sch_generic.h
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-07-06 02:21:31 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-06 02:21:31 -0400
commit6fe1c7a5556807e9d7154a2d2fb938d8a9e47e5f (patch)
tree27758ea169b402aba70ef68bde8e554e7f135031 /include/net/sch_generic.h
parentea2aca084ba82aaf7c148d04914ceed8758ce08a (diff)
net-sched: add dynamically sized qdisc class hash helpers
Currently all qdiscs which allow to create classes uses a fixed sized hash table with size 16 to hash the classes. This causes a large bottleneck when using thousands of classes and unbound filters. Add helpers for dynamically sized class hashes to fix this. The following patches will convert the qdiscs to use them. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/sch_generic.h')
-rw-r--r--include/net/sch_generic.h42
1 files changed, 42 insertions, 0 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index a87fc0312edc..073f2580b83b 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -167,6 +167,48 @@ extern void qdisc_unlock_tree(struct net_device *dev);
167extern struct Qdisc noop_qdisc; 167extern struct Qdisc noop_qdisc;
168extern struct Qdisc_ops noop_qdisc_ops; 168extern struct Qdisc_ops noop_qdisc_ops;
169 169
170struct Qdisc_class_common
171{
172 u32 classid;
173 struct hlist_node hnode;
174};
175
176struct Qdisc_class_hash
177{
178 struct hlist_head *hash;
179 unsigned int hashsize;
180 unsigned int hashmask;
181 unsigned int hashelems;
182};
183
184static inline unsigned int qdisc_class_hash(u32 id, u32 mask)
185{
186 id ^= id >> 8;
187 id ^= id >> 4;
188 return id & mask;
189}
190
191static inline struct Qdisc_class_common *
192qdisc_class_find(struct Qdisc_class_hash *hash, u32 id)
193{
194 struct Qdisc_class_common *cl;
195 struct hlist_node *n;
196 unsigned int h;
197
198 h = qdisc_class_hash(id, hash->hashmask);
199 hlist_for_each_entry(cl, n, &hash->hash[h], hnode) {
200 if (cl->classid == id)
201 return cl;
202 }
203 return NULL;
204}
205
206extern int qdisc_class_hash_init(struct Qdisc_class_hash *);
207extern void qdisc_class_hash_insert(struct Qdisc_class_hash *, struct Qdisc_class_common *);
208extern void qdisc_class_hash_remove(struct Qdisc_class_hash *, struct Qdisc_class_common *);
209extern void qdisc_class_hash_grow(struct Qdisc *, struct Qdisc_class_hash *);
210extern void qdisc_class_hash_destroy(struct Qdisc_class_hash *);
211
170extern void dev_init_scheduler(struct net_device *dev); 212extern void dev_init_scheduler(struct net_device *dev);
171extern void dev_shutdown(struct net_device *dev); 213extern void dev_shutdown(struct net_device *dev);
172extern void dev_activate(struct net_device *dev); 214extern void dev_activate(struct net_device *dev);