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 | } |
