aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2010-10-26 17:23:08 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-26 19:52:19 -0400
commit041b78f232bb87b2de8ca3fed50384bc7dc9c2de (patch)
treeca76ca89b76360f9fbc5987519d6cf0c8c53cdda /lib
parent014afa943d44f0df8e65bc4bd071c67772277d93 (diff)
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>
Diffstat (limited to 'lib')
-rw-r--r--lib/list_sort.c75
1 files changed, 67 insertions, 8 deletions
diff --git a/lib/list_sort.c b/lib/list_sort.c
index 01aff9e80821..d7325c6b103f 100644
--- a/lib/list_sort.c
+++ b/lib/list_sort.c
@@ -145,23 +145,65 @@ EXPORT_SYMBOL(list_sort);
145 145
146#include <linux/random.h> 146#include <linux/random.h>
147 147
148/*
149 * The pattern of set bits in the list length determines which cases
150 * are hit in list_sort().
151 */
152#define TEST_LIST_LEN (512+128+2) /* not including head */
153
154#define TEST_POISON1 0xDEADBEEF
155#define TEST_POISON2 0xA324354C
156
148struct debug_el { 157struct debug_el {
158 unsigned int poison1;
149 struct list_head list; 159 struct list_head list;
160 unsigned int poison2;
150 int value; 161 int value;
151 unsigned serial; 162 unsigned serial;
152}; 163};
153 164
154static int cmp(void *priv, struct list_head *a, struct list_head *b) 165/* Array, containing pointers to all elements in the test list */
166static struct debug_el **elts __initdata;
167
168static int __init check(struct debug_el *ela, struct debug_el *elb)
155{ 169{
156 return container_of(a, struct debug_el, list)->value 170 if (ela->serial >= TEST_LIST_LEN) {
157 - container_of(b, struct debug_el, list)->value; 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;
158} 195}
159 196
160/* 197static int __init cmp(void *priv, struct list_head *a, struct list_head *b)
161 * The pattern of set bits in the list length determines which cases 198{
162 * are hit in list_sort(). 199 struct debug_el *ela, *elb;
163 */ 200
164#define TEST_LIST_LEN (512+128+2) /* not including head */ 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
166static int __init list_sort_test(void) 208static int __init list_sort_test(void)
167{ 209{
@@ -172,6 +214,13 @@ static int __init list_sort_test(void)
172 214
173 printk(KERN_DEBUG "list_sort_test: start testing list_sort()\n"); 215 printk(KERN_DEBUG "list_sort_test: start testing list_sort()\n");
174 216
217 elts = kmalloc(sizeof(void *) * TEST_LIST_LEN, GFP_KERNEL);
218 if (!elts) {
219 printk(KERN_ERR "list_sort_test: error: cannot allocate "
220 "memory\n");
221 goto exit;
222 }
223
175 for (i = 0; i < TEST_LIST_LEN; i++) { 224 for (i = 0; i < TEST_LIST_LEN; i++) {
176 el = kmalloc(sizeof(*el), GFP_KERNEL); 225 el = kmalloc(sizeof(*el), GFP_KERNEL);
177 if (!el) { 226 if (!el) {
@@ -182,6 +231,9 @@ static int __init list_sort_test(void)
182 /* force some equivalencies */ 231 /* force some equivalencies */
183 el->value = random32() % (TEST_LIST_LEN/3); 232 el->value = random32() % (TEST_LIST_LEN/3);
184 el->serial = i; 233 el->serial = i;
234 el->poison1 = TEST_POISON1;
235 el->poison2 = TEST_POISON2;
236 elts[i] = el;
185 list_add_tail(&el->list, &head); 237 list_add_tail(&el->list, &head);
186 } 238 }
187 239
@@ -211,6 +263,12 @@ static int __init list_sort_test(void)
211 "equivalent elements not preserved\n"); 263 "equivalent elements not preserved\n");
212 goto exit; 264 goto exit;
213 } 265 }
266
267 if (check(el, el1)) {
268 printk(KERN_ERR "list_sort_test: error: element check "
269 "failed\n");
270 goto exit;
271 }
214 count++; 272 count++;
215 } 273 }
216 274
@@ -222,6 +280,7 @@ static int __init list_sort_test(void)
222 280
223 err = 0; 281 err = 0;
224exit: 282exit:
283 kfree(elts);
225 list_for_each_safe(cur, tmp, &head) { 284 list_for_each_safe(cur, tmp, &head) {
226 list_del(cur); 285 list_del(cur);
227 kfree(container_of(cur, struct debug_el, list)); 286 kfree(container_of(cur, struct debug_el, list));