Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1482305 > unrolled thread
| Started by | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| First post | 2016-09-13 11:50 +0200 |
| Last post | 2016-09-13 11:50 +0200 |
| Articles | 1 — 1 participant |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH v3 13/15] lockdep: Apply lock_acquire(release) on __Set(__Clear)PageLocked Byungchul Park <byungchul.park@lge.com> - 2016-09-13 11:50 +0200
| From | Byungchul Park <byungchul.park@lge.com> |
|---|---|
| Date | 2016-09-13 11:50 +0200 |
| Subject | [PATCH v3 13/15] lockdep: Apply lock_acquire(release) on __Set(__Clear)PageLocked |
| Message-ID | <sgSvL-8uI-3@gated-at.bofh.it> |
Usually PG_locked bit is updated by lock_page() or unlock_page().
However, it can be also updated through __SetPageLocked() or
__ClearPageLockded(). They have to be considered, to get paired between
acquire and release.
Furthermore, e.g. __SetPageLocked() in add_to_page_cache_lru() is called
frequently. We might miss many chances to check deadlock if we ignore it.
Consider __Set(__Clear)PageLockded as well.
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
include/linux/page-flags.h | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index e5a3244..e28f232 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -249,7 +249,6 @@ static inline int TestClearPage##uname(struct page *page) { return 0; }
#define TESTSCFLAG_FALSE(uname) \
TESTSETFLAG_FALSE(uname) TESTCLEARFLAG_FALSE(uname)
-__PAGEFLAG(Locked, locked, PF_NO_TAIL)
PAGEFLAG(Error, error, PF_NO_COMPOUND) TESTCLEARFLAG(Error, error, PF_NO_COMPOUND)
PAGEFLAG(Referenced, referenced, PF_HEAD)
TESTCLEARFLAG(Referenced, referenced, PF_HEAD)
@@ -351,6 +350,35 @@ TESTCLEARFLAG(Young, young, PF_ANY)
PAGEFLAG(Idle, idle, PF_ANY)
#endif
+#ifdef CONFIG_LOCKDEP_PAGELOCK
+#include <linux/lockdep.h>
+
+TESTPAGEFLAG(Locked, locked, PF_NO_TAIL)
+
+static __always_inline void __SetPageLocked(struct page *page)
+{
+ __set_bit(PG_locked, &PF_NO_TAIL(page, 1)->flags);
+
+ page = compound_head(page);
+ lock_acquire_exclusive(&page->map, 0, 1, NULL, _RET_IP_);
+}
+
+static __always_inline void __ClearPageLocked(struct page *page)
+{
+ __clear_bit(PG_locked, &PF_NO_TAIL(page, 1)->flags);
+
+ page = compound_head(page);
+ /*
+ * lock_commit_crosslock() is necessary for crosslock
+ * when the lock is released, before lock_release().
+ */
+ lock_commit_crosslock(&page->map);
+ lock_release(&page->map, 0, _RET_IP_);
+}
+#else
+__PAGEFLAG(Locked, locked, PF_NO_TAIL)
+#endif
+
/*
* On an anonymous page mapped into a user virtual memory area,
* page->mapping points to its anon_vma, not to a struct address_space;
--
1.9.1
Back to top | Article view | linux.kernel
csiph-web