Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Artem Bityutskiy and committed by
Linus Torvalds
f3dc0e38 eeee9ebb

+38 -27
+38 -27
lib/list_sort.c
··· 165 165 166 166 static int __init list_sort_test(void) 167 167 { 168 - int i, count; 169 - struct list_head *head = kmalloc(sizeof(*head), GFP_KERNEL); 170 - struct list_head *cur; 168 + int i, count = 1, err = -EINVAL; 169 + struct debug_el *el; 170 + struct list_head *cur, *tmp; 171 + LIST_HEAD(head); 171 172 172 173 printk(KERN_DEBUG "testing list_sort()\n"); 173 174 174 - cur = head; 175 175 for (i = 0; i < TEST_LIST_LEN; i++) { 176 - struct debug_el *el = kmalloc(sizeof(*el), GFP_KERNEL); 177 - BUG_ON(!el); 176 + el = kmalloc(sizeof(*el), GFP_KERNEL); 177 + if (!el) { 178 + printk(KERN_ERR "cancel list_sort() testing - cannot " 179 + "allocate memory\n"); 180 + goto exit; 181 + } 178 182 /* force some equivalencies */ 179 183 el->value = random32() % (TEST_LIST_LEN/3); 180 184 el->serial = i; 181 - 182 - el->list.prev = cur; 183 - cur->next = &el->list; 184 - cur = cur->next; 185 + list_add_tail(&el->list, &head); 185 186 } 186 - head->prev = cur; 187 187 188 - list_sort(NULL, head, cmp); 188 + list_sort(NULL, &head, cmp); 189 189 190 - count = 1; 191 - for (cur = head->next; cur->next != head; cur = cur->next) { 192 - struct debug_el *el = container_of(cur, struct debug_el, list); 193 - int cmp_result = cmp(NULL, cur, cur->next); 190 + for (cur = head.next; cur->next != &head; cur = cur->next) { 191 + struct debug_el *el1; 192 + int cmp_result; 193 + 194 194 if (cur->next->prev != cur) { 195 195 printk(KERN_ERR "list_sort() returned " 196 196 "a corrupted list!\n"); 197 - return 1; 198 - } else if (cmp_result > 0) { 197 + goto exit; 198 + } 199 + 200 + cmp_result = cmp(NULL, cur, cur->next); 201 + if (cmp_result > 0) { 199 202 printk(KERN_ERR "list_sort() failed to sort!\n"); 200 - return 1; 201 - } else if (cmp_result == 0 && 202 - el->serial >= container_of(cur->next, 203 - struct debug_el, list)->serial) { 203 + goto exit; 204 + } 205 + 206 + el = container_of(cur, struct debug_el, list); 207 + el1 = container_of(cur->next, struct debug_el, list); 208 + if (cmp_result == 0 && el->serial >= el1->serial) { 204 209 printk(KERN_ERR "list_sort() failed to preserve order " 205 210 "of equivalent elements!\n"); 206 - return 1; 211 + goto exit; 207 212 } 208 - kfree(cur->prev); 209 213 count++; 210 214 } 211 - kfree(cur); 215 + 212 216 if (count != TEST_LIST_LEN) { 213 217 printk(KERN_ERR "list_sort() returned list of " 214 218 "different length!\n"); 215 - return 1; 219 + goto exit; 216 220 } 217 - return 0; 221 + 222 + err = 0; 223 + exit: 224 + list_for_each_safe(cur, tmp, &head) { 225 + list_del(cur); 226 + kfree(container_of(cur, struct debug_el, list)); 227 + } 228 + return err; 218 229 } 219 230 module_init(list_sort_test); 220 231 #endif /* CONFIG_TEST_LIST_SORT */