[v2] powerpc/64s/radix: Fix MADV_[FREE|DONTNEED] TLB flush miss problem with THP

Message ID 20180614032256.5440-1-npiggin@gmail.com
State Changes Requested
Headers show
Series
  • [v2] powerpc/64s/radix: Fix MADV_[FREE|DONTNEED] TLB flush miss problem with THP
Related show

Commit Message

Nicholas Piggin June 14, 2018, 3:22 a.m.
The patch 99baac21e4 ("mm: fix MADV_[FREE|DONTNEED] TLB flush miss
problem") added a force flush mode to the mmu_gather flush, which
unconditionally flushes the entire address range being invalidated
(even if actual ptes only covered a smaller range), to solve a problem
with concurrent threads invalidating the same PTEs causing them to
miss TLBs that need flushing.

This does not work with powerpc that invalidates mmu_gather batches
according to page size. Have powerpc flush all possible page sizes in
the range if it encounters this concurrency condition.

Patch 4647706ebe ("mm: always flush VMA ranges affected by
zap_page_range") does add a TLB flush for all page sizes on powerpc for
the zap_page_range case, but that is to be removed and replaced with
the mmu_gather flush to avoid redundant flushing. It is also thought to
not cover other obscure race conditions:

https://lkml.kernel.org/r/BD3A0EBE-ECF4-41D4-87FA-C755EA9AB6BD@gmail.com

Hash does not have a problem because it invalidates TLBs inside the
page table locks.

Reported-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
Since v1:
- Compile fix or !THP
- Fixed missing PWC flush case
- Fixed concurrent TLB flush test
- Expanded changelog

I think this is a required fix for existing kernels, at least to be
safe and bring the flushig in to line with other architctures I
think we should add this as a fix. For the next kernel release I will
remove the duplicate flush in zap_page_range so this would definitely
be needed.

 arch/powerpc/mm/tlb-radix.c | 92 +++++++++++++++++++++++++++++--------
 include/linux/huge_mm.h     | 10 +---
 2 files changed, 76 insertions(+), 26 deletions(-)

Comments

kbuild test robot June 14, 2018, 5:43 a.m. | #1
Hi Nicholas,

I love your patch! Yet something to improve:

[auto build test ERROR on powerpc/next]
[also build test ERROR on next-20180613]
[cannot apply to v4.17]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-64s-radix-Fix-MADV_-FREE-DONTNEED-TLB-flush-miss-problem-with-THP/20180614-114728
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: arm-allnoconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.2.0 make.cross ARCH=arm 

All error/warnings (new ones prefixed by >>):

   In file included from include/linux/mm.h:478:0,
                    from include/linux/memcontrol.h:29,
                    from include/linux/swap.h:9,
                    from mm/compaction.c:12:
   include/linux/migrate.h: In function 'new_page_nodemask':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'PUD_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/migrate.h:47:11: note: in expansion of macro 'HPAGE_PMD_ORDER'
      order = HPAGE_PMD_ORDER;
              ^~~~~~~~~~~~~~~
   include/linux/huge_mm.h:82:25: note: each undeclared identifier is reported only once for each function it appears in
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/migrate.h:47:11: note: in expansion of macro 'HPAGE_PMD_ORDER'
      order = HPAGE_PMD_ORDER;
              ^~~~~~~~~~~~~~~
--
   In file included from include/linux/mm.h:478:0,
                    from include/linux/dax.h:6,
                    from mm/filemap.c:14:
   mm/filemap.c: In function 'page_cache_free_page':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'PUD_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/huge_mm.h:80:26: note: in expansion of macro 'HPAGE_PMD_ORDER'
    #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
                             ^~~~~~~~~~~~~~~
>> mm/filemap.c:279:22: note: in expansion of macro 'HPAGE_PMD_NR'
      page_ref_sub(page, HPAGE_PMD_NR);
                         ^~~~~~~~~~~~
   include/linux/huge_mm.h:82:25: note: each undeclared identifier is reported only once for each function it appears in
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/huge_mm.h:80:26: note: in expansion of macro 'HPAGE_PMD_ORDER'
    #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
                             ^~~~~~~~~~~~~~~
>> mm/filemap.c:279:22: note: in expansion of macro 'HPAGE_PMD_NR'
      page_ref_sub(page, HPAGE_PMD_NR);
                         ^~~~~~~~~~~~
   mm/filemap.c: In function 'page_cache_tree_delete_batch':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'PUD_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/huge_mm.h:80:26: note: in expansion of macro 'HPAGE_PMD_ORDER'
    #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
                             ^~~~~~~~~~~~~~~
   mm/filemap.c:351:18: note: in expansion of macro 'HPAGE_PMD_NR'
        tail_pages = HPAGE_PMD_NR - 1;
                     ^~~~~~~~~~~~
--
   In file included from include/linux/mm.h:478:0,
                    from include/linux/dax.h:6,
                    from mm/truncate.c:12:
   mm/truncate.c: In function 'truncate_cleanup_page':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'PUD_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/huge_mm.h:80:26: note: in expansion of macro 'HPAGE_PMD_ORDER'
    #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
                             ^~~~~~~~~~~~~~~
>> mm/truncate.c:182:38: note: in expansion of macro 'HPAGE_PMD_NR'
      pgoff_t nr = PageTransHuge(page) ? HPAGE_PMD_NR : 1;
                                         ^~~~~~~~~~~~
   include/linux/huge_mm.h:82:25: note: each undeclared identifier is reported only once for each function it appears in
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/huge_mm.h:80:26: note: in expansion of macro 'HPAGE_PMD_ORDER'
    #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
                             ^~~~~~~~~~~~~~~
>> mm/truncate.c:182:38: note: in expansion of macro 'HPAGE_PMD_NR'
      pgoff_t nr = PageTransHuge(page) ? HPAGE_PMD_NR : 1;
                                         ^~~~~~~~~~~~
   mm/truncate.c: In function 'invalidate_mapping_pages':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'PUD_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/huge_mm.h:80:26: note: in expansion of macro 'HPAGE_PMD_ORDER'
    #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
                             ^~~~~~~~~~~~~~~
   mm/truncate.c:580:14: note: in expansion of macro 'HPAGE_PMD_NR'
        index += HPAGE_PMD_NR - 1;
                 ^~~~~~~~~~~~
--
   In file included from include/linux/mm.h:478:0,
                    from mm/vmscan.c:17:
   include/linux/migrate.h: In function 'new_page_nodemask':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'PUD_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/migrate.h:47:11: note: in expansion of macro 'HPAGE_PMD_ORDER'
      order = HPAGE_PMD_ORDER;
              ^~~~~~~~~~~~~~~
   include/linux/huge_mm.h:82:25: note: each undeclared identifier is reported only once for each function it appears in
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/migrate.h:47:11: note: in expansion of macro 'HPAGE_PMD_ORDER'
      order = HPAGE_PMD_ORDER;
              ^~~~~~~~~~~~~~~
   mm/vmscan.c: In function 'is_page_cache_freeable':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'PUD_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/huge_mm.h:80:26: note: in expansion of macro 'HPAGE_PMD_ORDER'
    #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
                             ^~~~~~~~~~~~~~~
>> mm/vmscan.c:579:3: note: in expansion of macro 'HPAGE_PMD_NR'
      HPAGE_PMD_NR : 1;
      ^~~~~~~~~~~~
   mm/vmscan.c: In function '__remove_mapping':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'PUD_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
>> include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
>> include/linux/huge_mm.h:80:26: note: in expansion of macro 'HPAGE_PMD_ORDER'
    #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
                             ^~~~~~~~~~~~~~~
   mm/vmscan.c:742:18: note: in expansion of macro 'HPAGE_PMD_NR'
      refcount = 1 + HPAGE_PMD_NR;
                     ^~~~~~~~~~~~
--
   In file included from include/linux/mm.h:478:0,
                    from include/linux/pagemap.h:8,
                    from mm/shmem.c:29:
   mm/shmem.c: In function 'shmem_zero_setup':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'PUD_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
   include/linux/huge_mm.h:83:34: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_SIZE ((1UL) << HPAGE_PMD_SHIFT)
                                     ^~~~~~~~~~~~~~~
>> include/linux/huge_mm.h:84:27: note: in expansion of macro 'HPAGE_PMD_SIZE'
    #define HPAGE_PMD_MASK (~(HPAGE_PMD_SIZE - 1))
                              ^~~~~~~~~~~~~~
>> mm/shmem.c:4322:23: note: in expansion of macro 'HPAGE_PMD_MASK'
       ((vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK) <
                          ^~~~~~~~~~~~~~
   include/linux/huge_mm.h:82:25: note: each undeclared identifier is reported only once for each function it appears in
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^
   include/linux/huge_mm.h:83:34: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_SIZE ((1UL) << HPAGE_PMD_SHIFT)
                                     ^~~~~~~~~~~~~~~
>> include/linux/huge_mm.h:84:27: note: in expansion of macro 'HPAGE_PMD_SIZE'
    #define HPAGE_PMD_MASK (~(HPAGE_PMD_SIZE - 1))
                              ^~~~~~~~~~~~~~
>> mm/shmem.c:4322:23: note: in expansion of macro 'HPAGE_PMD_MASK'
       ((vma->vm_start + ~HPAGE_PMD_MASK) & HPAGE_PMD_MASK) <
                          ^~~~~~~~~~~~~~

vim +82 include/linux/huge_mm.h

5a6e75f8 Kirill A. Shutemov 2016-07-26  78  
d8c37c48 Naoya Horiguchi    2012-03-21 @79  #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
d8c37c48 Naoya Horiguchi    2012-03-21 @80  #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
d8c37c48 Naoya Horiguchi    2012-03-21  81  
fde52796 Aneesh Kumar K.V   2013-06-05 @82  #define HPAGE_PMD_SHIFT PMD_SHIFT
fde52796 Aneesh Kumar K.V   2013-06-05  83  #define HPAGE_PMD_SIZE	((1UL) << HPAGE_PMD_SHIFT)
fde52796 Aneesh Kumar K.V   2013-06-05 @84  #define HPAGE_PMD_MASK	(~(HPAGE_PMD_SIZE - 1))
71e3aac0 Andrea Arcangeli   2011-01-13  85  

:::::: The code at line 82 was first introduced by commit
:::::: fde52796d487b675cde55427e3347ff3e59f9a7f mm/THP: don't use HPAGE_SHIFT in transparent hugepage code

:::::: TO: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
:::::: CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
kbuild test robot June 14, 2018, 5:51 a.m. | #2
Hi Nicholas,

I love your patch! Yet something to improve:

[auto build test ERROR on powerpc/next]
[also build test ERROR on next-20180613]
[cannot apply to v4.17]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-64s-radix-Fix-MADV_-FREE-DONTNEED-TLB-flush-miss-problem-with-THP/20180614-114728
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: microblaze-nommu_defconfig (attached as .config)
compiler: microblaze-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=microblaze 

All errors (new ones prefixed by >>):

   In file included from include/linux/mm.h:478,
                    from arch/microblaze/include/asm/io.h:17,
                    from include/linux/clocksource.h:21,
                    from include/linux/clockchips.h:14,
                    from include/linux/tick.h:8,
                    from include/linux/sched/isolation.h:6,
                    from kernel/sched/sched.h:17,
                    from kernel/sched/loadavg.c:9:
   include/linux/migrate.h: In function 'new_page_nodemask':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'NMI_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^~~~~~~~~
   include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
   include/linux/migrate.h:47:11: note: in expansion of macro 'HPAGE_PMD_ORDER'
      order = HPAGE_PMD_ORDER;
              ^~~~~~~~~~~~~~~
   include/linux/huge_mm.h:82:25: note: each undeclared identifier is reported only once for each function it appears in
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^~~~~~~~~
   include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
   include/linux/migrate.h:47:11: note: in expansion of macro 'HPAGE_PMD_ORDER'
      order = HPAGE_PMD_ORDER;
              ^~~~~~~~~~~~~~~
--
   In file included from include/linux/mm.h:478,
                    from arch/microblaze/include/asm/io.h:17,
                    from include/linux/clocksource.h:21,
                    from include/linux/clockchips.h:14,
                    from include/linux/tick.h:8,
                    from include/linux/sched/isolation.h:6,
                    from kernel/sched/sched.h:17,
                    from kernel/sched/core.c:8:
   include/linux/migrate.h: In function 'new_page_nodemask':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'NMI_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^~~~~~~~~
   include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
   include/linux/migrate.h:47:11: note: in expansion of macro 'HPAGE_PMD_ORDER'
      order = HPAGE_PMD_ORDER;
              ^~~~~~~~~~~~~~~
   include/linux/huge_mm.h:82:25: note: each undeclared identifier is reported only once for each function it appears in
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^~~~~~~~~
   include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
   include/linux/migrate.h:47:11: note: in expansion of macro 'HPAGE_PMD_ORDER'
      order = HPAGE_PMD_ORDER;
              ^~~~~~~~~~~~~~~
   In file included from kernel/sched/sched.h:63,
                    from kernel/sched/core.c:8:
   kernel/sched/core.c: At top level:
   include/linux/syscalls.h:233:18: warning: 'sys_sched_rr_get_interval' alias between functions of incompatible types 'long int(pid_t,  struct timespec *)' {aka 'long int(int,  struct timespec *)'} and 'long int(long int,  long int)' [-Wattribute-alias]
     asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
                     ^~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:212:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel/sched/core.c:5274:1: note: in expansion of macro 'SYSCALL_DEFINE2'
    SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:238:18: note: aliased declaration here
     asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
                     ^~~~~~~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:212:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel/sched/core.c:5274:1: note: in expansion of macro 'SYSCALL_DEFINE2'
    SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:233:18: warning: 'sys_sched_getaffinity' alias between functions of incompatible types 'long int(pid_t,  unsigned int,  long unsigned int *)' {aka 'long int(int,  unsigned int,  long unsigned int *)'} and 'long int(long int,  long int,  long int)' [-Wattribute-alias]
     asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
                     ^~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:213:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel/sched/core.c:4909:1: note: in expansion of macro 'SYSCALL_DEFINE3'
    SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:238:18: note: aliased declaration here
     asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
                     ^~~~~~~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:213:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel/sched/core.c:4909:1: note: in expansion of macro 'SYSCALL_DEFINE3'
    SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:233:18: warning: 'sys_sched_setaffinity' alias between functions of incompatible types 'long int(pid_t,  unsigned int,  long unsigned int *)' {aka 'long int(int,  unsigned int,  long unsigned int *)'} and 'long int(long int,  long int,  long int)' [-Wattribute-alias]
     asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
                     ^~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:213:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel/sched/core.c:4857:1: note: in expansion of macro 'SYSCALL_DEFINE3'
    SYSCALL_DEFINE3(sched_setaffinity, pid_t, pid, unsigned int, len,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:238:18: note: aliased declaration here
     asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
                     ^~~~~~~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:213:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel/sched/core.c:4857:1: note: in expansion of macro 'SYSCALL_DEFINE3'
    SYSCALL_DEFINE3(sched_setaffinity, pid_t, pid, unsigned int, len,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:233:18: warning: 'sys_sched_getattr' alias between functions of incompatible types 'long int(pid_t,  struct sched_attr *, unsigned int,  unsigned int)' {aka 'long int(int,  struct sched_attr *, unsigned int,  unsigned int)'} and 'long int(long int,  long int,  long int,  long int)' [-Wattribute-alias]
     asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
                     ^~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:214:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)
--
   In file included from include/linux/mm.h:478,
                    from arch/microblaze/include/asm/io.h:17,
                    from include/linux/clocksource.h:21,
                    from include/linux/clockchips.h:14,
                    from include/linux/tick.h:8,
                    from include/linux/sched/isolation.h:6,
                    from kernel//sched/sched.h:17,
                    from kernel//sched/core.c:8:
   include/linux/migrate.h: In function 'new_page_nodemask':
>> include/linux/huge_mm.h:82:25: error: 'PMD_SHIFT' undeclared (first use in this function); did you mean 'NMI_SHIFT'?
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^~~~~~~~~
   include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
   include/linux/migrate.h:47:11: note: in expansion of macro 'HPAGE_PMD_ORDER'
      order = HPAGE_PMD_ORDER;
              ^~~~~~~~~~~~~~~
   include/linux/huge_mm.h:82:25: note: each undeclared identifier is reported only once for each function it appears in
    #define HPAGE_PMD_SHIFT PMD_SHIFT
                            ^~~~~~~~~
   include/linux/huge_mm.h:79:26: note: in expansion of macro 'HPAGE_PMD_SHIFT'
    #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
                             ^~~~~~~~~~~~~~~
   include/linux/migrate.h:47:11: note: in expansion of macro 'HPAGE_PMD_ORDER'
      order = HPAGE_PMD_ORDER;
              ^~~~~~~~~~~~~~~
   In file included from kernel//sched/sched.h:63,
                    from kernel//sched/core.c:8:
   kernel//sched/core.c: At top level:
   include/linux/syscalls.h:233:18: warning: 'sys_sched_rr_get_interval' alias between functions of incompatible types 'long int(pid_t,  struct timespec *)' {aka 'long int(int,  struct timespec *)'} and 'long int(long int,  long int)' [-Wattribute-alias]
     asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
                     ^~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:212:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel//sched/core.c:5274:1: note: in expansion of macro 'SYSCALL_DEFINE2'
    SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:238:18: note: aliased declaration here
     asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
                     ^~~~~~~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:212:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel//sched/core.c:5274:1: note: in expansion of macro 'SYSCALL_DEFINE2'
    SYSCALL_DEFINE2(sched_rr_get_interval, pid_t, pid,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:233:18: warning: 'sys_sched_getaffinity' alias between functions of incompatible types 'long int(pid_t,  unsigned int,  long unsigned int *)' {aka 'long int(int,  unsigned int,  long unsigned int *)'} and 'long int(long int,  long int,  long int)' [-Wattribute-alias]
     asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
                     ^~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:213:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel//sched/core.c:4909:1: note: in expansion of macro 'SYSCALL_DEFINE3'
    SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:238:18: note: aliased declaration here
     asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
                     ^~~~~~~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:213:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel//sched/core.c:4909:1: note: in expansion of macro 'SYSCALL_DEFINE3'
    SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:233:18: warning: 'sys_sched_setaffinity' alias between functions of incompatible types 'long int(pid_t,  unsigned int,  long unsigned int *)' {aka 'long int(int,  unsigned int,  long unsigned int *)'} and 'long int(long int,  long int,  long int)' [-Wattribute-alias]
     asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
                     ^~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:213:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel//sched/core.c:4857:1: note: in expansion of macro 'SYSCALL_DEFINE3'
    SYSCALL_DEFINE3(sched_setaffinity, pid_t, pid, unsigned int, len,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:238:18: note: aliased declaration here
     asmlinkage long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
                     ^~~~~~~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:213:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
                                       ^~~~~~~~~~~~~~~
   kernel//sched/core.c:4857:1: note: in expansion of macro 'SYSCALL_DEFINE3'
    SYSCALL_DEFINE3(sched_setaffinity, pid_t, pid, unsigned int, len,
    ^~~~~~~~~~~~~~~
   include/linux/syscalls.h:233:18: warning: 'sys_sched_getattr' alias between functions of incompatible types 'long int(pid_t,  struct sched_attr *, unsigned int,  unsigned int)' {aka 'long int(int,  struct sched_attr *, unsigned int,  unsigned int)'} and 'long int(long int,  long int,  long int,  long int)' [-Wattribute-alias]
     asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
                     ^~~
   include/linux/syscalls.h:222:2: note: in expansion of macro '__SYSCALL_DEFINEx'
     __SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
     ^~~~~~~~~~~~~~~~~
   include/linux/syscalls.h:214:36: note: in expansion of macro 'SYSCALL_DEFINEx'
    #define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)

vim +82 include/linux/huge_mm.h

d8c37c48 Naoya Horiguchi  2012-03-21  81  
fde52796 Aneesh Kumar K.V 2013-06-05 @82  #define HPAGE_PMD_SHIFT PMD_SHIFT
fde52796 Aneesh Kumar K.V 2013-06-05  83  #define HPAGE_PMD_SIZE	((1UL) << HPAGE_PMD_SHIFT)
fde52796 Aneesh Kumar K.V 2013-06-05  84  #define HPAGE_PMD_MASK	(~(HPAGE_PMD_SIZE - 1))
71e3aac0 Andrea Arcangeli 2011-01-13  85  

:::::: The code at line 82 was first introduced by commit
:::::: fde52796d487b675cde55427e3347ff3e59f9a7f mm/THP: don't use HPAGE_SHIFT in transparent hugepage code

:::::: TO: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
:::::: CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Nicholas Piggin June 14, 2018, 6:54 a.m. | #3
On Thu, 14 Jun 2018 13:51:40 +0800
kbuild test robot <lkp@intel.com> wrote:

> Hi Nicholas,
> 
> I love your patch! Yet something to improve:
> 
> [auto build test ERROR on powerpc/next]
> [also build test ERROR on next-20180613]
> [cannot apply to v4.17]
> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
> 
> url:    https://github.com/0day-ci/linux/commits/Nicholas-Piggin/powerpc-64s-radix-Fix-MADV_-FREE-DONTNEED-TLB-flush-miss-problem-with-THP/20180614-114728
> base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
> config: microblaze-nommu_defconfig (attached as .config)
> compiler: microblaze-linux-gcc (GCC) 8.1.0
> reproduce:
>         wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
>         chmod +x ~/bin/make.cross
>         # save the attached .config to linux build tree
>         GCC_VERSION=8.1.0 make.cross ARCH=microblaze 

Ooops, absent mindedly edited a header without thinking it's not
powerpc specific. Will fix it somehow.

Patch

diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c
index 67a6e86d3e7e..919232a59ea1 100644
--- a/arch/powerpc/mm/tlb-radix.c
+++ b/arch/powerpc/mm/tlb-radix.c
@@ -689,22 +689,17 @@  EXPORT_SYMBOL(radix__flush_tlb_kernel_range);
 static unsigned long tlb_single_page_flush_ceiling __read_mostly = 33;
 static unsigned long tlb_local_single_page_flush_ceiling __read_mostly = POWER9_TLB_SETS_RADIX * 2;
 
-void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
-		     unsigned long end)
+static inline void __radix__flush_tlb_range(struct mm_struct *mm,
+					unsigned long start, unsigned long end,
+					bool flush_all_sizes)
 
 {
-	struct mm_struct *mm = vma->vm_mm;
 	unsigned long pid;
 	unsigned int page_shift = mmu_psize_defs[mmu_virtual_psize].shift;
 	unsigned long page_size = 1UL << page_shift;
 	unsigned long nr_pages = (end - start) >> page_shift;
 	bool local, full;
 
-#ifdef CONFIG_HUGETLB_PAGE
-	if (is_vm_hugetlb_page(vma))
-		return radix__flush_hugetlb_tlb_range(vma, start, end);
-#endif
-
 	pid = mm->context.id;
 	if (unlikely(pid == MMU_NO_CONTEXT))
 		return;
@@ -738,16 +733,27 @@  void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 				_tlbie_pid(pid, RIC_FLUSH_TLB);
 		}
 	} else {
-		bool hflush = false;
+		bool hflush = flush_all_sizes;
+		bool gflush = flush_all_sizes;
 		unsigned long hstart, hend;
+		unsigned long gstart, gend;
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-		hstart = (start + HPAGE_PMD_SIZE - 1) >> HPAGE_PMD_SHIFT;
-		hend = end >> HPAGE_PMD_SHIFT;
-		if (hstart < hend) {
-			hstart <<= HPAGE_PMD_SHIFT;
-			hend <<= HPAGE_PMD_SHIFT;
+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE)
+		if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
 			hflush = true;
+
+		if (hflush) {
+			hstart = (start + HPAGE_PMD_SIZE - 1) & HPAGE_PMD_MASK;
+			hend = end & HPAGE_PMD_MASK;
+			if (hstart == hend)
+				hflush = false;
+		}
+
+		if (gflush) {
+			gstart = (start + HPAGE_PUD_SIZE - 1) & HPAGE_PUD_MASK;
+			gend = end & HPAGE_PUD_MASK;
+			if (gstart == gend)
+				gflush = false;
 		}
 #endif
 
@@ -757,18 +763,36 @@  void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 			if (hflush)
 				__tlbiel_va_range(hstart, hend, pid,
 						HPAGE_PMD_SIZE, MMU_PAGE_2M);
+			if (gflush)
+				__tlbiel_va_range(gstart, gend, pid,
+						HPAGE_PUD_SIZE, MMU_PAGE_1G);
 			asm volatile("ptesync": : :"memory");
 		} else {
 			__tlbie_va_range(start, end, pid, page_size, mmu_virtual_psize);
 			if (hflush)
 				__tlbie_va_range(hstart, hend, pid,
 						HPAGE_PMD_SIZE, MMU_PAGE_2M);
+			if (gflush)
+				__tlbie_va_range(gstart, gend, pid,
+						HPAGE_PUD_SIZE, MMU_PAGE_1G);
 			fixup_tlbie();
 			asm volatile("eieio; tlbsync; ptesync": : :"memory");
 		}
 	}
 	preempt_enable();
 }
+
+void radix__flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+		     unsigned long end)
+
+{
+#ifdef CONFIG_HUGETLB_PAGE
+	if (is_vm_hugetlb_page(vma))
+		return radix__flush_hugetlb_tlb_range(vma, start, end);
+#endif
+
+	__radix__flush_tlb_range(vma->vm_mm, start, end, false);
+}
 EXPORT_SYMBOL(radix__flush_tlb_range);
 
 static int radix_get_mmu_psize(int page_size)
@@ -837,6 +861,8 @@  void radix__tlb_flush(struct mmu_gather *tlb)
 	int psize = 0;
 	struct mm_struct *mm = tlb->mm;
 	int page_size = tlb->page_size;
+	unsigned long start = tlb->start;
+	unsigned long end = tlb->end;
 
 	/*
 	 * if page size is not something we understand, do a full mm flush
@@ -847,15 +873,45 @@  void radix__tlb_flush(struct mmu_gather *tlb)
 	 */
 	if (tlb->fullmm) {
 		__flush_all_mm(mm, true);
+#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE)
+	} else if (mm_tlb_flush_nested(mm)) {
+		/*
+		 * If there is a concurrent invalidation that is clearing ptes,
+		 * then it's possible this invalidation will miss one of those
+		 * cleared ptes and miss flushing the TLB. If this invalidate
+		 * returns before the other one flushes TLBs, that can result
+		 * in it returning while there are still valid TLBs inside the
+		 * range to be invalidated.
+		 *
+		 * See mm/memory.c:tlb_finish_mmu() for more details.
+		 *
+		 * The solution to this is ensure the entire range is always
+		 * flushed here. The problem for powerpc is that the flushes
+		 * are page size specific, so this "forced flush" would not
+		 * do the right thing if there are a mix of page sizes in
+		 * the range to be invalidated. So use __flush_tlb_range
+		 * which invalidates all possible page sizes in the range.
+		 *
+		 * PWC flush probably is not be required because the core code
+		 * shouldn't free page tables in this path, but accounting
+		 * for the possibility makes us a bit more robust.
+		 *
+		 * need_flush_all is an uncommon case because page table
+		 * teardown should be done with exclusive locks held (but
+		 * after locks are dropped another invalidate could come
+		 * in), it could be optimized further if necessary.
+		 */
+		if (!tlb->need_flush_all)
+			__radix__flush_tlb_range(mm, start, end, true);
+		else
+			radix__flush_all_mm(mm);
+#endif
 	} else if ( (psize = radix_get_mmu_psize(page_size)) == -1) {
 		if (!tlb->need_flush_all)
 			radix__flush_tlb_mm(mm);
 		else
 			radix__flush_all_mm(mm);
 	} else {
-		unsigned long start = tlb->start;
-		unsigned long end = tlb->end;
-
 		if (!tlb->need_flush_all)
 			radix__flush_tlb_range_psize(mm, start, end, psize);
 		else
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index a8a126259bc4..f7fe2b20efb3 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -79,7 +79,6 @@  extern struct kobj_attribute shmem_enabled_attr;
 #define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
 #define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define HPAGE_PMD_SHIFT PMD_SHIFT
 #define HPAGE_PMD_SIZE	((1UL) << HPAGE_PMD_SHIFT)
 #define HPAGE_PMD_MASK	(~(HPAGE_PMD_SIZE - 1))
@@ -88,6 +87,8 @@  extern struct kobj_attribute shmem_enabled_attr;
 #define HPAGE_PUD_SIZE	((1UL) << HPAGE_PUD_SHIFT)
 #define HPAGE_PUD_MASK	(~(HPAGE_PUD_SIZE - 1))
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+
 extern bool is_vma_temporary_stack(struct vm_area_struct *vma);
 
 extern unsigned long transparent_hugepage_flags;
@@ -246,13 +247,6 @@  static inline bool thp_migration_supported(void)
 }
 
 #else /* CONFIG_TRANSPARENT_HUGEPAGE */
-#define HPAGE_PMD_SHIFT ({ BUILD_BUG(); 0; })
-#define HPAGE_PMD_MASK ({ BUILD_BUG(); 0; })
-#define HPAGE_PMD_SIZE ({ BUILD_BUG(); 0; })
-
-#define HPAGE_PUD_SHIFT ({ BUILD_BUG(); 0; })
-#define HPAGE_PUD_MASK ({ BUILD_BUG(); 0; })
-#define HPAGE_PUD_SIZE ({ BUILD_BUG(); 0; })
 
 #define hpage_nr_pages(x) 1