Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'trace-v6.6-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace

Pull tracing fixes from Steven Rostedt:

- Fix the "bytes" output of the per_cpu stat file

The tracefs/per_cpu/cpu*/stats "bytes" was giving bogus values as the
accounting was not accurate. It is suppose to show how many used
bytes are still in the ring buffer, but even when the ring buffer was
empty it would still show there were bytes used.

- Fix a bug in eventfs where reading a dynamic event directory (open)
and then creating a dynamic event that goes into that diretory screws
up the accounting.

On close, the newly created event dentry will get a "dput" without
ever having a "dget" done for it. The fix is to allocate an array on
dir open to save what dentries were actually "dget" on, and what ones
to "dput" on close.

* tag 'trace-v6.6-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace:
eventfs: Remember what dentries were created on dir open
ring-buffer: Fix bytes info in per_cpu buffer stats

+85 -30
+70 -17
fs/tracefs/event_inode.c
··· 70 70 struct dentry *dentry, 71 71 unsigned int flags); 72 72 static int dcache_dir_open_wrapper(struct inode *inode, struct file *file); 73 + static int dcache_readdir_wrapper(struct file *file, struct dir_context *ctx); 73 74 static int eventfs_release(struct inode *inode, struct file *file); 74 75 75 76 static const struct inode_operations eventfs_root_dir_inode_operations = { ··· 80 79 static const struct file_operations eventfs_file_operations = { 81 80 .open = dcache_dir_open_wrapper, 82 81 .read = generic_read_dir, 83 - .iterate_shared = dcache_readdir, 82 + .iterate_shared = dcache_readdir_wrapper, 84 83 .llseek = generic_file_llseek, 85 84 .release = eventfs_release, 86 85 }; ··· 397 396 return ret; 398 397 } 399 398 399 + struct dentry_list { 400 + void *cursor; 401 + struct dentry **dentries; 402 + }; 403 + 400 404 /** 401 405 * eventfs_release - called to release eventfs file/dir 402 406 * @inode: inode to be released ··· 410 404 static int eventfs_release(struct inode *inode, struct file *file) 411 405 { 412 406 struct tracefs_inode *ti; 413 - struct eventfs_inode *ei; 414 - struct eventfs_file *ef; 415 - struct dentry *dentry; 416 - int idx; 407 + struct dentry_list *dlist = file->private_data; 408 + void *cursor; 409 + int i; 417 410 418 411 ti = get_tracefs(inode); 419 412 if (!(ti->flags & TRACEFS_EVENT_INODE)) 420 413 return -EINVAL; 421 414 422 - ei = ti->private; 423 - idx = srcu_read_lock(&eventfs_srcu); 424 - list_for_each_entry_srcu(ef, &ei->e_top_files, list, 425 - srcu_read_lock_held(&eventfs_srcu)) { 426 - mutex_lock(&eventfs_mutex); 427 - dentry = ef->dentry; 428 - mutex_unlock(&eventfs_mutex); 429 - if (dentry) 430 - dput(dentry); 415 + if (WARN_ON_ONCE(!dlist)) 416 + return -EINVAL; 417 + 418 + for (i = 0; dlist->dentries[i]; i++) { 419 + dput(dlist->dentries[i]); 431 420 } 432 - srcu_read_unlock(&eventfs_srcu, idx); 421 + 422 + cursor = dlist->cursor; 423 + kfree(dlist->dentries); 424 + kfree(dlist); 425 + file->private_data = cursor; 433 426 return dcache_dir_close(inode, file); 434 427 } 435 428 ··· 447 442 struct tracefs_inode *ti; 448 443 struct eventfs_inode *ei; 449 444 struct eventfs_file *ef; 445 + struct dentry_list *dlist; 446 + struct dentry **dentries = NULL; 450 447 struct dentry *dentry = file_dentry(file); 448 + struct dentry *d; 451 449 struct inode *f_inode = file_inode(file); 450 + int cnt = 0; 452 451 int idx; 452 + int ret; 453 453 454 454 ti = get_tracefs(f_inode); 455 455 if (!(ti->flags & TRACEFS_EVENT_INODE)) 456 456 return -EINVAL; 457 457 458 + if (WARN_ON_ONCE(file->private_data)) 459 + return -EINVAL; 460 + 461 + dlist = kmalloc(sizeof(*dlist), GFP_KERNEL); 462 + if (!dlist) 463 + return -ENOMEM; 464 + 458 465 ei = ti->private; 459 466 idx = srcu_read_lock(&eventfs_srcu); 460 467 list_for_each_entry_srcu(ef, &ei->e_top_files, list, 461 468 srcu_read_lock_held(&eventfs_srcu)) { 462 - create_dentry(ef, dentry, false); 469 + d = create_dentry(ef, dentry, false); 470 + if (d) { 471 + struct dentry **tmp; 472 + 473 + tmp = krealloc(dentries, sizeof(d) * (cnt + 2), GFP_KERNEL); 474 + if (!tmp) 475 + break; 476 + tmp[cnt] = d; 477 + tmp[cnt + 1] = NULL; 478 + cnt++; 479 + dentries = tmp; 480 + } 463 481 } 464 482 srcu_read_unlock(&eventfs_srcu, idx); 465 - return dcache_dir_open(inode, file); 483 + ret = dcache_dir_open(inode, file); 484 + 485 + /* 486 + * dcache_dir_open() sets file->private_data to a dentry cursor. 487 + * Need to save that but also save all the dentries that were 488 + * opened by this function. 489 + */ 490 + dlist->cursor = file->private_data; 491 + dlist->dentries = dentries; 492 + file->private_data = dlist; 493 + return ret; 494 + } 495 + 496 + /* 497 + * This just sets the file->private_data back to the cursor and back. 498 + */ 499 + static int dcache_readdir_wrapper(struct file *file, struct dir_context *ctx) 500 + { 501 + struct dentry_list *dlist = file->private_data; 502 + int ret; 503 + 504 + file->private_data = dlist->cursor; 505 + ret = dcache_readdir(file, ctx); 506 + dlist->cursor = file->private_data; 507 + file->private_data = dlist; 508 + return ret; 466 509 } 467 510 468 511 /**
+15 -13
kernel/trace/ring_buffer.c
··· 354 354 local_set(&bpage->commit, 0); 355 355 } 356 356 357 + static __always_inline unsigned int rb_page_commit(struct buffer_page *bpage) 358 + { 359 + return local_read(&bpage->page->commit); 360 + } 361 + 357 362 static void free_buffer_page(struct buffer_page *bpage) 358 363 { 359 364 free_page((unsigned long)bpage->page); ··· 2008 2003 * Increment overrun to account for the lost events. 2009 2004 */ 2010 2005 local_add(page_entries, &cpu_buffer->overrun); 2011 - local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); 2006 + local_sub(rb_page_commit(to_remove_page), &cpu_buffer->entries_bytes); 2012 2007 local_inc(&cpu_buffer->pages_lost); 2013 2008 } 2014 2009 ··· 2372 2367 cpu_buffer->reader_page->read); 2373 2368 } 2374 2369 2375 - static __always_inline unsigned rb_page_commit(struct buffer_page *bpage) 2376 - { 2377 - return local_read(&bpage->page->commit); 2378 - } 2379 - 2380 2370 static struct ring_buffer_event * 2381 2371 rb_iter_head_event(struct ring_buffer_iter *iter) 2382 2372 { ··· 2517 2517 * the counters. 2518 2518 */ 2519 2519 local_add(entries, &cpu_buffer->overrun); 2520 - local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes); 2520 + local_sub(rb_page_commit(next_page), &cpu_buffer->entries_bytes); 2521 2521 local_inc(&cpu_buffer->pages_lost); 2522 2522 2523 2523 /* ··· 2660 2660 2661 2661 event = __rb_page_index(tail_page, tail); 2662 2662 2663 - /* account for padding bytes */ 2664 - local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes); 2665 - 2666 2663 /* 2667 2664 * Save the original length to the meta data. 2668 2665 * This will be used by the reader to add lost event ··· 2673 2676 * write counter enough to allow another writer to slip 2674 2677 * in on this page. 2675 2678 * We put in a discarded commit instead, to make sure 2676 - * that this space is not used again. 2679 + * that this space is not used again, and this space will 2680 + * not be accounted into 'entries_bytes'. 2677 2681 * 2678 2682 * If we are less than the minimum size, we don't need to 2679 2683 * worry about it. ··· 2698 2700 event->type_len = RINGBUF_TYPE_PADDING; 2699 2701 /* time delta must be non zero */ 2700 2702 event->time_delta = 1; 2703 + 2704 + /* account for padding bytes */ 2705 + local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes); 2701 2706 2702 2707 /* Make sure the padding is visible before the tail_page->write update */ 2703 2708 smp_wmb(); ··· 4216 4215 EXPORT_SYMBOL_GPL(ring_buffer_oldest_event_ts); 4217 4216 4218 4217 /** 4219 - * ring_buffer_bytes_cpu - get the number of bytes consumed in a cpu buffer 4218 + * ring_buffer_bytes_cpu - get the number of bytes unconsumed in a cpu buffer 4220 4219 * @buffer: The ring buffer 4221 4220 * @cpu: The per CPU buffer to read from. 4222 4221 */ ··· 4724 4723 4725 4724 length = rb_event_length(event); 4726 4725 cpu_buffer->reader_page->read += length; 4726 + cpu_buffer->read_bytes += length; 4727 4727 } 4728 4728 4729 4729 static void rb_advance_iter(struct ring_buffer_iter *iter) ··· 5818 5816 } else { 5819 5817 /* update the entry counter */ 5820 5818 cpu_buffer->read += rb_page_entries(reader); 5821 - cpu_buffer->read_bytes += BUF_PAGE_SIZE; 5819 + cpu_buffer->read_bytes += rb_page_commit(reader); 5822 5820 5823 5821 /* swap the pages */ 5824 5822 rb_init_page(bpage);