From: Jarek Poplawski <jarkao2@gmail.com>
To: Patrick McHardy <kaber@trash.net>
Cc: netdev@vger.kernel.org, devik@cdi.cz
Subject: Re: net-sched 01/05: add dynamically sized qdisc class hash helpers
Date: Thu, 3 Jul 2008 14:18:24 +0200 [thread overview]
Message-ID: <20080703121824.GA2559@ami.dom.local> (raw)
In-Reply-To: <20080701143411.26309.41549.sendpatchset@localhost.localdomain>
A few tiny doubts below...
Patrick McHardy wrote, On 07/01/2008 04:34 PM:
> net-sched: add dynamically sized qdisc class hash helpers
>
> Signed-off-by: Patrick McHardy <kaber@trash.net>
>
> ---
> commit fe2579f858479ce266763ba861c87cd0371389af
> tree fe574771047ca02df76c7ec07d70b9402278531a
> parent 98cd24a4b3ac9ba234631803a05f96c3fddb500b
> author Patrick McHardy <kaber@trash.net> Tue, 01 Jul 2008 14:02:55 +0200
> committer Patrick McHardy <kaber@trash.net> Tue, 01 Jul 2008 14:02:55 +0200
>
> include/net/sch_generic.h | 41 ++++++++++++++++++
> net/sched/sch_api.c | 104 +++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 145 insertions(+), 0 deletions(-)
>
> diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
> index a87fc03..0541d3c 100644
> --- a/include/net/sch_generic.h
> +++ b/include/net/sch_generic.h
> @@ -167,6 +167,47 @@ extern void qdisc_unlock_tree(struct net_device *dev);
> extern struct Qdisc noop_qdisc;
> extern struct Qdisc_ops noop_qdisc_ops;
>
> +struct Qdisc_class_common
> +{
> + u32 classid;
> + struct hlist_node hnode;
> +};
> +
> +struct Qdisc_class_hash
> +{
> + struct hlist_head *hash;
> + unsigned int hashsize;
> + unsigned int hashmask;
? u32 hashmask;
> + unsigned int hashelems;
> +};
> +
> +static inline unsigned int qdisc_class_hash(u32 id, u32 mask)
> +{
> + id ^= id >> 8;
> + id ^= id >> 4;
> + return id & mask;
> +}
> +
> +static inline void *qdisc_class_find(struct Qdisc_class_hash *hash, u32 id)
Why not Qdisc_class_common *?
> +{
> + struct Qdisc_class_common *cl;
> + struct hlist_node *n;
> + unsigned int h;
> +
> + h = qdisc_class_hash(id, hash->hashmask);
> + hlist_for_each_entry(cl, n, &hash->hash[h], hnode) {
> + if (cl->classid == id)
> + return cl;
> + }
> + return NULL;
> +}
> +
> +extern int qdisc_class_hash_init(struct Qdisc_class_hash *);
> +extern void qdisc_class_hash_insert(struct Qdisc_class_hash *, struct Qdisc_class_common *);
> +extern void qdisc_class_hash_remove(struct Qdisc_class_hash *, struct Qdisc_class_common *);
> +extern void qdisc_class_hash_grow(struct Qdisc *, struct Qdisc_class_hash *);
> +extern void qdisc_class_hash_destroy(struct Qdisc_class_hash *);
> +
> extern void dev_init_scheduler(struct net_device *dev);
> extern void dev_shutdown(struct net_device *dev);
> extern void dev_activate(struct net_device *dev);
> diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> index 10f01ad..e9ebc7a 100644
> --- a/net/sched/sch_api.c
> +++ b/net/sched/sch_api.c
> @@ -316,6 +316,110 @@ void qdisc_watchdog_cancel(struct qdisc_watchdog *wd)
> }
> EXPORT_SYMBOL(qdisc_watchdog_cancel);
>
> +struct hlist_head *qdisc_class_hash_alloc(unsigned int n)
> +{
> + unsigned int size = n * sizeof(struct hlist_head), i;
> + struct hlist_head *h;
> +
> + if (size <= PAGE_SIZE)
> + h = kmalloc(size, GFP_KERNEL);
> + else
> + h = (struct hlist_head *)
> + __get_free_pages(GFP_KERNEL, get_order(size));
> +
> + if (h != NULL) {
> + for (i = 0; i < n; i++)
> + INIT_HLIST_HEAD(&h[i]);
> + }
> + return h;
> +}
> +
> +static void qdisc_class_hash_free(struct hlist_head *h, unsigned int n)
> +{
> + unsigned int size = n * sizeof(struct hlist_head);
> +
> + if (size <= PAGE_SIZE)
> + kfree(h);
> + else
> + free_pages((unsigned long)h, get_order(size));
> +}
> +
> +void qdisc_class_hash_grow(struct Qdisc *sch, struct Qdisc_class_hash *clhash)
> +{
> + struct Qdisc_class_common *cl;
> + struct hlist_node *n, *next;
> + struct hlist_head *nhash, *ohash;
> + unsigned int nsize, nmask, osize;
> + unsigned int i, h;
> +
> + /* Rehash when load factor exceeds 0.75 */
> + if (clhash->hashelems * 4 <= clhash->hashsize * 3)
With current init hashsize == 4 this will trigger after adding: 4th,
7th, 13th,... class. Maybe we could start with something higher?
> + return;
> + nsize = clhash->hashsize * 2;
> + nmask = nsize - 1;
> + nhash = qdisc_class_hash_alloc(nsize);
> + if (nhash == NULL)
> + return;
> +
> + ohash = clhash->hash;
> + osize = clhash->hashsize;
> +
> + sch_tree_lock(sch);
> + for (i = 0; i < osize; i++) {
> + hlist_for_each_entry_safe(cl, n, next, &ohash[i], hnode) {
> + h = qdisc_class_hash(cl->classid, nmask);
> + hlist_add_head(&cl->hnode, &nhash[h]);
With a large number of classes and changes this could probably give
noticable delays, so maybe there would be reasonable to add a
possibility of user defined, ungrowable hashsize as well?
Otherwise, it looks very nice to me.
Thanks,
Jarek P.
> + }
> + }
> + clhash->hash = nhash;
> + clhash->hashsize = nsize;
> + clhash->hashmask = nmask;
> + sch_tree_unlock(sch);
> +
> + qdisc_class_hash_free(ohash, osize);
> +}
> +EXPORT_SYMBOL(qdisc_class_hash_grow);
> +
> +int qdisc_class_hash_init(struct Qdisc_class_hash *clhash)
> +{
> + unsigned int size = 4;
> +
> + clhash->hash = qdisc_class_hash_alloc(size);
> + if (clhash->hash == NULL)
> + return -ENOMEM;
> + clhash->hashsize = size;
> + clhash->hashmask = size - 1;
> + clhash->hashelems = 0;
> + return 0;
> +}
> +EXPORT_SYMBOL(qdisc_class_hash_init);
> +
> +void qdisc_class_hash_destroy(struct Qdisc_class_hash *clhash)
> +{
> + qdisc_class_hash_free(clhash->hash, clhash->hashsize);
> +}
> +EXPORT_SYMBOL(qdisc_class_hash_destroy);
> +
> +void qdisc_class_hash_insert(struct Qdisc_class_hash *clhash,
> + struct Qdisc_class_common *cl)
> +{
> + unsigned int h;
> +
> + INIT_HLIST_NODE(&cl->hnode);
> + h = qdisc_class_hash(cl->classid, clhash->hashmask);
> + hlist_add_head(&cl->hnode, &clhash->hash[h]);
> + clhash->hashelems++;
> +}
> +EXPORT_SYMBOL(qdisc_class_hash_insert);
> +
> +void qdisc_class_hash_remove(struct Qdisc_class_hash *clhash,
> + struct Qdisc_class_common *cl)
> +{
> + hlist_del(&cl->hnode);
> + clhash->hashelems--;
> +}
> +EXPORT_SYMBOL(qdisc_class_hash_remove);
> +
> /* Allocate an unique handle from space managed by kernel */
>
> static u32 qdisc_alloc_handle(struct net_device *dev)
next prev parent reply other threads:[~2008-07-03 12:18 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-07-01 14:34 [RFC]: net-sched 00/05: dynamically sized class hashes Patrick McHardy
2008-07-01 14:34 ` net-sched 01/05: add dynamically sized qdisc class hash helpers Patrick McHardy
2008-07-03 12:18 ` Jarek Poplawski [this message]
2008-07-03 12:16 ` Patrick McHardy
2008-07-01 14:34 ` net-sched 02/05: sch_hfsc: use dynamic " Patrick McHardy
2008-07-01 14:34 ` net-sched 03/05: sch_cbq: " Patrick McHardy
2008-07-01 14:34 ` net-sched 04/05: sch_htb: move hash and sibling list removal to htb_delete Patrick McHardy
2008-07-02 8:15 ` Jarek Poplawski
2008-07-02 10:11 ` Patrick McHardy
2008-07-02 12:16 ` Jarek Poplawski
2008-07-02 12:25 ` Patrick McHardy
2008-07-02 21:14 ` Jarek Poplawski
2008-07-03 11:53 ` Patrick McHardy
2008-07-01 14:34 ` net-sched 05/05: sch_htb: use dynamic class hash helpers Patrick McHardy
2008-07-02 21:31 ` Jarek Poplawski
2008-07-03 11:55 ` Patrick McHardy
2008-07-02 2:50 ` [RFC]: net-sched 00/05: dynamically sized class hashes David Miller
2008-07-02 6:54 ` Martin Devera
2008-07-02 10:13 ` Patrick McHardy
2008-07-02 14:21 ` Patrick McHardy
2008-07-02 14:27 ` Martin Devera
2008-07-02 14:30 ` Patrick McHardy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080703121824.GA2559@ami.dom.local \
--to=jarkao2@gmail.com \
--cc=devik@cdi.cz \
--cc=kaber@trash.net \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.