Re: [PATCH v8 13/14] lockdep: Move data of CONFIG_LOCKDEP_PAGELOCK from page to page_ext

2017-08-07 Thread kbuild test robot
Hi Byungchul,

[auto build test ERROR on linus/master]
[also build test ERROR on v4.13-rc4 next-20170807]
[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/Byungchul-Park/lockdep-Implement-crossrelease-feature/20170807-172617
config: alpha-allmodconfig (attached as .config)
compiler: alpha-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget 
https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=alpha 

All errors (new ones prefixed by >>):

   warning: (LOCKDEP_COMPLETE && LOCKDEP_PAGELOCK) selects LOCKDEP_CROSSRELEASE 
which has unmet direct dependencies (PROVE_LOCKING)
   warning: (LOCKDEP_COMPLETE && LOCKDEP_PAGELOCK) selects LOCKDEP_CROSSRELEASE 
which has unmet direct dependencies (PROVE_LOCKING)
   In file included from include/linux/srcutree.h:28:0,
from include/linux/srcu.h:62,
from include/linux/notifier.h:15,
from include/linux/memory_hotplug.h:6,
from include/linux/mmzone.h:771,
from include/linux/gfp.h:5,
from include/linux/mm.h:9,
from include/linux/pid_namespace.h:6,
from include/linux/ptrace.h:9,
from arch/alpha/kernel/asm-offsets.c:10:
   include/linux/completion.h:32:27: error: field 'map' has incomplete type
 struct lockdep_map_cross map;
  ^~~
   In file included from include/linux/mm.h:23:0,
from include/linux/pid_namespace.h:6,
from include/linux/ptrace.h:9,
from arch/alpha/kernel/asm-offsets.c:10:
>> include/linux/page_ext.h:49:27: error: field 'map' has incomplete type
 struct lockdep_map_cross map;
  ^~~
   make[2]: *** [arch/alpha/kernel/asm-offsets.s] Error 1
   make[2]: Target '__build' not remade because of errors.
   make[1]: *** [prepare0] Error 2
   make[1]: Target 'prepare' not remade because of errors.
   make: *** [sub-make] Error 2

vim +/map +49 include/linux/page_ext.h

37  
38  /*
39   * Page Extension can be considered as an extended mem_map.
40   * A page_ext page is associated with every page descriptor. The
41   * page_ext helps us add more information about the page.
42   * All page_ext are allocated at boot or memory hotplug event,
43   * then the page_ext for pfn always exists.
44   */
45  struct page_ext {
46  unsigned long flags;
47  
48  #ifdef CONFIG_LOCKDEP_PAGELOCK
  > 49  struct lockdep_map_cross map;
50  #endif
51  };
52  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: application/gzip


[PATCH v8 13/14] lockdep: Move data of CONFIG_LOCKDEP_PAGELOCK from page to page_ext

2017-08-07 Thread Byungchul Park
CONFIG_LOCKDEP_PAGELOCK needs to keep lockdep_map_cross per page. Since
it's a debug feature, it's preferred to keep it in struct page_ext than
struct page. Move it to struct page_ext.

Signed-off-by: Byungchul Park 
---
 include/linux/mm_types.h   |  4 ---
 include/linux/page-flags.h | 19 +++--
 include/linux/page_ext.h   |  4 +++
 include/linux/pagemap.h| 28 ---
 lib/Kconfig.debug  |  1 +
 mm/filemap.c   | 69 ++
 mm/page_alloc.c|  3 --
 mm/page_ext.c  |  4 +++
 8 files changed, 118 insertions(+), 14 deletions(-)

diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index f1e3dba..ac3121c 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -220,10 +220,6 @@ struct page {
 #ifdef LAST_CPUPID_NOT_IN_PAGE_FLAGS
int _last_cpupid;
 #endif
-
-#ifdef CONFIG_LOCKDEP_PAGELOCK
-   struct lockdep_map_cross map;
-#endif
 }
 /*
  * The struct page can be forced to be double word aligned so that atomic ops
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index b793342..879dd0d 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -374,28 +374,41 @@ static __always_inline int PageSwapCache(struct page 
*page)
 
 #ifdef CONFIG_LOCKDEP_PAGELOCK
 #include 
+#include 
 
 TESTPAGEFLAG(Locked, locked, PF_NO_TAIL)
 
 static __always_inline void __SetPageLocked(struct page *page)
 {
+   struct page_ext *e;
+
__set_bit(PG_locked, &PF_NO_TAIL(page, 1)->flags);
 
page = compound_head(page);
-   lock_acquire_exclusive((struct lockdep_map *)&page->map, 0, 1, NULL, 
_RET_IP_);
+   e = lookup_page_ext(page);
+   if (unlikely(!e))
+   return;
+
+   lock_acquire_exclusive((struct lockdep_map *)&e->map, 0, 1, NULL, 
_RET_IP_);
 }
 
 static __always_inline void __ClearPageLocked(struct page *page)
 {
+   struct page_ext *e;
+
__clear_bit(PG_locked, &PF_NO_TAIL(page, 1)->flags);
 
page = compound_head(page);
+   e = lookup_page_ext(page);
+   if (unlikely(!e))
+   return;
+
/*
 * lock_commit_crosslock() is necessary for crosslock
 * when the lock is released, before lock_release().
 */
-   lock_commit_crosslock((struct lockdep_map *)&page->map);
-   lock_release((struct lockdep_map *)&page->map, 0, _RET_IP_);
+   lock_commit_crosslock((struct lockdep_map *)&e->map);
+   lock_release((struct lockdep_map *)&e->map, 0, _RET_IP_);
 }
 #else
 __PAGEFLAG(Locked, locked, PF_NO_TAIL)
