|
@@ -6343,7 +6343,7 @@ static u64 perf_virt_to_phys(u64 virt)
|
|
|
|
|
|
static struct perf_callchain_entry __empty_callchain = { .nr = 0, };
|
|
static struct perf_callchain_entry __empty_callchain = { .nr = 0, };
|
|
|
|
|
|
-static struct perf_callchain_entry *
|
|
|
|
|
|
+struct perf_callchain_entry *
|
|
perf_callchain(struct perf_event *event, struct pt_regs *regs)
|
|
perf_callchain(struct perf_event *event, struct pt_regs *regs)
|
|
{
|
|
{
|
|
bool kernel = !event->attr.exclude_callchain_kernel;
|
|
bool kernel = !event->attr.exclude_callchain_kernel;
|
|
@@ -6382,7 +6382,9 @@ void perf_prepare_sample(struct perf_event_header *header,
|
|
if (sample_type & PERF_SAMPLE_CALLCHAIN) {
|
|
if (sample_type & PERF_SAMPLE_CALLCHAIN) {
|
|
int size = 1;
|
|
int size = 1;
|
|
|
|
|
|
- data->callchain = perf_callchain(event, regs);
|
|
|
|
|
|
+ if (!(sample_type & __PERF_SAMPLE_CALLCHAIN_EARLY))
|
|
|
|
+ data->callchain = perf_callchain(event, regs);
|
|
|
|
+
|
|
size += data->callchain->nr;
|
|
size += data->callchain->nr;
|
|
|
|
|
|
header->size += size * sizeof(u64);
|
|
header->size += size * sizeof(u64);
|
|
@@ -7335,6 +7337,10 @@ static bool perf_addr_filter_match(struct perf_addr_filter *filter,
|
|
struct file *file, unsigned long offset,
|
|
struct file *file, unsigned long offset,
|
|
unsigned long size)
|
|
unsigned long size)
|
|
{
|
|
{
|
|
|
|
+ /* d_inode(NULL) won't be equal to any mapped user-space file */
|
|
|
|
+ if (!filter->path.dentry)
|
|
|
|
+ return false;
|
|
|
|
+
|
|
if (d_inode(filter->path.dentry) != file_inode(file))
|
|
if (d_inode(filter->path.dentry) != file_inode(file))
|
|
return false;
|
|
return false;
|
|
|
|
|