diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-07-17 11:27:42 -0400 |
---|---|---|
committer | Steven Rostedt <srostedt@redhat.com> | 2009-07-17 11:27:42 -0400 |
commit | ee14f41ea9139587f78d96c01063d26b032b20e1 (patch) | |
tree | 1858d6dd6fdf1b18f9b7bcbc2642e624a085be15 /trace-read.c | |
parent | 8fe41e31b4407bdbb862c9dff35c2ac50f690627 (diff) |
Use reading if mmap fails
Some archs do not allow 4K pages to be mapped. But the ftrace data
file (for now) requires that pages are mapped by 4K. In case the
mmap fails, we read the pages instead.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Diffstat (limited to 'trace-read.c')
-rw-r--r-- | trace-read.c | 78 |
1 files changed, 72 insertions, 6 deletions
diff --git a/trace-read.c b/trace-read.c index d37636a..f65043b 100644 --- a/trace-read.c +++ b/trace-read.c | |||
@@ -18,6 +18,7 @@ | |||
18 | * | 18 | * |
19 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 19 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
20 | */ | 20 | */ |
21 | #define _LARGEFILE64_SOURCE | ||
21 | #define _GNU_SOURCE | 22 | #define _GNU_SOURCE |
22 | #include <dirent.h> | 23 | #include <dirent.h> |
23 | #include <stdio.h> | 24 | #include <stdio.h> |
@@ -39,6 +40,8 @@ | |||
39 | 40 | ||
40 | static int input_fd; | 41 | static int input_fd; |
41 | 42 | ||
43 | static int read_page; | ||
44 | |||
42 | static int file_bigendian; | 45 | static int file_bigendian; |
43 | static int host_bigendian; | 46 | static int host_bigendian; |
44 | static int long_size; | 47 | static int long_size; |
@@ -286,6 +289,27 @@ struct cpu_data { | |||
286 | static int cpus; | 289 | static int cpus; |
287 | static struct cpu_data *cpu_data; | 290 | static struct cpu_data *cpu_data; |
288 | 291 | ||
292 | static void init_read(int cpu) | ||
293 | { | ||
294 | off64_t ret; | ||
295 | off64_t save_seek; | ||
296 | |||
297 | cpu_data[cpu].page = malloc_or_die(PAGE_SIZE); | ||
298 | |||
299 | /* other parts of the code may expect the pointer to not move */ | ||
300 | save_seek = lseek64(input_fd, 0, SEEK_CUR); | ||
301 | |||
302 | ret = lseek64(input_fd, (off64_t)cpu_data[cpu].offset, SEEK_SET); | ||
303 | if (ret < 0) | ||
304 | die("failed to lseek"); | ||
305 | ret = read(input_fd, cpu_data[cpu].page, PAGE_SIZE); | ||
306 | if (ret < 0) | ||
307 | die("failed to read page"); | ||
308 | |||
309 | /* reset the file pointer back */ | ||
310 | lseek64(input_fd, save_seek, SEEK_SET); | ||
311 | } | ||
312 | |||
289 | static void init_cpu(int cpu) | 313 | static void init_cpu(int cpu) |
290 | { | 314 | { |
291 | if (!cpu_data[cpu].size) { | 315 | if (!cpu_data[cpu].size) { |
@@ -293,27 +317,69 @@ static void init_cpu(int cpu) | |||
293 | return; | 317 | return; |
294 | } | 318 | } |
295 | 319 | ||
320 | if (read_page) { | ||
321 | init_read(cpu); | ||
322 | return; | ||
323 | } | ||
324 | |||
296 | cpu_data[cpu].page = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, | 325 | cpu_data[cpu].page = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, |
297 | input_fd, cpu_data[cpu].offset); | 326 | input_fd, cpu_data[cpu].offset); |
298 | if (cpu_data[cpu].page == MAP_FAILED) | 327 | if (cpu_data[cpu].page == MAP_FAILED) { |
299 | die("failed to mmap cpu %d at offset 0x%llx", | 328 | /* fall back to just reading pages */ |
300 | cpu, cpu_data[cpu].offset); | 329 | fprintf(stderr, "Can not mmap file, will read instead\n"); |
330 | read_page = 1; | ||
331 | |||
332 | init_read(cpu); | ||
333 | } | ||
334 | } | ||
335 | |||
336 | static void update_cpu_data_index(int cpu) | ||
337 | { | ||
338 | cpu_data[cpu].offset += PAGE_SIZE; | ||
339 | cpu_data[cpu].size -= PAGE_SIZE; | ||
340 | cpu_data[cpu].index = 0; | ||
301 | } | 341 | } |
302 | 342 | ||
303 | static void get_next_page(int cpu) | 343 | static void get_next_page(int cpu) |
304 | { | 344 | { |
345 | off64_t save_seek; | ||
346 | off64_t ret; | ||
347 | |||
305 | if (!cpu_data[cpu].page) | 348 | if (!cpu_data[cpu].page) |
306 | return; | 349 | return; |
307 | 350 | ||
351 | if (read_page) { | ||
352 | if (cpu_data[cpu].size <= PAGE_SIZE) { | ||
353 | free(cpu_data[cpu].page); | ||
354 | cpu_data[cpu].page = NULL; | ||
355 | return; | ||
356 | } | ||
357 | |||
358 | update_cpu_data_index(cpu); | ||
359 | |||
360 | /* other parts of the code may expect the pointer to not move */ | ||
361 | save_seek = lseek64(input_fd, 0, SEEK_CUR); | ||
362 | |||
363 | ret = lseek64(input_fd, cpu_data[cpu].offset, SEEK_SET); | ||
364 | if (ret < 0) | ||
365 | die("failed to lseek"); | ||
366 | ret = read(input_fd, cpu_data[cpu].page, PAGE_SIZE); | ||
367 | if (ret < 0) | ||
368 | die("failed to read page"); | ||
369 | |||
370 | /* reset the file pointer back */ | ||
371 | lseek64(input_fd, save_seek, SEEK_SET); | ||
372 | |||
373 | return; | ||
374 | } | ||
375 | |||
308 | munmap(cpu_data[cpu].page, PAGE_SIZE); | 376 | munmap(cpu_data[cpu].page, PAGE_SIZE); |
309 | cpu_data[cpu].page = NULL; | 377 | cpu_data[cpu].page = NULL; |
310 | 378 | ||
311 | if (cpu_data[cpu].size <= PAGE_SIZE) | 379 | if (cpu_data[cpu].size <= PAGE_SIZE) |
312 | return; | 380 | return; |
313 | 381 | ||
314 | cpu_data[cpu].offset += PAGE_SIZE; | 382 | update_cpu_data_index(cpu); |
315 | cpu_data[cpu].size -= PAGE_SIZE; | ||
316 | cpu_data[cpu].index = 0; | ||
317 | 383 | ||
318 | cpu_data[cpu].page = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, | 384 | cpu_data[cpu].page = mmap(NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, |
319 | input_fd, cpu_data[cpu].offset); | 385 | input_fd, cpu_data[cpu].offset); |