xarray: Replace exceptional entries
Introduce xarray value entries and tagged pointers to replace radix tree exceptional entries. This is a slight change in encoding to allow the use of an extra bit (we can now store BITS_PER_LONG - 1 bits in a value entry). It is also a change in emphasis; exceptional entries are intimidating and different. As the comment explains, you can choose to store values or pointers in the xarray and they are both first-class citizens. Signed-off-by: Matthew Wilcox <willy@infradead.org> Reviewed-by: Josef Bacik <jbacik@fb.com>
This commit is contained in:
@@ -155,8 +155,8 @@
|
||||
* refault distance will immediately activate the refaulting page.
|
||||
*/
|
||||
|
||||
#define EVICTION_SHIFT (RADIX_TREE_EXCEPTIONAL_ENTRY + \
|
||||
NODES_SHIFT + \
|
||||
#define EVICTION_SHIFT ((BITS_PER_LONG - BITS_PER_XA_VALUE) + \
|
||||
NODES_SHIFT + \
|
||||
MEM_CGROUP_ID_SHIFT)
|
||||
#define EVICTION_MASK (~0UL >> EVICTION_SHIFT)
|
||||
|
||||
@@ -173,20 +173,19 @@ static unsigned int bucket_order __read_mostly;
|
||||
static void *pack_shadow(int memcgid, pg_data_t *pgdat, unsigned long eviction)
|
||||
{
|
||||
eviction >>= bucket_order;
|
||||
eviction &= EVICTION_MASK;
|
||||
eviction = (eviction << MEM_CGROUP_ID_SHIFT) | memcgid;
|
||||
eviction = (eviction << NODES_SHIFT) | pgdat->node_id;
|
||||
eviction = (eviction << RADIX_TREE_EXCEPTIONAL_SHIFT);
|
||||
|
||||
return (void *)(eviction | RADIX_TREE_EXCEPTIONAL_ENTRY);
|
||||
return xa_mk_value(eviction);
|
||||
}
|
||||
|
||||
static void unpack_shadow(void *shadow, int *memcgidp, pg_data_t **pgdat,
|
||||
unsigned long *evictionp)
|
||||
{
|
||||
unsigned long entry = (unsigned long)shadow;
|
||||
unsigned long entry = xa_to_value(shadow);
|
||||
int memcgid, nid;
|
||||
|
||||
entry >>= RADIX_TREE_EXCEPTIONAL_SHIFT;
|
||||
nid = entry & ((1UL << NODES_SHIFT) - 1);
|
||||
entry >>= NODES_SHIFT;
|
||||
memcgid = entry & ((1UL << MEM_CGROUP_ID_SHIFT) - 1);
|
||||
@@ -453,7 +452,7 @@ static enum lru_status shadow_lru_isolate(struct list_head *item,
|
||||
goto out_invalid;
|
||||
for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) {
|
||||
if (node->slots[i]) {
|
||||
if (WARN_ON_ONCE(!radix_tree_exceptional_entry(node->slots[i])))
|
||||
if (WARN_ON_ONCE(!xa_is_value(node->slots[i])))
|
||||
goto out_invalid;
|
||||
if (WARN_ON_ONCE(!node->exceptional))
|
||||
goto out_invalid;
|
||||
|
Reference in New Issue
Block a user