@@ -103,6 +103,19 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item);
*/
bool list_lru_del(struct list_lru *lru, struct list_head *item);
+/**
+ * list_lru_get_mru: gets and removes the tail from one of the node lists
+ * @list_lru: the lru pointer
+ * @nid: the node id
+ *
+ * This function removes the most recently added item from one of the node
+ * id specified. This function should not be used if the list_lru is memcg
+ * aware.
+ *
+ * Return value: The element removed
+ */
+struct list_head *list_lru_get_mru(struct list_lru *lru, int nid);
+
/**
* list_lru_count_one: return the number of objects currently held by @lru
* @lru: the lru pointer.
@@ -156,6 +156,34 @@ bool list_lru_del(struct list_lru *lru, struct list_head *item)
}
EXPORT_SYMBOL_GPL(list_lru_del);
+struct list_head *list_lru_get_mru(struct list_lru *lru, int nid)
+{
+ struct list_lru_node *nlru = &lru->node[nid];
+ struct list_lru_one *l = &nlru->lru;
+ struct list_head *ret;
+
+ /* This function does not attempt to search through the memcg lists */
+ if (list_lru_memcg_aware(lru)) {
+ WARN_ONCE(1, "list_lru: %s not supported on memcg aware list_lrus", __func__);
+ return NULL;
+ }
+
+ spin_lock(&nlru->lock);
+ if (list_empty(&l->list)) {
+ ret = NULL;
+ } else {
+ /* Get tail */
+ ret = l->list.prev;
+ list_del_init(ret);
+
+ l->nr_items--;
+ nlru->nr_items--;
+ }
+ spin_unlock(&nlru->lock);
+
+ return ret;
+}
+
void list_lru_isolate(struct list_lru_one *list, struct list_head *item)
{
list_del_init(item);