diff --git a/include/linux/list_lru.h b/include/linux/list_lru.h index cf59a8a..95a73ea 100644 --- a/include/linux/list_lru.h +++ b/include/linux/list_lru.h @@ -40,8 +40,37 @@ struct list_lru { }; int list_lru_init(struct list_lru *lru); -int list_lru_add(struct list_lru *lru, struct list_head *item); -int list_lru_del(struct list_lru *lru, struct list_head *item); + +struct list_lru_node *list_lru_to_node(struct list_lru *lru, + struct list_head *item); +int list_lru_add_node(struct list_lru *lru, struct list_lru_node *nlru, + struct list_head *item); +int list_lru_del_node(struct list_lru *lru, struct list_lru_node *nlru, + struct list_head *item); + +static inline int list_lru_add(struct list_lru *lru, struct list_head *item) +{ + int ret; + struct list_lru_node *nlru = list_lru_to_node(lru, item); + + spin_lock(&nlru->lock); + ret = list_lru_add_node(lru, nlru, item); + spin_unlock(&nlru->lock); + + return ret; +} + +static inline int list_lru_del(struct list_lru *lru, struct list_head *item) +{ + int ret; + struct list_lru_node *nlru = list_lru_to_node(lru, item); + + spin_lock(&nlru->lock); + ret = list_lru_del_node(lru, nlru, item); + spin_unlock(&nlru->lock); + + return ret; +} unsigned long list_lru_count_node(struct list_lru *lru, int nid); static inline unsigned long list_lru_count(struct list_lru *lru) diff --git a/lib/list_lru.c b/lib/list_lru.c index dae13d6..f72029d 100644 --- a/lib/list_lru.c +++ b/lib/list_lru.c @@ -9,49 +9,53 @@ #include #include -int -list_lru_add( +struct list_lru_node * +list_lru_to_node( struct list_lru *lru, struct list_head *item) { int nid = page_to_nid(virt_to_page(item)); - struct list_lru_node *nlru = &lru->node[nid]; + return &lru->node[nid]; +} +EXPORT_SYMBOL_GPL(list_lru_to_node); + +int +list_lru_add_node( + struct list_lru *lru, + struct list_lru_node *nlru, + struct list_head *item) +{ + int nid = page_to_nid(virt_to_page(item)); - spin_lock(&nlru->lock); BUG_ON(nlru->nr_items < 0); if (list_empty(item)) { list_add_tail(item, &nlru->list); if (nlru->nr_items++ == 0) node_set(nid, lru->active_nodes); - spin_unlock(&nlru->lock); return 1; } - spin_unlock(&nlru->lock); return 0; } -EXPORT_SYMBOL_GPL(list_lru_add); +EXPORT_SYMBOL_GPL(list_lru_add_node); int -list_lru_del( - struct list_lru *lru, - struct list_head *item) +list_lru_del_node( + struct list_lru *lru, + struct list_lru_node *nlru, + struct list_head *item) { int nid = page_to_nid(virt_to_page(item)); - struct list_lru_node *nlru = &lru->node[nid]; - spin_lock(&nlru->lock); if (!list_empty(item)) { list_del_init(item); if (--nlru->nr_items == 0) node_clear(nid, lru->active_nodes); BUG_ON(nlru->nr_items < 0); - spin_unlock(&nlru->lock); return 1; } - spin_unlock(&nlru->lock); return 0; } -EXPORT_SYMBOL_GPL(list_lru_del); +EXPORT_SYMBOL_GPL(list_lru_del_node); unsigned long list_lru_count_node(struct list_lru *lru, int nid)