Skip to content

Commit 5edc6bb

Browse files
committed
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
2 parents 2ad78f8 + ef36b4f commit 5edc6bb

File tree

2 files changed

+85
-30
lines changed

2 files changed

+85
-30
lines changed

fs/tracefs/event_inode.c

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ static struct dentry *eventfs_root_lookup(struct inode *dir,
7070
struct dentry *dentry,
7171
unsigned int flags);
7272
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);
7374
static int eventfs_release(struct inode *inode, struct file *file);
7475

7576
static const struct inode_operations eventfs_root_dir_inode_operations = {
@@ -79,7 +80,7 @@ static const struct inode_operations eventfs_root_dir_inode_operations = {
7980
static const struct file_operations eventfs_file_operations = {
8081
.open = dcache_dir_open_wrapper,
8182
.read = generic_read_dir,
82-
.iterate_shared = dcache_readdir,
83+
.iterate_shared = dcache_readdir_wrapper,
8384
.llseek = generic_file_llseek,
8485
.release = eventfs_release,
8586
};
@@ -396,6 +397,11 @@ static struct dentry *eventfs_root_lookup(struct inode *dir,
396397
return ret;
397398
}
398399

400+
struct dentry_list {
401+
void *cursor;
402+
struct dentry **dentries;
403+
};
404+
399405
/**
400406
* eventfs_release - called to release eventfs file/dir
401407
* @inode: inode to be released
@@ -404,26 +410,25 @@ static struct dentry *eventfs_root_lookup(struct inode *dir,
404410
static int eventfs_release(struct inode *inode, struct file *file)
405411
{
406412
struct tracefs_inode *ti;
407-
struct eventfs_inode *ei;
408-
struct eventfs_file *ef;
409-
struct dentry *dentry;
410-
int idx;
413+
struct dentry_list *dlist = file->private_data;
414+
void *cursor;
415+
int i;
411416

412417
ti = get_tracefs(inode);
413418
if (!(ti->flags & TRACEFS_EVENT_INODE))
414419
return -EINVAL;
415420

416-
ei = ti->private;
417-
idx = srcu_read_lock(&eventfs_srcu);
418-
list_for_each_entry_srcu(ef, &ei->e_top_files, list,
419-
srcu_read_lock_held(&eventfs_srcu)) {
420-
mutex_lock(&eventfs_mutex);
421-
dentry = ef->dentry;
422-
mutex_unlock(&eventfs_mutex);
423-
if (dentry)
424-
dput(dentry);
421+
if (WARN_ON_ONCE(!dlist))
422+
return -EINVAL;
423+
424+
for (i = 0; dlist->dentries[i]; i++) {
425+
dput(dlist->dentries[i]);
425426
}
426-
srcu_read_unlock(&eventfs_srcu, idx);
427+
428+
cursor = dlist->cursor;
429+
kfree(dlist->dentries);
430+
kfree(dlist);
431+
file->private_data = cursor;
427432
return dcache_dir_close(inode, file);
428433
}
429434

@@ -442,22 +447,70 @@ static int dcache_dir_open_wrapper(struct inode *inode, struct file *file)
442447
struct tracefs_inode *ti;
443448
struct eventfs_inode *ei;
444449
struct eventfs_file *ef;
450+
struct dentry_list *dlist;
451+
struct dentry **dentries = NULL;
445452
struct dentry *dentry = file_dentry(file);
453+
struct dentry *d;
446454
struct inode *f_inode = file_inode(file);
455+
int cnt = 0;
447456
int idx;
457+
int ret;
448458

449459
ti = get_tracefs(f_inode);
450460
if (!(ti->flags & TRACEFS_EVENT_INODE))
451461
return -EINVAL;
452462

463+
if (WARN_ON_ONCE(file->private_data))
464+
return -EINVAL;
465+
466+
dlist = kmalloc(sizeof(*dlist), GFP_KERNEL);
467+
if (!dlist)
468+
return -ENOMEM;
469+
453470
ei = ti->private;
454471
idx = srcu_read_lock(&eventfs_srcu);
455472
list_for_each_entry_srcu(ef, &ei->e_top_files, list,
456473
srcu_read_lock_held(&eventfs_srcu)) {
457-
create_dentry(ef, dentry, false);
474+
d = create_dentry(ef, dentry, false);
475+
if (d) {
476+
struct dentry **tmp;
477+
478+
tmp = krealloc(dentries, sizeof(d) * (cnt + 2), GFP_KERNEL);
479+
if (!tmp)
480+
break;
481+
tmp[cnt] = d;
482+
tmp[cnt + 1] = NULL;
483+
cnt++;
484+
dentries = tmp;
485+
}
458486
}
459487
srcu_read_unlock(&eventfs_srcu, idx);
460-
return dcache_dir_open(inode, file);
488+
ret = dcache_dir_open(inode, file);
489+
490+
/*
491+
* dcache_dir_open() sets file->private_data to a dentry cursor.
492+
* Need to save that but also save all the dentries that were
493+
* opened by this function.
494+
*/
495+
dlist->cursor = file->private_data;
496+
dlist->dentries = dentries;
497+
file->private_data = dlist;
498+
return ret;
499+
}
500+
501+
/*
502+
* This just sets the file->private_data back to the cursor and back.
503+
*/
504+
static int dcache_readdir_wrapper(struct file *file, struct dir_context *ctx)
505+
{
506+
struct dentry_list *dlist = file->private_data;
507+
int ret;
508+
509+
file->private_data = dlist->cursor;
510+
ret = dcache_readdir(file, ctx);
511+
dlist->cursor = file->private_data;
512+
file->private_data = dlist;
513+
return ret;
461514
}
462515

463516
/**

kernel/trace/ring_buffer.c

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,11 @@ static void rb_init_page(struct buffer_data_page *bpage)
354354
local_set(&bpage->commit, 0);
355355
}
356356

357+
static __always_inline unsigned int rb_page_commit(struct buffer_page *bpage)
358+
{
359+
return local_read(&bpage->page->commit);
360+
}
361+
357362
static void free_buffer_page(struct buffer_page *bpage)
358363
{
359364
free_page((unsigned long)bpage->page);
@@ -2003,7 +2008,7 @@ rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
20032008
* Increment overrun to account for the lost events.
20042009
*/
20052010
local_add(page_entries, &cpu_buffer->overrun);
2006-
local_sub(BUF_PAGE_SIZE, &cpu_buffer->entries_bytes);
2011+
local_sub(rb_page_commit(to_remove_page), &cpu_buffer->entries_bytes);
20072012
local_inc(&cpu_buffer->pages_lost);
20082013
}
20092014

