mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
dax: support dirty DAX entries in radix tree
Add support for tracking dirty DAX entries in the struct address_space radix tree. This tree is already used for dirty page writeback, and it already supports the use of exceptional (non struct page*) entries. In order to properly track dirty DAX pages we will insert new exceptional entries into the radix tree that represent dirty DAX PTE or PMD pages. These exceptional entries will also contain the writeback addresses for the PTE or PMD faults that we can use at fsync/msync time. There are currently two types of exceptional entries (shmem and shadow) that can be placed into the radix tree, and this adds a third. We rely on the fact that only one type of exceptional entry can be found in a given radix tree based on its usage. This happens for free with DAX vs shmem but we explicitly prevent shadow entries from being added to radix trees for DAX mappings. The only shadow entries that would be generated for DAX radix trees would be to track zero page mappings that were created for holes. These pages would receive minimal benefit from having shadow entries, and the choice to have only one type of exceptional entry in a given radix tree makes the logic simpler both in clear_exceptional_entry() and in the rest of DAX. Signed-off-by: Ross Zwisler <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: "J. Bruce Fields" <[email protected]> Cc: "Theodore Ts'o" <[email protected]> Cc: Alexander Viro <[email protected]> Cc: Andreas Dilger <[email protected]> Cc: Dave Chinner <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jan Kara <[email protected]> Cc: Jeff Layton <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Dan Williams <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Hugh Dickins <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
parent
3f4a2670de
commit
f9fe48bece
9 changed files with 78 additions and 42 deletions
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/backing-dev.h>
|
||||
#include <linux/dax.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/swap.h>
|
||||
|
|
@ -34,31 +35,39 @@ static void clear_exceptional_entry(struct address_space *mapping,
|
|||
return;
|
||||
|
||||
spin_lock_irq(&mapping->tree_lock);
|
||||
/*
|
||||
* Regular page slots are stabilized by the page lock even
|
||||
* without the tree itself locked. These unlocked entries
|
||||
* need verification under the tree lock.
|
||||
*/
|
||||
if (!__radix_tree_lookup(&mapping->page_tree, index, &node, &slot))
|
||||
goto unlock;
|
||||
if (*slot != entry)
|
||||
goto unlock;
|
||||
radix_tree_replace_slot(slot, NULL);
|
||||
mapping->nrshadows--;
|
||||
if (!node)
|
||||
goto unlock;
|
||||
workingset_node_shadows_dec(node);
|
||||
/*
|
||||
* Don't track node without shadow entries.
|
||||
*
|
||||
* Avoid acquiring the list_lru lock if already untracked.
|
||||
* The list_empty() test is safe as node->private_list is
|
||||
* protected by mapping->tree_lock.
|
||||
*/
|
||||
if (!workingset_node_shadows(node) &&
|
||||
!list_empty(&node->private_list))
|
||||
list_lru_del(&workingset_shadow_nodes, &node->private_list);
|
||||
__radix_tree_delete_node(&mapping->page_tree, node);
|
||||
|
||||
if (dax_mapping(mapping)) {
|
||||
if (radix_tree_delete_item(&mapping->page_tree, index, entry))
|
||||
mapping->nrexceptional--;
|
||||
} else {
|
||||
/*
|
||||
* Regular page slots are stabilized by the page lock even
|
||||
* without the tree itself locked. These unlocked entries
|
||||
* need verification under the tree lock.
|
||||
*/
|
||||
if (!__radix_tree_lookup(&mapping->page_tree, index, &node,
|
||||
&slot))
|
||||
goto unlock;
|
||||
if (*slot != entry)
|
||||
goto unlock;
|
||||
radix_tree_replace_slot(slot, NULL);
|
||||
mapping->nrexceptional--;
|
||||
if (!node)
|
||||
goto unlock;
|
||||
workingset_node_shadows_dec(node);
|
||||
/*
|
||||
* Don't track node without shadow entries.
|
||||
*
|
||||
* Avoid acquiring the list_lru lock if already untracked.
|
||||
* The list_empty() test is safe as node->private_list is
|
||||
* protected by mapping->tree_lock.
|
||||
*/
|
||||
if (!workingset_node_shadows(node) &&
|
||||
!list_empty(&node->private_list))
|
||||
list_lru_del(&workingset_shadow_nodes,
|
||||
&node->private_list);
|
||||
__radix_tree_delete_node(&mapping->page_tree, node);
|
||||
}
|
||||
unlock:
|
||||
spin_unlock_irq(&mapping->tree_lock);
|
||||
}
|
||||
|
|
@ -228,7 +237,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
|
|||
int i;
|
||||
|
||||
cleancache_invalidate_inode(mapping);
|
||||
if (mapping->nrpages == 0 && mapping->nrshadows == 0)
|
||||
if (mapping->nrpages == 0 && mapping->nrexceptional == 0)
|
||||
return;
|
||||
|
||||
/* Offsets within partial pages */
|
||||
|
|
@ -402,7 +411,7 @@ EXPORT_SYMBOL(truncate_inode_pages);
|
|||
*/
|
||||
void truncate_inode_pages_final(struct address_space *mapping)
|
||||
{
|
||||
unsigned long nrshadows;
|
||||
unsigned long nrexceptional;
|
||||
unsigned long nrpages;
|
||||
|
||||
/*
|
||||
|
|
@ -416,14 +425,14 @@ void truncate_inode_pages_final(struct address_space *mapping)
|
|||
|
||||
/*
|
||||
* When reclaim installs eviction entries, it increases
|
||||
* nrshadows first, then decreases nrpages. Make sure we see
|
||||
* nrexceptional first, then decreases nrpages. Make sure we see
|
||||
* this in the right order or we might miss an entry.
|
||||
*/
|
||||
nrpages = mapping->nrpages;
|
||||
smp_rmb();
|
||||
nrshadows = mapping->nrshadows;
|
||||
nrexceptional = mapping->nrexceptional;
|
||||
|
||||
if (nrpages || nrshadows) {
|
||||
if (nrpages || nrexceptional) {
|
||||
/*
|
||||
* As truncation uses a lockless tree lookup, cycle
|
||||
* the tree lock to make sure any ongoing tree
|
||||
|
|
|
|||
Loading…
Reference in a new issue