Messages in this thread Patch in this message | | | Date | Fri, 17 Dec 2010 18:01:15 +0800 | From | Lai Jiangshan <> | Subject | Re: [PATCH 3/3] plist: shrink plist_head |
| |
On 12/16/2010 06:23 PM, Lai Jiangshan wrote: > struct plist_head is too big, and the field prio_list > in the struct plist_head is used seldom. So it can be > removed and we use the first plist_node's prio_list > when needed. > > The size of struct rtmutex and struct task_struct will > also decreased after struct plist_head shrinked. > > Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> > --- > include/linux/plist.h | 47 ++++++++++++++++++++++--------------------- > lib/plist.c | 54 ++++++++++++++++++++++++++++++++------------------ > 2 files changed, 59 insertions(+), 42 deletions(-) > > diff --git a/include/linux/plist.h b/include/linux/plist.h > index 7254eda..c9b9f32 100644 > --- a/include/linux/plist.h > +++ b/include/linux/plist.h > @@ -31,15 +31,17 @@ > * > * Simple ASCII art explanation: > * > - * |HEAD | > - * | | > - * |prio_list.prev|<------------------------------------| > - * |prio_list.next|<->|pl|<->|pl|<--------------->|pl|<-| > - * |10 | |10| |21| |21| |21| |40| (prio) > - * | | | | | | | | | | | | > - * | | | | | | | | | | | | > - * |node_list.next|<->|nl|<->|nl|<->|nl|<->|nl|<->|nl|<-| > - * |node_list.prev|<------------------------------------| > + * pl:prio_list (only for plist_node) > + * nl:node_list > + * HEAD| NODE(S) > + * | > + * ||------------------------------------| > + * ||->|pl|<->|pl|<--------------->|pl|<-| > + * | |10| |21| |21| |21| |40| (prio) > + * | | | | | | | | | | | > + * | | | | | | | | | | | > + * |->|nl|<->|nl|<->|nl|<->|nl|<->|nl|<->|nl|<-| > + * |-------------------------------------------| > *
This is the test code for this new plist. After my careful review and the tests, I trust this plist.
Subject: [PATCH] plist: test for plist
Add test code for checking plist when kernel is booting.
Signed-off-by: Lai Jiangshan <laijs@cn.fujitsu.com> --- diff --git a/lib/plist.c b/lib/plist.c index 8c614d0..0ae7e64 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -28,6 +28,8 @@ #ifdef CONFIG_DEBUG_PI_LIST +static struct plist_head test_head; + static void plist_check_prev_next(struct list_head *t, struct list_head *p, struct list_head *n) { @@ -54,7 +56,7 @@ static void plist_check_list(struct list_head *top) static void plist_check_head(struct plist_head *head) { - WARN_ON(!head->rawlock && !head->spinlock); + WARN_ON(head != &test_head && !head->rawlock && !head->spinlock); if (head->rawlock) WARN_ON_SMP(!raw_spin_is_locked(head->rawlock)); if (head->spinlock) @@ -135,3 +137,80 @@ void plist_del(struct plist_node *node, struct plist_head *head) plist_check_head(head); } + +#ifdef CONFIG_DEBUG_PI_LIST +#include <linux/sched.h> +#include <linux/module.h> +#include <linux/init.h> + +static struct plist_node __initdata test_node[241]; + +static void __init plist_test_check(int nr_expect) +{ + struct plist_node *first, *prio_pos, *node_pos; + + if (plist_head_empty(&test_head)) { + BUG_ON(nr_expect != 0); + return; + } + + prio_pos = first = plist_first(&test_head); + plist_for_each(node_pos, &test_head) { + if (nr_expect-- < 0) + break; + if (node_pos == first) + continue; + if (node_pos->prio == prio_pos->prio) { + BUG_ON(!list_empty(&node_pos->prio_list)); + continue; + } + + BUG_ON(prio_pos->prio > node_pos->prio); + BUG_ON(prio_pos->prio_list.next != &node_pos->prio_list); + prio_pos = node_pos; + } + + BUG_ON(nr_expect != 0); + BUG_ON(prio_pos->prio_list.next != &first->prio_list); +} + +static int __init plist_test(void) +{ + int nr_expect = 0, i, loop; + unsigned int r = local_clock(); + + printk(KERN_INFO "start plist test\n"); + plist_head_init(&test_head, NULL); + for (i = 0; i < ARRAY_SIZE(test_node); i++) + plist_node_init(test_node + i, 0); + + for (loop = 0; loop < 1000; loop++) { + r = r * 193939 % 47629; + i = r % ARRAY_SIZE(test_node); + if (plist_node_empty(test_node + i)) { + r = r * 193939 % 47629; + test_node[i].prio = r % 99; + plist_add(test_node + i, &test_head); + nr_expect++; + } else { + plist_del(test_node + i, &test_head); + nr_expect--; + } + plist_test_check(nr_expect); + } + + for (i = 0; i < ARRAY_SIZE(test_node); i++) { + if (plist_node_empty(test_node + i)) + continue; + plist_del(test_node + i, &test_head); + nr_expect--; + plist_test_check(nr_expect); + } + + printk(KERN_INFO "end plist test\n"); + return 0; +} + +module_init(plist_test); + +#endif
| |