@@ -2367,11 +2372,6 @@ rb_reader_event(struct ring_buffer_per_cpu *cpu_buffer)
23672372
cpu_buffer->reader_page->read);
23682373
}
23692374

2370-
static __always_inline unsigned rb_page_commit(struct buffer_page *bpage)
2371-
{
2372-
return local_read(&bpage->page->commit);
2373-
}
2374-
23752375
static struct ring_buffer_event *
23762376
rb_iter_head_event(struct ring_buffer_iter *iter)
23772377
{
@@ -2517,7 +2517,7 @@ rb_handle_head_page(struct ring_buffer_per_cpu *cpu_buffer,
25172517
* the counters.
25182518
*/
25192519
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);
25212521
local_inc(&cpu_buffer->pages_lost);
25222522

25232523
/*
@@ -2660,9 +2660,6 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
26602660

26612661
event = __rb_page_index(tail_page, tail);
26622662

2663-
/* account for padding bytes */
2664-
local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes);
2665-
26662663
/*
26672664
* Save the original length to the meta data.
26682665
* This will be used by the reader to add lost event
@@ -2676,7 +2673,8 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
26762673
* write counter enough to allow another writer to slip
26772674
* in on this page.
26782675
* We put in a discarded commit instead, to make sure
2679-
* that this space is not used again.
2676+
* that this space is not used again, and this space will
2677+
* not be accounted into 'entries_bytes'.
26802678
*
26812679
* If we are less than the minimum size, we don't need to
26822680
* worry about it.
@@ -2701,6 +2699,9 @@ rb_reset_tail(struct ring_buffer_per_cpu *cpu_buffer,
27012699
/* time delta must be non zero */
27022700
event->time_delta = 1;
27032701

2702+
/* account for padding bytes */
2703+
local_add(BUF_PAGE_SIZE - tail, &cpu_buffer->entries_bytes);
2704+
27042705
/* Make sure the padding is visible before the tail_page->write update */
27052706
smp_wmb();
27062707

@@ -4215,7 +4216,7 @@ u64 ring_buffer_oldest_event_ts(struct trace_buffer *buffer, int cpu)
42154216
EXPORT_SYMBOL_GPL(ring_buffer_oldest_event_ts);
42164217

42174218
/**
4218-
* ring_buffer_bytes_cpu - get the number of bytes consumed in a cpu buffer
4219+
* ring_buffer_bytes_cpu - get the number of bytes unconsumed in a cpu buffer
42194220
* @buffer: The ring buffer
42204221
* @cpu: The per CPU buffer to read from.
42214222
*/
@@ -4723,6 +4724,7 @@ static void rb_advance_reader(struct ring_buffer_per_cpu *cpu_buffer)
47234724

47244725
length = rb_event_length(event);
47254726
cpu_buffer->reader_page->read += length;
4727+
cpu_buffer->read_bytes += length;
47264728
}
47274729

47284730
static void rb_advance_iter(struct ring_buffer_iter *iter)
@@ -5816,7 +5818,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
58165818
} else {
58175819
/* update the entry counter */
58185820
cpu_buffer->read += rb_page_entries(reader);
5819-
cpu_buffer->read_bytes += BUF_PAGE_SIZE;
5821+
cpu_buffer->read_bytes += rb_page_commit(reader);
58205822

58215823
/* swap the pages */
58225824
rb_init_page(bpage);

0 commit comments

Comments
 (0)