Skip to content

Commit ff61541

Browse files
virtuosoPeter Zijlstra
authored andcommitted
perf/x86/intel/bts: Fix the use of page_private()
Commit 8062382 ("perf/x86/intel/bts: Add BTS PMU driver") brought in a warning with the BTS buffer initialization that is easily tripped with (assuming KPTI is disabled): instantly throwing: > ------------[ cut here ]------------ > WARNING: CPU: 2 PID: 326 at arch/x86/events/intel/bts.c:86 bts_buffer_setup_aux+0x117/0x3d0 > Modules linked in: > CPU: 2 PID: 326 Comm: perf Not tainted 5.4.0-rc8-00291-gceb9e77324fa #904 > RIP: 0010:bts_buffer_setup_aux+0x117/0x3d0 > Call Trace: > rb_alloc_aux+0x339/0x550 > perf_mmap+0x607/0xc70 > mmap_region+0x76b/0xbd0 ... It appears to assume (for lost raisins) that PagePrivate() is set, while later it actually tests for PagePrivate() before using page_private(). Make it consistent and always check PagePrivate() before using page_private(). Fixes: 8062382 ("perf/x86/intel/bts: Add BTS PMU driver") Signed-off-by: Alexander Shishkin <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Vince Weaver <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 1e69a0e commit ff61541

File tree

1 file changed

+11
-5
lines changed
  • arch/x86/events/intel

1 file changed

+11
-5
lines changed

arch/x86/events/intel/bts.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,17 @@ struct bts_buffer {
6363

6464
static struct pmu bts_pmu;
6565

66+
static int buf_nr_pages(struct page *page)
67+
{
68+
if (!PagePrivate(page))
69+
return 1;
70+
71+
return 1 << page_private(page);
72+
}
73+
6674
static size_t buf_size(struct page *page)
6775
{
68-
return 1 << (PAGE_SHIFT + page_private(page));
76+
return buf_nr_pages(page) * PAGE_SIZE;
6977
}
7078

7179
static void *
@@ -83,9 +91,7 @@ bts_buffer_setup_aux(struct perf_event *event, void **pages,
8391
/* count all the high order buffers */
8492
for (pg = 0, nbuf = 0; pg < nr_pages;) {
8593
page = virt_to_page(pages[pg]);
86-
if (WARN_ON_ONCE(!PagePrivate(page) && nr_pages > 1))
87-
return NULL;
88-
pg += 1 << page_private(page);
94+
pg += buf_nr_pages(page);
8995
nbuf++;
9096
}
9197

@@ -109,7 +115,7 @@ bts_buffer_setup_aux(struct perf_event *event, void **pages,
109115
unsigned int __nr_pages;
110116

111117
page = virt_to_page(pages[pg]);
112-
__nr_pages = PagePrivate(page) ? 1 << page_private(page) : 1;
118+
__nr_pages = buf_nr_pages(page);
113119
buf->buf[nbuf].page = page;
114120
buf->buf[nbuf].offset = offset;
115121
buf->buf[nbuf].displacement = (pad ? BTS_RECORD_SIZE - pad : 0);

0 commit comments

Comments
 (0)