summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-10-26 14:23:07 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-26 16:52:19 -0700
commitf3dc0e384248ea6fda0987f909007fa9ab5fb51a (patch)
tree1c834baf780e16a9e47d1cacd41498dbb361483a
parenteeee9ebb54b76a33a13d2c926ffb018a4aea410f (diff)
lib/list_sort: test: improve errors handling
The 'lib_sort()' test does not free memory if it fails, and it makes the kernel panic if it cannot allocate memory. This patch fixes the problem. This patch also changes several small things: o use 'list_add()' helper instead of adding manually o introduce temporary 'el1' variable to avoid ugly and unreadalbe "if" statement o make 'head' to be stack variable instead of 'kmalloc()'ed, which simplifies code a bit Overall, this patch is of clean-up type. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Cc: Don Mullis <don.mullis@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--lib/list_sort.c65
1 files changed, 38 insertions, 27 deletions
diff --git a/lib/list_sort.c b/lib/list_sort.c
index 8f3c24415ae5..2b99ff80f4be 100644
--- a/lib/list_sort.c
+++ b/lib/list_sort.c
@@ -165,56 +165,67 @@ static int cmp(void *priv, struct list_head *a, struct list_head *b)
static int __init list_sort_test(void)
{
- int i, count;
- struct list_head *head = kmalloc(sizeof(*head), GFP_KERNEL);
- struct list_head *cur;
+ int i, count = 1, err = -EINVAL;
+ struct debug_el *el;
+ struct list_head *cur, *tmp;
+ LIST_HEAD(head);
printk(KERN_DEBUG "testing list_sort()\n");
- cur = head;
for (i = 0; i < TEST_LIST_LEN; i++) {
- struct debug_el *el = kmalloc(sizeof(*el), GFP_KERNEL);
- BUG_ON(!el);
+ el = kmalloc(sizeof(*el), GFP_KERNEL);
+ if (!el) {
+ printk(KERN_ERR "cancel list_sort() testing - cannot "
+ "allocate memory\n");
+ goto exit;
+ }
/* force some equivalencies */
el->value = random32() % (TEST_LIST_LEN/3);
el->serial = i;
-
- el->list.prev = cur;
- cur->next = &el->list;
- cur = cur->next;
+ list_add_tail(&el->list, &head);
}
- head->prev = cur;
- list_sort(NULL, head, cmp);
+ list_sort(NULL, &head, cmp);
+
+ for (cur = head.next; cur->next != &head; cur = cur->next) {
+ struct debug_el *el1;
+ int cmp_result;
- count = 1;
- for (cur = head->next; cur->next != head; cur = cur->next) {
- struct debug_el *el = container_of(cur, struct debug_el, list);
- int cmp_result = cmp(NULL, cur, cur->next);
if (cur->next->prev != cur) {
printk(KERN_ERR "list_sort() returned "
"a corrupted list!\n");
- return 1;
- } else if (cmp_result > 0) {
+ goto exit;
+ }
+
+ cmp_result = cmp(NULL, cur, cur->next);
+ if (cmp_result > 0) {
printk(KERN_ERR "list_sort() failed to sort!\n");
- return 1;
- } else if (cmp_result == 0 &&
- el->serial >= container_of(cur->next,
- struct debug_el, list)->serial) {
+ goto exit;
+ }
+
+ el = container_of(cur, struct debug_el, list);
+ el1 = container_of(cur->next, struct debug_el, list);
+ if (cmp_result == 0 && el->serial >= el1->serial) {
printk(KERN_ERR "list_sort() failed to preserve order "
"of equivalent elements!\n");
- return 1;
+ goto exit;
}
- kfree(cur->prev);
count++;
}
- kfree(cur);
+
if (count != TEST_LIST_LEN) {
printk(KERN_ERR "list_sort() returned list of "
"different length!\n");
- return 1;
+ goto exit;
+ }
+
+ err = 0;
+exit:
+ list_for_each_safe(cur, tmp, &head) {
+ list_del(cur);
+ kfree(container_of(cur, struct debug_el, list));
}
- return 0;
+ return err;
}
module_init(list_sort_test);
#endif /* CONFIG_TEST_LIST_SORT */