diff options
| author | Vaibhav Nagarnaik <vnagarnaik@google.com> | 2012-02-02 15:00:41 -0500 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2012-04-23 21:17:51 -0400 |
| commit | 438ced1720b584000a9e8a4349d1f6bb7ee3ad6d (patch) | |
| tree | 2c769e58411c68b298ab816c577ecb2119c7067c /kernel/trace | |
| parent | 5a26c8f0cf1e95106858bb4e23ca6dd14c9b842f (diff) | |
ring-buffer: Add per_cpu ring buffer control files
Add a debugfs entry under per_cpu/ folder for each cpu called
buffer_size_kb to control the ring buffer size for each CPU
independently.
If the global file buffer_size_kb is used to set size, the individual
ring buffers will be adjusted to the given size. The buffer_size_kb will
report the common size to maintain backward compatibility.
If the buffer_size_kb file under the per_cpu/ directory is used to
change buffer size for a specific CPU, only the size of the respective
ring buffer is updated. When tracing/buffer_size_kb is read, it reports
'X' to indicate that sizes of per_cpu ring buffers are not equivalent.
Link: http://lkml.kernel.org/r/1328212844-11889-1-git-send-email-vnagarnaik@google.com
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Michael Rubin <mrubin@google.com>
Cc: David Sharp <dhsharp@google.com>
Cc: Justin Teravest <teravest@google.com>
Signed-off-by: Vaibhav Nagarnaik <vnagarnaik@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
| -rw-r--r-- | kernel/trace/ring_buffer.c | 248 | ||||
| -rw-r--r-- | kernel/trace/trace.c | 190 | ||||
| -rw-r--r-- | kernel/trace/trace.h | 2 |
3 files changed, 293 insertions, 147 deletions
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index cf8d11e91efd..2d5eb3320827 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
| @@ -449,6 +449,7 @@ struct ring_buffer_per_cpu { | |||
| 449 | raw_spinlock_t reader_lock; /* serialize readers */ | 449 | raw_spinlock_t reader_lock; /* serialize readers */ |
| 450 | arch_spinlock_t lock; | 450 | arch_spinlock_t lock; |
| 451 | struct lock_class_key lock_key; | 451 | struct lock_class_key lock_key; |
| 452 | unsigned int nr_pages; | ||
| 452 | struct list_head *pages; | 453 | struct list_head *pages; |
| 453 | struct buffer_page *head_page; /* read from head */ | 454 | struct buffer_page *head_page; /* read from head */ |
| 454 | struct buffer_page *tail_page; /* write to tail */ | 455 | struct buffer_page *tail_page; /* write to tail */ |
| @@ -466,10 +467,12 @@ struct ring_buffer_per_cpu { | |||
| 466 | unsigned long read_bytes; | 467 | unsigned long read_bytes; |
| 467 | u64 write_stamp; | 468 | u64 write_stamp; |
| 468 | u64 read_stamp; | 469 | u64 read_stamp; |
| 470 | /* ring buffer pages to update, > 0 to add, < 0 to remove */ | ||
| 471 | int nr_pages_to_update; | ||
| 472 | struct list_head new_pages; /* new pages to add */ | ||
| 469 | }; | 473 | }; |
| 470 | 474 | ||
| 471 | struct ring_buffer { | 475 | struct ring_buffer { |
| 472 | unsigned pages; | ||
| 473 | unsigned flags; | 476 | unsigned flags; |
| 474 | int cpus; | 477 | int cpus; |
| 475 | atomic_t record_disabled; | 478 | atomic_t record_disabled; |
| @@ -963,14 +966,10 @@ static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer) | |||
| 963 | return 0; | 966 | return 0; |
| 964 | } | 967 | } |
| 965 | 968 | ||
| 966 | static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, | 969 | static int __rb_allocate_pages(int nr_pages, struct list_head *pages, int cpu) |
| 967 | unsigned nr_pages) | ||
| 968 | { | 970 | { |
| 971 | int i; | ||
| 969 | struct buffer_page *bpage, *tmp; | 972 | struct buffer_page *bpage, *tmp; |
| 970 | LIST_HEAD(pages); | ||
| 971 | unsigned i; | ||
| 972 | |||
| 973 | WARN_ON(!nr_pages); | ||
| 974 | 973 | ||
| 975 | for (i = 0; i < nr_pages; i++) { | 974 | for (i = 0; i < nr_pages; i++) { |
| 976 | struct page *page; | 975 | struct page *page; |
| @@ -981,15 +980,13 @@ static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, | |||
| 981 | */ | 980 | */ |
| 982 | bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()), | 981 | bpage = kzalloc_node(ALIGN(sizeof(*bpage), cache_line_size()), |
| 983 | GFP_KERNEL | __GFP_NORETRY, | 982 | GFP_KERNEL | __GFP_NORETRY, |
| 984 | cpu_to_node(cpu_buffer->cpu)); | 983 | cpu_to_node(cpu)); |
| 985 | if (!bpage) | 984 | if (!bpage) |
| 986 | goto free_pages; | 985 | goto free_pages; |
| 987 | 986 | ||
| 988 | rb_check_bpage(cpu_buffer, bpage); | 987 | list_add(&bpage->list, pages); |
| 989 | 988 | ||
| 990 | list_add(&bpage->list, &pages); | 989 | page = alloc_pages_node(cpu_to_node(cpu), |
| 991 | |||
| 992 | page = alloc_pages_node(cpu_to_node(cpu_buffer->cpu), | ||
| 993 | GFP_KERNEL | __GFP_NORETRY, 0); | 990 | GFP_KERNEL | __GFP_NORETRY, 0); |
| 994 | if (!page) | 991 | if (!page) |
| 995 | goto free_pages; | 992 | goto free_pages; |
| @@ -997,6 +994,27 @@ static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, | |||
| 997 | rb_init_page(bpage->page); | 994 | rb_init_page(bpage->page); |
| 998 | } | 995 | } |
| 999 | 996 | ||
| 997 | return 0; | ||
| 998 | |||
| 999 | free_pages: | ||
| 1000 | list_for_each_entry_safe(bpage, tmp, pages, list) { | ||
| 1001 | list_del_init(&bpage->list); | ||
| 1002 | free_buffer_page(bpage); | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | return -ENOMEM; | ||
| 1006 | } | ||
| 1007 | |||
| 1008 | static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, | ||
| 1009 | unsigned nr_pages) | ||
| 1010 | { | ||
| 1011 | LIST_HEAD(pages); | ||
| 1012 | |||
| 1013 | WARN_ON(!nr_pages); | ||
| 1014 | |||
| 1015 | if (__rb_allocate_pages(nr_pages, &pages, cpu_buffer->cpu)) | ||
| 1016 | return -ENOMEM; | ||
| 1017 | |||
| 1000 | /* | 1018 | /* |
| 1001 | * The ring buffer page list is a circular list that does not | 1019 | * The ring buffer page list is a circular list that does not |
| 1002 | * start and end with a list head. All page list items point to | 1020 | * start and end with a list head. All page list items point to |
| @@ -1005,20 +1023,15 @@ static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, | |||
| 1005 | cpu_buffer->pages = pages.next; | 1023 | cpu_buffer->pages = pages.next; |
| 1006 | list_del(&pages); | 1024 | list_del(&pages); |
| 1007 | 1025 | ||
| 1026 | cpu_buffer->nr_pages = nr_pages; | ||
| 1027 | |||
| 1008 | rb_check_pages(cpu_buffer); | 1028 | rb_check_pages(cpu_buffer); |
| 1009 | 1029 | ||
| 1010 | return 0; | 1030 | return 0; |
| 1011 | |||
| 1012 | free_pages: | ||
| 1013 | list_for_each_entry_safe(bpage, tmp, &pages, list) { | ||
| 1014 | list_del_init(&bpage->list); | ||
| 1015 | free_buffer_page(bpage); | ||
| 1016 | } | ||
| 1017 | return -ENOMEM; | ||
| 1018 | } | 1031 | } |
| 1019 | 1032 | ||
| 1020 | static struct ring_buffer_per_cpu * | 1033 | static struct ring_buffer_per_cpu * |
| 1021 | rb_allocate_cpu_buffer(struct ring_buffer *buffer, int cpu) | 1034 | rb_allocate_cpu_buffer(struct ring_buffer *buffer, int nr_pages, int cpu) |
| 1022 | { | 1035 | { |
| 1023 | struct ring_buffer_per_cpu *cpu_buffer; | 1036 | struct ring_buffer_per_cpu *cpu_buffer; |
| 1024 | struct buffer_page *bpage; | 1037 | struct buffer_page *bpage; |
| @@ -1052,7 +1065,7 @@ rb_allocate_cpu_buffer(struct ring_buffer *buffer, int cpu) | |||
| 1052 | 1065 | ||
| 1053 | INIT_LIST_HEAD(&cpu_buffer->reader_page->list); | 1066 | INIT_LIST_HEAD(&cpu_buffer->reader_page->list); |
| 1054 | 1067 | ||
| 1055 | ret = rb_allocate_pages(cpu_buffer, buffer->pages); | 1068 | ret = rb_allocate_pages(cpu_buffer, nr_pages); |
| 1056 | if (ret < 0) | 1069 | if (ret < 0) |
| 1057 | goto fail_free_reader; | 1070 | goto fail_free_reader; |
| 1058 | 1071 | ||
| @@ -1113,7 +1126,7 @@ struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags, | |||
| 1113 | { | 1126 | { |
| 1114 | struct ring_buffer *buffer; | 1127 | struct ring_buffer *buffer; |
| 1115 | int bsize; | 1128 | int bsize; |
| 1116 | int cpu; | 1129 | int cpu, nr_pages; |
| 1117 | 1130 | ||
| 1118 | /* keep it in its own cache line */ | 1131 | /* keep it in its own cache line */ |
| 1119 | buffer = kzalloc(ALIGN(sizeof(*buffer), cache_line_size()), | 1132 | buffer = kzalloc(ALIGN(sizeof(*buffer), cache_line_size()), |
| @@ -1124,14 +1137,14 @@ struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags, | |||
| 1124 | if (!alloc_cpumask_var(&buffer->cpumask, GFP_KERNEL)) | 1137 | if (!alloc_cpumask_var(&buffer->cpumask, GFP_KERNEL)) |
| 1125 | goto fail_free_buffer; | 1138 | goto fail_free_buffer; |
| 1126 | 1139 | ||
| 1127 | buffer->pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); | 1140 | nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); |
| 1128 | buffer->flags = flags; | 1141 | buffer->flags = flags; |
| 1129 | buffer->clock = trace_clock_local; | 1142 | buffer->clock = trace_clock_local; |
| 1130 | buffer->reader_lock_key = key; | 1143 | buffer->reader_lock_key = key; |
| 1131 | 1144 | ||
| 1132 | /* need at least two pages */ | 1145 | /* need at least two pages */ |
| 1133 | if (buffer->pages < 2) | 1146 | if (nr_pages < 2) |
| 1134 | buffer->pages = 2; | 1147 | nr_pages = 2; |
| 1135 | 1148 | ||
| 1136 | /* | 1149 | /* |
| 1137 | * In case of non-hotplug cpu, if the ring-buffer is allocated | 1150 | * In case of non-hotplug cpu, if the ring-buffer is allocated |
| @@ -1154,7 +1167,7 @@ struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags, | |||
| 1154 | 1167 | ||
| 1155 | for_each_buffer_cpu(buffer, cpu) { | 1168 | for_each_buffer_cpu(buffer, cpu) { |
| 1156 | buffer->buffers[cpu] = | 1169 | buffer->buffers[cpu] = |
| 1157 | rb_allocate_cpu_buffer(buffer, cpu); | 1170 | rb_allocate_cpu_buffer(buffer, nr_pages, cpu); |
| 1158 | if (!buffer->buffers[cpu]) | 1171 | if (!buffer->buffers[cpu]) |
| 1159 | goto fail_free_buffers; | 1172 | goto fail_free_buffers; |
| 1160 | } | 1173 | } |
| @@ -1276,6 +1289,18 @@ out: | |||
| 1276 | raw_spin_unlock_irq(&cpu_buffer->reader_lock); | 1289 | raw_spin_unlock_irq(&cpu_buffer->reader_lock); |
| 1277 | } | 1290 | } |
| 1278 | 1291 | ||
| 1292 | static void update_pages_handler(struct ring_buffer_per_cpu *cpu_buffer) | ||
| 1293 | { | ||
| 1294 | if (cpu_buffer->nr_pages_to_update > 0) | ||
| 1295 | rb_insert_pages(cpu_buffer, &cpu_buffer->new_pages, | ||
| 1296 | cpu_buffer->nr_pages_to_update); | ||
| 1297 | else | ||
| 1298 | rb_remove_pages(cpu_buffer, -cpu_buffer->nr_pages_to_update); | ||
| 1299 | cpu_buffer->nr_pages += cpu_buffer->nr_pages_to_update; | ||
| 1300 | /* reset this value */ | ||
| 1301 | cpu_buffer->nr_pages_to_update = 0; | ||
| 1302 | } | ||
| 1303 | |||
| 1279 | /** | 1304 | /** |
| 1280 | * ring_buffer_resize - resize the ring buffer | 1305 | * ring_buffer_resize - resize the ring buffer |
| 1281 | * @buffer: the buffer to resize. | 1306 | * @buffer: the buffer to resize. |
| @@ -1285,14 +1310,12 @@ out: | |||
| 1285 | * | 1310 | * |
| 1286 | * Returns -1 on failure. | 1311 | * Returns -1 on failure. |
| 1287 | */ | 1312 | */ |
| 1288 | int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) | 1313 | int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size, |
| 1314 | int cpu_id) | ||
| 1289 | { | 1315 | { |
| 1290 | struct ring_buffer_per_cpu *cpu_buffer; | 1316 | struct ring_buffer_per_cpu *cpu_buffer; |
| 1291 | unsigned nr_pages, rm_pages, new_pages; | 1317 | unsigned nr_pages; |
| 1292 | struct buffer_page *bpage, *tmp; | 1318 | int cpu; |
| 1293 | unsigned long buffer_size; | ||
| 1294 | LIST_HEAD(pages); | ||
| 1295 | int i, cpu; | ||
| 1296 | 1319 | ||
| 1297 | /* | 1320 | /* |
| 1298 | * Always succeed at resizing a non-existent buffer: | 1321 | * Always succeed at resizing a non-existent buffer: |
| @@ -1302,15 +1325,11 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) | |||
| 1302 | 1325 | ||
| 1303 | size = DIV_ROUND_UP(size, BUF_PAGE_SIZE); | 1326 | size = DIV_ROUND_UP(size, BUF_PAGE_SIZE); |
| 1304 | size *= BUF_PAGE_SIZE; | 1327 | size *= BUF_PAGE_SIZE; |
| 1305 | buffer_size = buffer->pages * BUF_PAGE_SIZE; | ||
| 1306 | 1328 | ||
| 1307 | /* we need a minimum of two pages */ | 1329 | /* we need a minimum of two pages */ |
| 1308 | if (size < BUF_PAGE_SIZE * 2) | 1330 | if (size < BUF_PAGE_SIZE * 2) |
| 1309 | size = BUF_PAGE_SIZE * 2; | 1331 | size = BUF_PAGE_SIZE * 2; |
| 1310 | 1332 | ||
| 1311 | if (size == buffer_size) | ||
| 1312 | return size; | ||
| 1313 | |||
| 1314 | atomic_inc(&buffer->record_disabled); | 1333 | atomic_inc(&buffer->record_disabled); |
| 1315 | 1334 | ||
| 1316 | /* Make sure all writers are done with this buffer. */ | 1335 | /* Make sure all writers are done with this buffer. */ |
| @@ -1321,68 +1340,56 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) | |||
| 1321 | 1340 | ||
| 1322 | nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); | 1341 | nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); |
| 1323 | 1342 | ||
| 1324 | if (size < buffer_size) { | 1343 | if (cpu_id == RING_BUFFER_ALL_CPUS) { |
| 1325 | 1344 | /* calculate the pages to update */ | |
| 1326 | /* easy case, just free pages */ | ||
| 1327 | if (RB_WARN_ON(buffer, nr_pages >= buffer->pages)) | ||
| 1328 | goto out_fail; | ||
| 1329 | |||
| 1330 | rm_pages = buffer->pages - nr_pages; | ||
| 1331 | |||
| 1332 | for_each_buffer_cpu(buffer, cpu) { | 1345 | for_each_buffer_cpu(buffer, cpu) { |
| 1333 | cpu_buffer = buffer->buffers[cpu]; | 1346 | cpu_buffer = buffer->buffers[cpu]; |
| 1334 | rb_remove_pages(cpu_buffer, rm_pages); | ||
| 1335 | } | ||
| 1336 | goto out; | ||
| 1337 | } | ||
| 1338 | 1347 | ||
| 1339 | /* | 1348 | cpu_buffer->nr_pages_to_update = nr_pages - |
| 1340 | * This is a bit more difficult. We only want to add pages | 1349 | cpu_buffer->nr_pages; |
| 1341 | * when we can allocate enough for all CPUs. We do this | ||
| 1342 | * by allocating all the pages and storing them on a local | ||
| 1343 | * link list. If we succeed in our allocation, then we | ||
| 1344 | * add these pages to the cpu_buffers. Otherwise we just free | ||
| 1345 | * them all and return -ENOMEM; | ||
| 1346 | */ | ||
| 1347 | if (RB_WARN_ON(buffer, nr_pages <= buffer->pages)) | ||
| 1348 | goto out_fail; | ||
| 1349 | 1350 | ||
| 1350 | new_pages = nr_pages - buffer->pages; | 1351 | /* |
| 1352 | * nothing more to do for removing pages or no update | ||
| 1353 | */ | ||
| 1354 | if (cpu_buffer->nr_pages_to_update <= 0) | ||
| 1355 | continue; | ||
| 1351 | 1356 | ||
| 1352 | for_each_buffer_cpu(buffer, cpu) { | ||
| 1353 | for (i = 0; i < new_pages; i++) { | ||
| 1354 | struct page *page; | ||
| 1355 | /* | 1357 | /* |
| 1356 | * __GFP_NORETRY flag makes sure that the allocation | 1358 | * to add pages, make sure all new pages can be |
| 1357 | * fails gracefully without invoking oom-killer and | 1359 | * allocated without receiving ENOMEM |
| 1358 | * the system is not destabilized. | ||
| 1359 | */ | 1360 | */ |
| 1360 | bpage = kzalloc_node(ALIGN(sizeof(*bpage), | 1361 | INIT_LIST_HEAD(&cpu_buffer->new_pages); |
| 1361 | cache_line_size()), | 1362 | if (__rb_allocate_pages(cpu_buffer->nr_pages_to_update, |
| 1362 | GFP_KERNEL | __GFP_NORETRY, | 1363 | &cpu_buffer->new_pages, cpu)) |
| 1363 | cpu_to_node(cpu)); | 1364 | /* not enough memory for new pages */ |
| 1364 | if (!bpage) | 1365 | goto no_mem; |
| 1365 | goto free_pages; | ||
| 1366 | list_add(&bpage->list, &pages); | ||
| 1367 | page = alloc_pages_node(cpu_to_node(cpu), | ||
| 1368 | GFP_KERNEL | __GFP_NORETRY, 0); | ||
| 1369 | if (!page) | ||
| 1370 | goto free_pages; | ||
| 1371 | bpage->page = page_address(page); | ||
| 1372 | rb_init_page(bpage->page); | ||
| 1373 | } | 1366 | } |
| 1374 | } | ||
| 1375 | 1367 | ||
| 1376 | for_each_buffer_cpu(buffer, cpu) { | 1368 | /* wait for all the updates to complete */ |
| 1377 | cpu_buffer = buffer->buffers[cpu]; | 1369 | for_each_buffer_cpu(buffer, cpu) { |
| 1378 | rb_insert_pages(cpu_buffer, &pages, new_pages); | 1370 | cpu_buffer = buffer->buffers[cpu]; |
| 1379 | } | 1371 | if (cpu_buffer->nr_pages_to_update) { |
| 1372 | update_pages_handler(cpu_buffer); | ||
| 1373 | } | ||
| 1374 | } | ||
| 1375 | } else { | ||
| 1376 | cpu_buffer = buffer->buffers[cpu_id]; | ||
| 1377 | if (nr_pages == cpu_buffer->nr_pages) | ||
| 1378 | goto out; | ||
| 1380 | 1379 | ||
| 1381 | if (RB_WARN_ON(buffer, !list_empty(&pages))) | 1380 | cpu_buffer->nr_pages_to_update = nr_pages - |
| 1382 | goto out_fail; | 1381 | cpu_buffer->nr_pages; |
| 1382 | |||
| 1383 | INIT_LIST_HEAD(&cpu_buffer->new_pages); | ||
| 1384 | if (cpu_buffer->nr_pages_to_update > 0 && | ||
| 1385 | __rb_allocate_pages(cpu_buffer->nr_pages_to_update, | ||
| 1386 | &cpu_buffer->new_pages, cpu_id)) | ||
| 1387 | goto no_mem; | ||
| 1388 | |||
| 1389 | update_pages_handler(cpu_buffer); | ||
| 1390 | } | ||
| 1383 | 1391 | ||
| 1384 | out: | 1392 | out: |
| 1385 | buffer->pages = nr_pages; | ||
| 1386 | put_online_cpus(); | 1393 | put_online_cpus(); |
| 1387 | mutex_unlock(&buffer->mutex); | 1394 | mutex_unlock(&buffer->mutex); |
| 1388 | 1395 | ||
| @@ -1390,25 +1397,24 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size) | |||
| 1390 | 1397 | ||
| 1391 | return size; | 1398 | return size; |
| 1392 | 1399 | ||
| 1393 | free_pages: | 1400 | no_mem: |
| 1394 | list_for_each_entry_safe(bpage, tmp, &pages, list) { | 1401 | for_each_buffer_cpu(buffer, cpu) { |
| 1395 | list_del_init(&bpage->list); | 1402 | struct buffer_page *bpage, *tmp; |
| 1396 | free_buffer_page(bpage); | 1403 | cpu_buffer = buffer->buffers[cpu]; |
| 1404 | /* reset this number regardless */ | ||
| 1405 | cpu_buffer->nr_pages_to_update = 0; | ||
| 1406 | if (list_empty(&cpu_buffer->new_pages)) | ||
| 1407 | continue; | ||
| 1408 | list_for_each_entry_safe(bpage, tmp, &cpu_buffer->new_pages, | ||
| 1409 | list) { | ||
| 1410 | list_del_init(&bpage->list); | ||
| 1411 | free_buffer_page(bpage); | ||
| 1412 | } | ||
| 1397 | } | 1413 | } |
| 1398 | put_online_cpus(); | 1414 | put_online_cpus(); |
| 1399 | mutex_unlock(&buffer->mutex); | 1415 | mutex_unlock(&buffer->mutex); |
| 1400 | atomic_dec(&buffer->record_disabled); | 1416 | atomic_dec(&buffer->record_disabled); |
| 1401 | return -ENOMEM; | 1417 | return -ENOMEM; |
| 1402 | |||
| 1403 | /* | ||
| 1404 | * Something went totally wrong, and we are too paranoid | ||
| 1405 | * to even clean up the mess. | ||
| 1406 | */ | ||
| 1407 | out_fail: | ||
| 1408 | put_online_cpus(); | ||
| 1409 | mutex_unlock(&buffer->mutex); | ||
| 1410 | atomic_dec(&buffer->record_disabled); | ||
| 1411 | return -1; | ||
| 1412 | } | 1418 | } |
| 1413 | EXPORT_SYMBOL_GPL(ring_buffer_resize); | 1419 | EXPORT_SYMBOL_GPL(ring_buffer_resize); |
| 1414 | 1420 | ||
| @@ -1510,7 +1516,7 @@ rb_set_commit_to_write(struct ring_buffer_per_cpu *cpu_buffer) | |||
| 1510 | * assign the commit to the tail. | 1516 | * assign the commit to the tail. |
| 1511 | */ | 1517 | */ |
| 1512 | again: | 1518 | again: |
| 1513 | max_count = cpu_buffer->buffer->pages * 100; | 1519 | max_count = cpu_buffer->nr_pages * 100; |
| 1514 | 1520 | ||
| 1515 | while (cpu_buffer->commit_page != cpu_buffer->tail_page) { | 1521 | while (cpu_buffer->commit_page != cpu_buffer->tail_page) { |
| 1516 | if (RB_WARN_ON(cpu_buffer, !(--max_count))) | 1522 | if (RB_WARN_ON(cpu_buffer, !(--max_count))) |
| @@ -3588,9 +3594,18 @@ EXPORT_SYMBOL_GPL(ring_buffer_read); | |||
| 3588 | * ring_buffer_size - return the size of the ring buffer (in bytes) | 3594 | * ring_buffer_size - return the size of the ring buffer (in bytes) |
| 3589 | * @buffer: The ring buffer. | 3595 | * @buffer: The ring buffer. |
| 3590 | */ | 3596 | */ |
| 3591 | unsigned long ring_buffer_size(struct ring_buffer *buffer) | 3597 | unsigned long ring_buffer_size(struct ring_buffer *buffer, int cpu) |
| 3592 | { | 3598 | { |
| 3593 | return BUF_PAGE_SIZE * buffer->pages; | 3599 | /* |
| 3600 | * Earlier, this method returned | ||
| 3601 | * BUF_PAGE_SIZE * buffer->nr_pages | ||
| 3602 | * Since the nr_pages field is now removed, we have converted this to | ||
| 3603 | * return the per cpu buffer value. | ||
| 3604 | */ | ||
| 3605 | if (!cpumask_test_cpu(cpu, buffer->cpumask)) | ||
| 3606 | return 0; | ||
| 3607 | |||
| 3608 | return BUF_PAGE_SIZE * buffer->buffers[cpu]->nr_pages; | ||
| 3594 | } | 3609 | } |
| 3595 | EXPORT_SYMBOL_GPL(ring_buffer_size); | 3610 | EXPORT_SYMBOL_GPL(ring_buffer_size); |
| 3596 | 3611 | ||
| @@ -3765,8 +3780,11 @@ int ring_buffer_swap_cpu(struct ring_buffer *buffer_a, | |||
| 3765 | !cpumask_test_cpu(cpu, buffer_b->cpumask)) | 3780 | !cpumask_test_cpu(cpu, buffer_b->cpumask)) |
| 3766 | goto out; | 3781 | goto out; |
| 3767 | 3782 | ||
| 3783 | cpu_buffer_a = buffer_a->buffers[cpu]; | ||
| 3784 | cpu_buffer_b = buffer_b->buffers[cpu]; | ||
| 3785 | |||
| 3768 | /* At least make sure the two buffers are somewhat the same */ | 3786 | /* At least make sure the two buffers are somewhat the same */ |
| 3769 | if (buffer_a->pages != buffer_b->pages) | 3787 | if (cpu_buffer_a->nr_pages != cpu_buffer_b->nr_pages) |
| 3770 | goto out; | 3788 | goto out; |
| 3771 | 3789 | ||
| 3772 | ret = -EAGAIN; | 3790 | ret = -EAGAIN; |
| @@ -3780,9 +3798,6 @@ int ring_buffer_swap_cpu(struct ring_buffer *buffer_a, | |||
| 3780 | if (atomic_read(&buffer_b->record_disabled)) | 3798 | if (atomic_read(&buffer_b->record_disabled)) |
| 3781 | goto out; | 3799 | goto out; |
| 3782 | 3800 | ||
| 3783 | cpu_buffer_a = buffer_a->buffers[cpu]; | ||
| 3784 | cpu_buffer_b = buffer_b->buffers[cpu]; | ||
| 3785 | |||
| 3786 | if (atomic_read(&cpu_buffer_a->record_disabled)) | 3801 | if (atomic_read(&cpu_buffer_a->record_disabled)) |
| 3787 | goto out; | 3802 | goto out; |
| 3788 | 3803 | ||
| @@ -4071,6 +4086,8 @@ static int rb_cpu_notify(struct notifier_block *self, | |||
| 4071 | struct ring_buffer *buffer = | 4086 | struct ring_buffer *buffer = |
| 4072 | container_of(self, struct ring_buffer, cpu_notify); | 4087 | container_of(self, struct ring_buffer, cpu_notify); |
| 4073 | long cpu = (long)hcpu; | 4088 | long cpu = (long)hcpu; |
| 4089 | int cpu_i, nr_pages_same; | ||
| 4090 | unsigned int nr_pages; | ||
| 4074 | 4091 | ||
| 4075 | switch (action) { | 4092 | switch (action) { |
| 4076 | case CPU_UP_PREPARE: | 4093 | case CPU_UP_PREPARE: |
| @@ -4078,8 +4095,23 @@ static int rb_cpu_notify(struct notifier_block *self, | |||
| 4078 | if (cpumask_test_cpu(cpu, buffer->cpumask)) | 4095 | if (cpumask_test_cpu(cpu, buffer->cpumask)) |
| 4079 | return NOTIFY_OK; | 4096 | return NOTIFY_OK; |
| 4080 | 4097 | ||
| 4098 | nr_pages = 0; | ||
| 4099 | nr_pages_same = 1; | ||
| 4100 | /* check if all cpu sizes are same */ | ||
| 4101 | for_each_buffer_cpu(buffer, cpu_i) { | ||
| 4102 | /* fill in the size from first enabled cpu */ | ||
| 4103 | if (nr_pages == 0) | ||
| 4104 | nr_pages = buffer->buffers[cpu_i]->nr_pages; | ||
| 4105 | if (nr_pages != buffer->buffers[cpu_i]->nr_pages) { | ||
| 4106 | nr_pages_same = 0; | ||
| 4107 | break; | ||
| 4108 | } | ||
| 4109 | } | ||
| 4110 | /* allocate minimum pages, user can later expand it */ | ||
| 4111 | if (!nr_pages_same) | ||
| 4112 | nr_pages = 2; | ||
| 4081 | buffer->buffers[cpu] = | 4113 | buffer->buffers[cpu] = |
| 4082 | rb_allocate_cpu_buffer(buffer, cpu); | 4114 | rb_allocate_cpu_buffer(buffer, nr_pages, cpu); |
| 4083 | if (!buffer->buffers[cpu]) { | 4115 | if (!buffer->buffers[cpu]) { |
| 4084 | WARN(1, "failed to allocate ring buffer on CPU %ld\n", | 4116 | WARN(1, "failed to allocate ring buffer on CPU %ld\n", |
| 4085 | cpu); | 4117 | cpu); |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index bbcde546f9f7..f11a285ee5bb 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
| @@ -838,7 +838,8 @@ __acquires(kernel_lock) | |||
| 838 | 838 | ||
| 839 | /* If we expanded the buffers, make sure the max is expanded too */ | 839 | /* If we expanded the buffers, make sure the max is expanded too */ |
| 840 | if (ring_buffer_expanded && type->use_max_tr) | 840 | if (ring_buffer_expanded && type->use_max_tr) |
| 841 | ring_buffer_resize(max_tr.buffer, trace_buf_size); | 841 | ring_buffer_resize(max_tr.buffer, trace_buf_size, |
| 842 | RING_BUFFER_ALL_CPUS); | ||
| 842 | 843 | ||
| 843 | /* the test is responsible for initializing and enabling */ | 844 | /* the test is responsible for initializing and enabling */ |
| 844 | pr_info("Testing tracer %s: ", type->name); | 845 | pr_info("Testing tracer %s: ", type->name); |
| @@ -854,7 +855,8 @@ __acquires(kernel_lock) | |||
| 854 | 855 | ||
| 855 | /* Shrink the max buffer again */ | 856 | /* Shrink the max buffer again */ |
| 856 | if (ring_buffer_expanded && type->use_max_tr) | 857 | if (ring_buffer_expanded && type->use_max_tr) |
| 857 | ring_buffer_resize(max_tr.buffer, 1); | 858 | ring_buffer_resize(max_tr.buffer, 1, |
| 859 | RING_BUFFER_ALL_CPUS); | ||
| 858 | 860 | ||
| 859 | printk(KERN_CONT "PASSED\n"); | 861 | printk(KERN_CONT "PASSED\n"); |
| 860 | } | 862 | } |
| @@ -3053,7 +3055,14 @@ int tracer_init(struct tracer *t, struct trace_array *tr) | |||
| 3053 | return t->init(tr); | 3055 | return t->init(tr); |
| 3054 | } | 3056 | } |
| 3055 | 3057 | ||
| 3056 | static int __tracing_resize_ring_buffer(unsigned long size) | 3058 | static void set_buffer_entries(struct trace_array *tr, unsigned long val) |
| 3059 | { | ||
| 3060 | int cpu; | ||
| 3061 | for_each_tracing_cpu(cpu) | ||
| 3062 | tr->data[cpu]->entries = val; | ||
| 3063 | } | ||
| 3064 | |||
| 3065 | static int __tracing_resize_ring_buffer(unsigned long size, int cpu) | ||
| 3057 | { | 3066 | { |
| 3058 | int ret; | 3067 | int ret; |
| 3059 | 3068 | ||
| @@ -3064,19 +3073,32 @@ static int __tracing_resize_ring_buffer(unsigned long size) | |||
| 3064 | */ | 3073 | */ |
| 3065 | ring_buffer_expanded = 1; | 3074 | ring_buffer_expanded = 1; |
| 3066 | 3075 | ||
| 3067 | ret = ring_buffer_resize(global_trace.buffer, size); | 3076 | ret = ring_buffer_resize(global_trace.buffer, size, cpu); |
| 3068 | if (ret < 0) | 3077 | if (ret < 0) |
| 3069 | return ret; | 3078 | return ret; |
| 3070 | 3079 | ||
| 3071 | if (!current_trace->use_max_tr) | 3080 | if (!current_trace->use_max_tr) |
| 3072 | goto out; | 3081 | goto out; |
| 3073 | 3082 | ||
| 3074 | ret = ring_buffer_resize(max_tr.buffer, size); | 3083 | ret = ring_buffer_resize(max_tr.buffer, size, cpu); |
| 3075 | if (ret < 0) { | 3084 | if (ret < 0) { |
| 3076 | int r; | 3085 | int r = 0; |
| 3086 | |||
| 3087 | if (cpu == RING_BUFFER_ALL_CPUS) { | ||
| 3088 | int i; | ||
| 3089 | for_each_tracing_cpu(i) { | ||
| 3090 | r = ring_buffer_resize(global_trace.buffer, | ||
| 3091 | global_trace.data[i]->entries, | ||
| 3092 | i); | ||
| 3093 | if (r < 0) | ||
| 3094 | break; | ||
| 3095 | } | ||
| 3096 | } else { | ||
| 3097 | r = ring_buffer_resize(global_trace.buffer, | ||
| 3098 | global_trace.data[cpu]->entries, | ||
| 3099 | cpu); | ||
| 3100 | } | ||
| 3077 | 3101 | ||
| 3078 | r = ring_buffer_resize(global_trace.buffer, | ||
| 3079 | global_trace.entries); | ||
| 3080 | if (r < 0) { | 3102 | if (r < 0) { |
| 3081 | /* | 3103 | /* |
| 3082 | * AARGH! We are left with different | 3104 | * AARGH! We are left with different |
| @@ -3098,14 +3120,21 @@ static int __tracing_resize_ring_buffer(unsigned long size) | |||
| 3098 | return ret; | 3120 | return ret; |
| 3099 | } | 3121 | } |
| 3100 | 3122 | ||
| 3101 | max_tr.entries = size; | 3123 | if (cpu == RING_BUFFER_ALL_CPUS) |
| 3124 | set_buffer_entries(&max_tr, size); | ||
| 3125 | else | ||
| 3126 | max_tr.data[cpu]->entries = size; | ||
| 3127 | |||
| 3102 | out: | 3128 | out: |
| 3103 | global_trace.entries = size; | 3129 | if (cpu == RING_BUFFER_ALL_CPUS) |
| 3130 | set_buffer_entries(&global_trace, size); | ||
| 3131 | else | ||
| 3132 | global_trace.data[cpu]->entries = size; | ||
| 3104 | 3133 | ||
| 3105 | return ret; | 3134 | return ret; |
| 3106 | } | 3135 | } |
| 3107 | 3136 | ||
| 3108 | static ssize_t tracing_resize_ring_buffer(unsigned long size) | 3137 | static ssize_t tracing_resize_ring_buffer(unsigned long size, int cpu_id) |
| 3109 | { | 3138 | { |
| 3110 | int cpu, ret = size; | 3139 | int cpu, ret = size; |
| 3111 | 3140 | ||
| @@ -3121,12 +3150,19 @@ static ssize_t tracing_resize_ring_buffer(unsigned long size) | |||
| 3121 | atomic_inc(&max_tr.data[cpu]->disabled); | 3150 | atomic_inc(&max_tr.data[cpu]->disabled); |
| 3122 | } | 3151 | } |
| 3123 | 3152 | ||
| 3124 | if (size != global_trace.entries) | 3153 | if (cpu_id != RING_BUFFER_ALL_CPUS) { |
| 3125 | ret = __tracing_resize_ring_buffer(size); | 3154 | /* make sure, this cpu is enabled in the mask */ |
| 3155 | if (!cpumask_test_cpu(cpu_id, tracing_buffer_mask)) { | ||
| 3156 | ret = -EINVAL; | ||
| 3157 | goto out; | ||
| 3158 | } | ||
| 3159 | } | ||
| 3126 | 3160 | ||
| 3161 | ret = __tracing_resize_ring_buffer(size, cpu_id); | ||
| 3127 | if (ret < 0) | 3162 | if (ret < 0) |
| 3128 | ret = -ENOMEM; | 3163 | ret = -ENOMEM; |
| 3129 | 3164 | ||
| 3165 | out: | ||
| 3130 | for_each_tracing_cpu(cpu) { | 3166 | for_each_tracing_cpu(cpu) { |
| 3131 | if (global_trace.data[cpu]) | 3167 | if (global_trace.data[cpu]) |
| 3132 | atomic_dec(&global_trace.data[cpu]->disabled); | 3168 | atomic_dec(&global_trace.data[cpu]->disabled); |
| @@ -3157,7 +3193,8 @@ int tracing_update_buffers(void) | |||
| 3157 | 3193 | ||
| 3158 | mutex_lock(&trace_types_lock); | 3194 | mutex_lock(&trace_types_lock); |
| 3159 | if (!ring_buffer_expanded) | 3195 | if (!ring_buffer_expanded) |
| 3160 | ret = __tracing_resize_ring_buffer(trace_buf_size); | 3196 | ret = __tracing_resize_ring_buffer(trace_buf_size, |
| 3197 | RING_BUFFER_ALL_CPUS); | ||
| 3161 | mutex_unlock(&trace_types_lock); | 3198 | mutex_unlock(&trace_types_lock); |
| 3162 | 3199 | ||
| 3163 | return ret; | 3200 | return ret; |
| @@ -3181,7 +3218,8 @@ static int tracing_set_tracer(const char *buf) | |||
| 3181 | mutex_lock(&trace_types_lock); | 3218 | mutex_lock(&trace_types_lock); |
| 3182 | 3219 | ||
| 3183 | if (!ring_buffer_expanded) { | 3220 | if (!ring_buffer_expanded) { |
| 3184 | ret = __tracing_resize_ring_buffer(trace_buf_size); | 3221 | ret = __tracing_resize_ring_buffer(trace_buf_size, |
| 3222 | RING_BUFFER_ALL_CPUS); | ||
| 3185 | if (ret < 0) | 3223 | if (ret < 0) |
| 3186 | goto out; | 3224 | goto out; |
| 3187 | ret = 0; | 3225 | ret = 0; |
| @@ -3207,8 +3245,8 @@ static int tracing_set_tracer(const char *buf) | |||
| 3207 | * The max_tr ring buffer has some state (e.g. ring->clock) and | 3245 | * The max_tr ring buffer has some state (e.g. ring->clock) and |
| 3208 | * we want preserve it. | 3246 | * we want preserve it. |
| 3209 | */ | 3247 | */ |
| 3210 | ring_buffer_resize(max_tr.buffer, 1); | 3248 | ring_buffer_resize(max_tr.buffer, 1, RING_BUFFER_ALL_CPUS); |
| 3211 | max_tr.entries = 1; | 3249 | set_buffer_entries(&max_tr, 1); |
| 3212 | } | 3250 | } |
| 3213 | destroy_trace_option_files(topts); | 3251 | destroy_trace_option_files(topts); |
| 3214 | 3252 | ||
| @@ -3216,10 +3254,17 @@ static int tracing_set_tracer(const char *buf) | |||
| 3216 | 3254 | ||
| 3217 | topts = create_trace_option_files(current_trace); | 3255 | topts = create_trace_option_files(current_trace); |
| 3218 | if (current_trace->use_max_tr) { | 3256 | if (current_trace->use_max_tr) { |
| 3219 | ret = ring_buffer_resize(max_tr.buffer, global_trace.entries); | 3257 | int cpu; |
| 3220 | if (ret < 0) | 3258 | /* we need to make per cpu buffer sizes equivalent */ |
| 3221 | goto out; | 3259 | for_each_tracing_cpu(cpu) { |
| 3222 | max_tr.entries = global_trace.entries; | 3260 | ret = ring_buffer_resize(max_tr.buffer, |
| 3261 | global_trace.data[cpu]->entries, | ||
| 3262 | cpu); | ||
| 3263 | if (ret < 0) | ||
| 3264 | goto out; | ||
| 3265 | max_tr.data[cpu]->entries = | ||
| 3266 | global_trace.data[cpu]->entries; | ||
| 3267 | } | ||
| 3223 | } | 3268 | } |
| 3224 | 3269 | ||
| 3225 | if (t->init) { | 3270 | if (t->init) { |
| @@ -3721,30 +3766,82 @@ out_err: | |||
| 3721 | goto out; | 3766 | goto out; |
| 3722 | } | 3767 | } |
| 3723 | 3768 | ||
| 3769 | struct ftrace_entries_info { | ||
| 3770 | struct trace_array *tr; | ||
| 3771 | int cpu; | ||
| 3772 | }; | ||
| 3773 | |||
| 3774 | static int tracing_entries_open(struct inode *inode, struct file *filp) | ||
| 3775 | { | ||
| 3776 | struct ftrace_entries_info *info; | ||
| 3777 | |||
| 3778 | if (tracing_disabled) | ||
| 3779 | return -ENODEV; | ||
| 3780 | |||
| 3781 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
| 3782 | if (!info) | ||
| 3783 | return -ENOMEM; | ||
| 3784 | |||
| 3785 | info->tr = &global_trace; | ||
| 3786 | info->cpu = (unsigned long)inode->i_private; | ||
| 3787 | |||
| 3788 | filp->private_data = info; | ||
| 3789 | |||
| 3790 | return 0; | ||
| 3791 | } | ||
| 3792 | |||
| 3724 | static ssize_t | 3793 | static ssize_t |
| 3725 | tracing_entries_read(struct file *filp, char __user *ubuf, | 3794 | tracing_entries_read(struct file *filp, char __user *ubuf, |
| 3726 | size_t cnt, loff_t *ppos) | 3795 | size_t cnt, loff_t *ppos) |
| 3727 | { | 3796 | { |
| 3728 | struct trace_array *tr = filp->private_data; | 3797 | struct ftrace_entries_info *info = filp->private_data; |
| 3729 | char buf[96]; | 3798 | struct trace_array *tr = info->tr; |
| 3730 | int r; | 3799 | char buf[64]; |
| 3800 | int r = 0; | ||
| 3801 | ssize_t ret; | ||
| 3731 | 3802 | ||
| 3732 | mutex_lock(&trace_types_lock); | 3803 | mutex_lock(&trace_types_lock); |
| 3733 | if (!ring_buffer_expanded) | 3804 | |
| 3734 | r = sprintf(buf, "%lu (expanded: %lu)\n", | 3805 | if (info->cpu == RING_BUFFER_ALL_CPUS) { |
| 3735 | tr->entries >> 10, | 3806 | int cpu, buf_size_same; |
| 3736 | trace_buf_size >> 10); | 3807 | unsigned long size; |
| 3737 | else | 3808 | |
| 3738 | r = sprintf(buf, "%lu\n", tr->entries >> 10); | 3809 | size = 0; |
| 3810 | buf_size_same = 1; | ||
| 3811 | /* check if all cpu sizes are same */ | ||
| 3812 | for_each_tracing_cpu(cpu) { | ||
| 3813 | /* fill in the size from first enabled cpu */ | ||
| 3814 | if (size == 0) | ||
| 3815 | size = tr->data[cpu]->entries; | ||
| 3816 | if (size != tr->data[cpu]->entries) { | ||
| 3817 | buf_size_same = 0; | ||
| 3818 | break; | ||
| 3819 | } | ||
| 3820 | } | ||
| 3821 | |||
| 3822 | if (buf_size_same) { | ||
| 3823 | if (!ring_buffer_expanded) | ||
| 3824 | r = sprintf(buf, "%lu (expanded: %lu)\n", | ||
| 3825 | size >> 10, | ||
| 3826 | trace_buf_size >> 10); | ||
| 3827 | else | ||
| 3828 | r = sprintf(buf, "%lu\n", size >> 10); | ||
| 3829 | } else | ||
| 3830 | r = sprintf(buf, "X\n"); | ||
| 3831 | } else | ||
| 3832 | r = sprintf(buf, "%lu\n", tr->data[info->cpu]->entries >> 10); | ||
| 3833 | |||
| 3739 | mutex_unlock(&trace_types_lock); | 3834 | mutex_unlock(&trace_types_lock); |
| 3740 | 3835 | ||
| 3741 | return simple_read_from_buffer(ubuf, cnt, ppos, buf, r); | 3836 | ret = simple_read_from_buffer(ubuf, cnt, ppos, buf, r); |
| 3837 | return ret; | ||
| 3742 | } | 3838 | } |
| 3743 | 3839 | ||
| 3744 | static ssize_t | 3840 | static ssize_t |
| 3745 | tracing_entries_write(struct file *filp, const char __user *ubuf, | 3841 | tracing_entries_write(struct file *filp, const char __user *ubuf, |
| 3746 | size_t cnt, loff_t *ppos) | 3842 | size_t cnt, loff_t *ppos) |
| 3747 | { | 3843 | { |
| 3844 | struct ftrace_entries_info *info = filp->private_data; | ||
| 3748 | unsigned long val; | 3845 | unsigned long val; |
| 3749 | int ret; | 3846 | int ret; |
| 3750 | 3847 | ||
| @@ -3759,7 +3856,7 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, | |||
| 3759 | /* value is in KB */ | 3856 | /* value is in KB */ |
| 3760 | val <<= 10; | 3857 | val <<= 10; |
| 3761 | 3858 | ||
| 3762 | ret = tracing_resize_ring_buffer(val); | 3859 | ret = tracing_resize_ring_buffer(val, info->cpu); |
| 3763 | if (ret < 0) | 3860 | if (ret < 0) |
| 3764 | return ret; | 3861 | return ret; |
| 3765 | 3862 | ||
| @@ -3768,6 +3865,16 @@ tracing_entries_write(struct file *filp, const char __user *ubuf, | |||
| 3768 | return cnt; | 3865 | return cnt; |
| 3769 | } | 3866 | } |
| 3770 | 3867 | ||
| 3868 | static int | ||
| 3869 | tracing_entries_release(struct inode *inode, struct file *filp) | ||
| 3870 | { | ||
| 3871 | struct ftrace_entries_info *info = filp->private_data; | ||
| 3872 | |||
| 3873 | kfree(info); | ||
| 3874 | |||
| 3875 | return 0; | ||
| 3876 | } | ||
| 3877 | |||
| 3771 | static ssize_t | 3878 | static ssize_t |
| 3772 | tracing_total_entries_read(struct file *filp, char __user *ubuf, | 3879 | tracing_total_entries_read(struct file *filp, char __user *ubuf, |
| 3773 | size_t cnt, loff_t *ppos) | 3880 | size_t cnt, loff_t *ppos) |
| @@ -3779,7 +3886,7 @@ tracing_total_entries_read(struct file *filp, char __user *ubuf, | |||
| 3779 | 3886 | ||
| 3780 | mutex_lock(&trace_types_lock); | 3887 | mutex_lock(&trace_types_lock); |
| 3781 | for_each_tracing_cpu(cpu) { | 3888 | for_each_tracing_cpu(cpu) { |
| 3782 | size += tr->entries >> 10; | 3889 | size += tr->data[cpu]->entries >> 10; |
| 3783 | if (!ring_buffer_expanded) | 3890 | if (!ring_buffer_expanded) |
| 3784 | expanded_size += trace_buf_size >> 10; | 3891 | expanded_size += trace_buf_size >> 10; |
| 3785 | } | 3892 | } |
| @@ -3813,7 +3920,7 @@ tracing_free_buffer_release(struct inode *inode, struct file *filp) | |||
| 3813 | if (trace_flags & TRACE_ITER_STOP_ON_FREE) | 3920 | if (trace_flags & TRACE_ITER_STOP_ON_FREE) |
| 3814 | tracing_off(); | 3921 | tracing_off(); |
| 3815 | /* resize the ring buffer to 0 */ | 3922 | /* resize the ring buffer to 0 */ |
| 3816 | tracing_resize_ring_buffer(0); | 3923 | tracing_resize_ring_buffer(0, RING_BUFFER_ALL_CPUS); |
| 3817 | 3924 | ||
| 3818 | return 0; | 3925 | return 0; |
| 3819 | } | 3926 | } |
| @@ -4012,9 +4119,10 @@ static const struct file_operations tracing_pipe_fops = { | |||
| 4012 | }; | 4119 | }; |
| 4013 | 4120 | ||
| 4014 | static const struct file_operations tracing_entries_fops = { | 4121 | static const struct file_operations tracing_entries_fops = { |
| 4015 | .open = tracing_open_generic, | 4122 | .open = tracing_entries_open, |
| 4016 | .read = tracing_entries_read, | 4123 | .read = tracing_entries_read, |
| 4017 | .write = tracing_entries_write, | 4124 | .write = tracing_entries_write, |
| 4125 | .release = tracing_entries_release, | ||
| 4018 | .llseek = generic_file_llseek, | 4126 | .llseek = generic_file_llseek, |
| 4019 | }; | 4127 | }; |
| 4020 | 4128 | ||
| @@ -4466,6 +4574,9 @@ static void tracing_init_debugfs_percpu(long cpu) | |||
| 4466 | 4574 | ||
| 4467 | trace_create_file("stats", 0444, d_cpu, | 4575 | trace_create_file("stats", 0444, d_cpu, |
| 4468 | (void *) cpu, &tracing_stats_fops); | 4576 | (void *) cpu, &tracing_stats_fops); |
| 4577 | |||
| 4578 | trace_create_file("buffer_size_kb", 0444, d_cpu, | ||
| 4579 | (void *) cpu, &tracing_entries_fops); | ||
| 4469 | } | 4580 | } |
| 4470 | 4581 | ||
| 4471 | #ifdef CONFIG_FTRACE_SELFTEST | 4582 | #ifdef CONFIG_FTRACE_SELFTEST |
| @@ -4795,7 +4906,7 @@ static __init int tracer_init_debugfs(void) | |||
| 4795 | (void *) TRACE_PIPE_ALL_CPU, &tracing_pipe_fops); | 4906 | (void *) TRACE_PIPE_ALL_CPU, &tracing_pipe_fops); |
| 4796 | 4907 | ||
| 4797 | trace_create_file("buffer_size_kb", 0644, d_tracer, | 4908 | trace_create_file("buffer_size_kb", 0644, d_tracer, |
| 4798 | &global_trace, &tracing_entries_fops); | 4909 | (void *) RING_BUFFER_ALL_CPUS, &tracing_entries_fops); |
| 4799 | 4910 | ||
| 4800 | trace_create_file("buffer_total_size_kb", 0444, d_tracer, | 4911 | trace_create_file("buffer_total_size_kb", 0444, d_tracer, |
| 4801 | &global_trace, &tracing_total_entries_fops); | 4912 | &global_trace, &tracing_total_entries_fops); |
| @@ -5056,7 +5167,6 @@ __init static int tracer_alloc_buffers(void) | |||
| 5056 | WARN_ON(1); | 5167 | WARN_ON(1); |
| 5057 | goto out_free_cpumask; | 5168 | goto out_free_cpumask; |
| 5058 | } | 5169 | } |
| 5059 | global_trace.entries = ring_buffer_size(global_trace.buffer); | ||
| 5060 | if (global_trace.buffer_disabled) | 5170 | if (global_trace.buffer_disabled) |
| 5061 | tracing_off(); | 5171 | tracing_off(); |
| 5062 | 5172 | ||
| @@ -5069,7 +5179,6 @@ __init static int tracer_alloc_buffers(void) | |||
| 5069 | ring_buffer_free(global_trace.buffer); | 5179 | ring_buffer_free(global_trace.buffer); |
| 5070 | goto out_free_cpumask; | 5180 | goto out_free_cpumask; |
| 5071 | } | 5181 | } |
| 5072 | max_tr.entries = 1; | ||
| 5073 | #endif | 5182 | #endif |
| 5074 | 5183 | ||
| 5075 | /* Allocate the first page for all buffers */ | 5184 | /* Allocate the first page for all buffers */ |
| @@ -5078,6 +5187,11 @@ __init static int tracer_alloc_buffers(void) | |||
| 5078 | max_tr.data[i] = &per_cpu(max_tr_data, i); | 5187 | max_tr.data[i] = &per_cpu(max_tr_data, i); |
| 5079 | } | 5188 | } |
| 5080 | 5189 | ||
| 5190 | set_buffer_entries(&global_trace, ring_buf_size); | ||
| 5191 | #ifdef CONFIG_TRACER_MAX_TRACE | ||
| 5192 | set_buffer_entries(&max_tr, 1); | ||
| 5193 | #endif | ||
| 5194 | |||
| 5081 | trace_init_cmdlines(); | 5195 | trace_init_cmdlines(); |
| 5082 | 5196 | ||
| 5083 | register_tracer(&nop_trace); | 5197 | register_tracer(&nop_trace); |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index f9d85504f04b..1c8b7c6f7b3b 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
| @@ -131,6 +131,7 @@ struct trace_array_cpu { | |||
| 131 | atomic_t disabled; | 131 | atomic_t disabled; |
| 132 | void *buffer_page; /* ring buffer spare */ | 132 | void *buffer_page; /* ring buffer spare */ |
| 133 | 133 | ||
| 134 | unsigned long entries; | ||
| 134 | unsigned long saved_latency; | 135 | unsigned long saved_latency; |
| 135 | unsigned long critical_start; | 136 | unsigned long critical_start; |
| 136 | unsigned long critical_end; | 137 | unsigned long critical_end; |
| @@ -152,7 +153,6 @@ struct trace_array_cpu { | |||
| 152 | */ | 153 | */ |
| 153 | struct trace_array { | 154 | struct trace_array { |
| 154 | struct ring_buffer *buffer; | 155 | struct ring_buffer *buffer; |
| 155 | unsigned long entries; | ||
| 156 | int cpu; | 156 | int cpu; |
| 157 | int buffer_disabled; | 157 | int buffer_disabled; |
| 158 | cycle_t time_start; | 158 | cycle_t time_start; |
