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

lib/list_sort: test: check element addresses

Improve 'lib_sort()' test and check that:
o 'cmp()' is called only for elements which were present in the original list,
i.e., the 'a' and 'b' parameters are valid
o the resulted (sorted) list consists onlly of the original elements
o intdoruce "poison" fields to make sure data around 'struc list_head' field
are not corrupted.

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
041b78f2 014afa94

+71 -12
+71 -12
lib/list_sort.c
··· 145 145 146 146 #include <linux/random.h> 147 147 148 - struct debug_el { 149 - struct list_head list; 150 - int value; 151 - unsigned serial; 152 - }; 153 - 154 - static int cmp(void *priv, struct list_head *a, struct list_head *b) 155 - { 156 - return container_of(a, struct debug_el, list)->value 157 - - container_of(b, struct debug_el, list)->value; 158 - } 159 - 160 148 /* 161 149 * The pattern of set bits in the list length determines which cases 162 150 * are hit in list_sort(). 163 151 */ 164 152 #define TEST_LIST_LEN (512+128+2) /* not including head */ 153 + 154 + #define TEST_POISON1 0xDEADBEEF 155 + #define TEST_POISON2 0xA324354C 156 + 157 + struct debug_el { 158 + unsigned int poison1; 159 + struct list_head list; 160 + unsigned int poison2; 161 + int value; 162 + unsigned serial; 163 + }; 164 + 165 + /* Array, containing pointers to all elements in the test list */ 166 + static struct debug_el **elts __initdata; 167 + 168 + static int __init check(struct debug_el *ela, struct debug_el *elb) 169 + { 170 + if (ela->serial >= TEST_LIST_LEN) { 171 + printk(KERN_ERR "list_sort_test: error: incorrect serial %d\n", 172 + ela->serial); 173 + return -EINVAL; 174 + } 175 + if (elb->serial >= TEST_LIST_LEN) { 176 + printk(KERN_ERR "list_sort_test: error: incorrect serial %d\n", 177 + elb->serial); 178 + return -EINVAL; 179 + } 180 + if (elts[ela->serial] != ela || elts[elb->serial] != elb) { 181 + printk(KERN_ERR "list_sort_test: error: phantom element\n"); 182 + return -EINVAL; 183 + } 184 + if (ela->poison1 != TEST_POISON1 || ela->poison2 != TEST_POISON2) { 185 + printk(KERN_ERR "list_sort_test: error: bad poison: %#x/%#x\n", 186 + ela->poison1, ela->poison2); 187 + return -EINVAL; 188 + } 189 + if (elb->poison1 != TEST_POISON1 || elb->poison2 != TEST_POISON2) { 190 + printk(KERN_ERR "list_sort_test: error: bad poison: %#x/%#x\n", 191 + elb->poison1, elb->poison2); 192 + return -EINVAL; 193 + } 194 + return 0; 195 + } 196 + 197 + static int __init cmp(void *priv, struct list_head *a, struct list_head *b) 198 + { 199 + struct debug_el *ela, *elb; 200 + 201 + ela = container_of(a, struct debug_el, list); 202 + elb = container_of(b, struct debug_el, list); 203 + 204 + check(ela, elb); 205 + return ela->value - elb->value; 206 + } 165 207 166 208 static int __init list_sort_test(void) 167 209 { ··· 213 171 LIST_HEAD(head); 214 172 215 173 printk(KERN_DEBUG "list_sort_test: start testing list_sort()\n"); 174 + 175 + elts = kmalloc(sizeof(void *) * TEST_LIST_LEN, GFP_KERNEL); 176 + if (!elts) { 177 + printk(KERN_ERR "list_sort_test: error: cannot allocate " 178 + "memory\n"); 179 + goto exit; 180 + } 216 181 217 182 for (i = 0; i < TEST_LIST_LEN; i++) { 218 183 el = kmalloc(sizeof(*el), GFP_KERNEL); ··· 231 182 /* force some equivalencies */ 232 183 el->value = random32() % (TEST_LIST_LEN/3); 233 184 el->serial = i; 185 + el->poison1 = TEST_POISON1; 186 + el->poison2 = TEST_POISON2; 187 + elts[i] = el; 234 188 list_add_tail(&el->list, &head); 235 189 } 236 190 ··· 263 211 "equivalent elements not preserved\n"); 264 212 goto exit; 265 213 } 214 + 215 + if (check(el, el1)) { 216 + printk(KERN_ERR "list_sort_test: error: element check " 217 + "failed\n"); 218 + goto exit; 219 + } 266 220 count++; 267 221 } 268 222 ··· 280 222 281 223 err = 0; 282 224 exit: 225 + kfree(elts); 283 226 list_for_each_safe(cur, tmp, &head) { 284 227 list_del(cur); 285 228 kfree(container_of(cur, struct debug_el, list));