summaryrefslogtreecommitdiffstats
path: root/mm/memcontrol.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2017-09-04 14:50:49 +0200
committerTakashi Iwai <tiwai@suse.de>2017-09-04 14:50:49 +0200
commitb06898d119f6b8dba7b318ad73558ce2d39161e8 (patch)
treedf85bc0cd9047202faa6b02ee8ce706f155ba896 /mm/memcontrol.c
parentb24a5f293058b512f1685930f2983a20ee3e15ab (diff)
parentf5fd4a67bef5f2c5c2c9eb0cb2900e12d192ae23 (diff)
downloadop-kernel-dev-b06898d119f6b8dba7b318ad73558ce2d39161e8.zip
op-kernel-dev-b06898d119f6b8dba7b318ad73558ce2d39161e8.tar.gz
Merge tag 'asoc-v4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v4.14 This is quite a large release by volume of patches and diff, a lot of that is mechanical cleanup patches but it's great to also see a range of vendors actively working on adding new features and fixing issues in their drivers. Intel and Realtek have been especially active here. - Continued work towards moving everything to the component model from Morimoto-san. - Use of devres for jack detection GPIOs, eliminating some potential resource leaks. - Jack detection support for Qualcomm MSM8916. - Support for Allwinner H3, Cirrus Logic CS43130, Intel Kabylake systems with RT5663, Realtek RT274, TI TLV320AIC32x6 and Wolfson WM8523.
Diffstat (limited to 'mm/memcontrol.c')
-rw-r--r--mm/memcontrol.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 3df3c04..e09741a 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -1611,9 +1611,13 @@ cleanup:
* @page: the page
*
* This function protects unlocked LRU pages from being moved to
- * another cgroup and stabilizes their page->mem_cgroup binding.
+ * another cgroup.
+ *
+ * It ensures lifetime of the returned memcg. Caller is responsible
+ * for the lifetime of the page; __unlock_page_memcg() is available
+ * when @page might get freed inside the locked section.
*/
-void lock_page_memcg(struct page *page)
+struct mem_cgroup *lock_page_memcg(struct page *page)
{
struct mem_cgroup *memcg;
unsigned long flags;
@@ -1622,18 +1626,24 @@ void lock_page_memcg(struct page *page)
* The RCU lock is held throughout the transaction. The fast
* path can get away without acquiring the memcg->move_lock
* because page moving starts with an RCU grace period.
- */
+ *
+ * The RCU lock also protects the memcg from being freed when
+ * the page state that is going to change is the only thing
+ * preventing the page itself from being freed. E.g. writeback
+ * doesn't hold a page reference and relies on PG_writeback to
+ * keep off truncation, migration and so forth.
+ */
rcu_read_lock();
if (mem_cgroup_disabled())
- return;
+ return NULL;
again:
memcg = page->mem_cgroup;
if (unlikely(!memcg))
- return;
+ return NULL;
if (atomic_read(&memcg->moving_account) <= 0)
- return;
+ return memcg;
spin_lock_irqsave(&memcg->move_lock, flags);
if (memcg != page->mem_cgroup) {
@@ -1649,18 +1659,18 @@ again:
memcg->move_lock_task = current;
memcg->move_lock_flags = flags;
- return;
+ return memcg;
}
EXPORT_SYMBOL(lock_page_memcg);
/**
- * unlock_page_memcg - unlock a page->mem_cgroup binding
- * @page: the page
+ * __unlock_page_memcg - unlock and unpin a memcg
+ * @memcg: the memcg
+ *
+ * Unlock and unpin a memcg returned by lock_page_memcg().
*/
-void unlock_page_memcg(struct page *page)
+void __unlock_page_memcg(struct mem_cgroup *memcg)
{
- struct mem_cgroup *memcg = page->mem_cgroup;
-
if (memcg && memcg->move_lock_task == current) {
unsigned long flags = memcg->move_lock_flags;
@@ -1672,6 +1682,15 @@ void unlock_page_memcg(struct page *page)
rcu_read_unlock();
}
+
+/**
+ * unlock_page_memcg - unlock a page->mem_cgroup binding
+ * @page: the page
+ */
+void unlock_page_memcg(struct page *page)
+{
+ __unlock_page_memcg(page->mem_cgroup);
+}
EXPORT_SYMBOL(unlock_page_memcg);
/*
OpenPOWER on IntegriCloud