diff options
author | Steven Rostedt <rostedt@goodmis.org> | 2008-09-29 23:02:40 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-14 04:38:56 -0400 |
commit | ed56829cb3195de499f97fa6108fe9134319bae6 (patch) | |
tree | e038bfb9898146dead5a20d2a1ffb44f8fb24676 /kernel | |
parent | a7b1374333407f409cf8df7e623b12490f073c84 (diff) |
ring_buffer: reset buffer page when freeing
Mathieu Desnoyers pointed out that the freeing of the page frame needs
to be reset otherwise we might trigger BUG_ON in the page free code.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/trace/ring_buffer.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 95ca9338cb6c..cfa711374d9a 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -128,6 +128,17 @@ struct buffer_page { | |||
128 | }; | 128 | }; |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * Also stolen from mm/slob.c. Thanks to Mathieu Desnoyers for pointing | ||
132 | * this issue out. | ||
133 | */ | ||
134 | static inline void free_buffer_page(struct buffer_page *bpage) | ||
135 | { | ||
136 | reset_page_mapcount(&bpage->page); | ||
137 | bpage->page.mapping = NULL; | ||
138 | __free_page(&bpage->page); | ||
139 | } | ||
140 | |||
141 | /* | ||
131 | * We need to fit the time_stamp delta into 27 bits. | 142 | * We need to fit the time_stamp delta into 27 bits. |
132 | */ | 143 | */ |
133 | static inline int test_time_stamp(u64 delta) | 144 | static inline int test_time_stamp(u64 delta) |
@@ -240,7 +251,7 @@ static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, | |||
240 | free_pages: | 251 | free_pages: |
241 | list_for_each_entry_safe(page, tmp, &pages, list) { | 252 | list_for_each_entry_safe(page, tmp, &pages, list) { |
242 | list_del_init(&page->list); | 253 | list_del_init(&page->list); |
243 | __free_page(&page->page); | 254 | free_buffer_page(page); |
244 | } | 255 | } |
245 | return -ENOMEM; | 256 | return -ENOMEM; |
246 | } | 257 | } |
@@ -284,7 +295,7 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer) | |||
284 | 295 | ||
285 | list_for_each_entry_safe(page, tmp, head, list) { | 296 | list_for_each_entry_safe(page, tmp, head, list) { |
286 | list_del_init(&page->list); | 297 | list_del_init(&page->list); |
287 | __free_page(&page->page); | 298 | free_buffer_page(page); |
288 | } | 299 | } |
289 | kfree(cpu_buffer); | 300 | kfree(cpu_buffer); |
290 | } | 301 | } |
@@ -393,7 +404,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned nr_pages) | |||
393 | p = cpu_buffer->pages.next; | 404 | p = cpu_buffer->pages.next; |
394 | page = list_entry(p, struct buffer_page, list); | 405 | page = list_entry(p, struct buffer_page, list); |
395 | list_del_init(&page->list); | 406 | list_del_init(&page->list); |
396 | __free_page(&page->page); | 407 | free_buffer_page(page); |
397 | } | 408 | } |
398 | BUG_ON(list_empty(&cpu_buffer->pages)); | 409 | BUG_ON(list_empty(&cpu_buffer->pages)); |
399 | 410 | ||
@@ -520,7 +531,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) | |||
520 | free_pages: | 531 | free_pages: |
521 | list_for_each_entry_safe(page, tmp, &pages, list) { | 532 | list_for_each_entry_safe(page, tmp, &pages, list) { |
522 | list_del_init(&page->list); | 533 | list_del_init(&page->list); |
523 | __free_page(&page->page); | 534 | free_buffer_page(page); |
524 | } | 535 | } |
525 | return -ENOMEM; | 536 | return -ENOMEM; |
526 | } | 537 | } |