0001
0002
0003
0004
0005
0006
0007
0008 #ifndef _LRU_LIST_H
0009 #define _LRU_LIST_H
0010
0011 #include <linux/list.h>
0012 #include <linux/nodemask.h>
0013 #include <linux/shrinker.h>
0014 #include <linux/xarray.h>
0015
0016 struct mem_cgroup;
0017
0018
0019 enum lru_status {
0020 LRU_REMOVED,
0021 LRU_REMOVED_RETRY,
0022
0023 LRU_ROTATE,
0024 LRU_SKIP,
0025 LRU_RETRY,
0026
0027 };
0028
0029 struct list_lru_one {
0030 struct list_head list;
0031
0032 long nr_items;
0033 };
0034
0035 struct list_lru_memcg {
0036 struct rcu_head rcu;
0037
0038 struct list_lru_one node[];
0039 };
0040
0041 struct list_lru_node {
0042
0043 spinlock_t lock;
0044
0045 struct list_lru_one lru;
0046 long nr_items;
0047 } ____cacheline_aligned_in_smp;
0048
0049 struct list_lru {
0050 struct list_lru_node *node;
0051 #ifdef CONFIG_MEMCG_KMEM
0052 struct list_head list;
0053 int shrinker_id;
0054 bool memcg_aware;
0055 struct xarray xa;
0056 #endif
0057 };
0058
0059 void list_lru_destroy(struct list_lru *lru);
0060 int __list_lru_init(struct list_lru *lru, bool memcg_aware,
0061 struct lock_class_key *key, struct shrinker *shrinker);
0062
0063 #define list_lru_init(lru) \
0064 __list_lru_init((lru), false, NULL, NULL)
0065 #define list_lru_init_key(lru, key) \
0066 __list_lru_init((lru), false, (key), NULL)
0067 #define list_lru_init_memcg(lru, shrinker) \
0068 __list_lru_init((lru), true, NULL, shrinker)
0069
0070 int memcg_list_lru_alloc(struct mem_cgroup *memcg, struct list_lru *lru,
0071 gfp_t gfp);
0072 void memcg_reparent_list_lrus(struct mem_cgroup *memcg, struct mem_cgroup *parent);
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090 bool list_lru_add(struct list_lru *lru, struct list_head *item);
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103 bool list_lru_del(struct list_lru *lru, struct list_head *item);
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115 unsigned long list_lru_count_one(struct list_lru *lru,
0116 int nid, struct mem_cgroup *memcg);
0117 unsigned long list_lru_count_node(struct list_lru *lru, int nid);
0118
0119 static inline unsigned long list_lru_shrink_count(struct list_lru *lru,
0120 struct shrink_control *sc)
0121 {
0122 return list_lru_count_one(lru, sc->nid, sc->memcg);
0123 }
0124
0125 static inline unsigned long list_lru_count(struct list_lru *lru)
0126 {
0127 long count = 0;
0128 int nid;
0129
0130 for_each_node_state(nid, N_NORMAL_MEMORY)
0131 count += list_lru_count_node(lru, nid);
0132
0133 return count;
0134 }
0135
0136 void list_lru_isolate(struct list_lru_one *list, struct list_head *item);
0137 void list_lru_isolate_move(struct list_lru_one *list, struct list_head *item,
0138 struct list_head *head);
0139
0140 typedef enum lru_status (*list_lru_walk_cb)(struct list_head *item,
0141 struct list_lru_one *list, spinlock_t *lock, void *cb_arg);
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165 unsigned long list_lru_walk_one(struct list_lru *lru,
0166 int nid, struct mem_cgroup *memcg,
0167 list_lru_walk_cb isolate, void *cb_arg,
0168 unsigned long *nr_to_walk);
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 unsigned long list_lru_walk_one_irq(struct list_lru *lru,
0183 int nid, struct mem_cgroup *memcg,
0184 list_lru_walk_cb isolate, void *cb_arg,
0185 unsigned long *nr_to_walk);
0186 unsigned long list_lru_walk_node(struct list_lru *lru, int nid,
0187 list_lru_walk_cb isolate, void *cb_arg,
0188 unsigned long *nr_to_walk);
0189
0190 static inline unsigned long
0191 list_lru_shrink_walk(struct list_lru *lru, struct shrink_control *sc,
0192 list_lru_walk_cb isolate, void *cb_arg)
0193 {
0194 return list_lru_walk_one(lru, sc->nid, sc->memcg, isolate, cb_arg,
0195 &sc->nr_to_scan);
0196 }
0197
0198 static inline unsigned long
0199 list_lru_shrink_walk_irq(struct list_lru *lru, struct shrink_control *sc,
0200 list_lru_walk_cb isolate, void *cb_arg)
0201 {
0202 return list_lru_walk_one_irq(lru, sc->nid, sc->memcg, isolate, cb_arg,
0203 &sc->nr_to_scan);
0204 }
0205
0206 static inline unsigned long
0207 list_lru_walk(struct list_lru *lru, list_lru_walk_cb isolate,
0208 void *cb_arg, unsigned long nr_to_walk)
0209 {
0210 long isolated = 0;
0211 int nid;
0212
0213 for_each_node_state(nid, N_NORMAL_MEMORY) {
0214 isolated += list_lru_walk_node(lru, nid, isolate,
0215 cb_arg, &nr_to_walk);
0216 if (nr_to_walk <= 0)
0217 break;
0218 }
0219 return isolated;
0220 }
0221 #endif