Re: [PATCH 3/3] plist: shrink plist_head

From: Lai Jiangshan
Date: Fri Dec 17 2010 - 05:00:24 EST


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@xxxxxxxxxxxxxx>
> ---
> 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@xxxxxxxxxxxxxx>
---
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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/