diff --git a/include/linux/page_ext.h b/include/linux/page_ext.h
index 9298c39..d1c52c8c 100644
--- a/include/linux/page_ext.h
+++ b/include/linux/page_ext.h
@@ -44,6 +44,10 @@ enum page_ext_flags {
  */
 struct page_ext {
unsigned long flags;
+
+#ifdef CONFIG_LOCKDEP_PAGELOCK
+   struct lockdep_map_cross map;
+#endif
 };
 
 extern void pgdat_page_ext_init(struct pglist_data *pgdat);
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 9f448c6..b75b8bc 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -16,6 +16,7 @@
 #include 
 #ifdef CONFIG_LOCKDEP_PAGELOCK
 #include 
+#include 
 #endif
 
 /*
@@ -454,28 +455,47 @@ static inline pgoff_t linear_page_index(struct 
vm_area_struct *vma,
 }
 
 #ifdef CONFIG_LOCKDEP_PAGELOCK
+extern struct page_ext_operations lockdep_pagelock_ops;
+
 #define lock_page_init(p)  \
 do {   \
static struct lock_class_key __key; \
-   lockdep_init_map_crosslock((struct lockdep_map *)&(p)->map, \
+   struct page_ext *e = lookup_page_ext(p);\
+   \
+   if (unlikely(!e))   \
+   break;  \
+   \
+   lockdep_init_map_crosslock((struct lockdep_map *)&(e)->map, \
"(PG_locked)" #p, &__key, 0);   \
 } while (0)
 
 static inline void lock_page_acquire(struct page *page, int try)
 {
+   struct page_ext *e;
+
page = compound_head(page);
-   lock_acquire_exclusive((struct lockdep_map *)&page->map, 0,
+   e = lookup_page_ext(page);
+   if (unlikely(!e))
+   return;
+
+   lock_acquire_exclusive((struct lockdep_map *)&e->map, 0,
   try, NULL, _RET_IP_);
 }
 
 static inline void lock_page_release(struct page *page)
 {
+   struct page_ext *e;
+
page = compound_head(page);
+   e = lookup_page_ext(page);
+   if (unlikely(!e))
+   return;
+
/*
 * lock_commit_crosslock() is necessary for crosslocks.
 */
-   lock_commit_crosslock((struct lo