• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Manage cache of swap slots to be used for and returned from
4  * swap.
5  *
6  * Copyright(c) 2016 Intel Corporation.
7  *
8  * Author: Tim Chen <tim.c.chen@linux.intel.com>
9  *
10  * We allocate the swap slots from the global pool and put
11  * it into local per cpu caches.  This has the advantage
12  * of no needing to acquire the swap_info lock every time
13  * we need a new slot.
14  *
15  * There is also opportunity to simply return the slot
16  * to local caches without needing to acquire swap_info
17  * lock.  We do not reuse the returned slots directly but
18  * move them back to the global pool in a batch.  This
19  * allows the slots to coaellesce and reduce fragmentation.
20  *
21  * The swap entry allocated is marked with SWAP_HAS_CACHE
22  * flag in map_count that prevents it from being allocated
23  * again from the global pool.
24  *
25  * The swap slots cache is protected by a mutex instead of
26  * a spin lock as when we search for slots with scan_swap_map,
27  * we can possibly sleep.
28  */
29 
30 #include <linux/swap_slots.h>
31 #include <linux/cpu.h>
32 #include <linux/cpumask.h>
33 #include <linux/vmalloc.h>
34 #include <linux/mutex.h>
35 #include <linux/mm.h>
36 #include <trace/hooks/mm.h>
37 
38 static DEFINE_PER_CPU(struct swap_slots_cache, swp_slots);
39 static bool	swap_slot_cache_active;
40 bool	swap_slot_cache_enabled;
41 static bool	swap_slot_cache_initialized;
42 static DEFINE_MUTEX(swap_slots_cache_mutex);
43 /* Serialize swap slots cache enable/disable operations */
44 static DEFINE_MUTEX(swap_slots_cache_enable_mutex);
45 
46 static void __drain_swap_slots_cache(unsigned int type);
47 static void deactivate_swap_slots_cache(void);
48 static void reactivate_swap_slots_cache(void);
49 
50 #define use_swap_slot_cache (swap_slot_cache_active && swap_slot_cache_enabled)
51 #define SLOTS_CACHE 0x1
52 #define SLOTS_CACHE_RET 0x2
53 
deactivate_swap_slots_cache(void)54 static void deactivate_swap_slots_cache(void)
55 {
56 	mutex_lock(&swap_slots_cache_mutex);
57 	swap_slot_cache_active = false;
58 	trace_android_vh_swap_slot_cache_active(false);
59 	__drain_swap_slots_cache(SLOTS_CACHE|SLOTS_CACHE_RET);
60 	mutex_unlock(&swap_slots_cache_mutex);
61 }
62 
reactivate_swap_slots_cache(void)63 static void reactivate_swap_slots_cache(void)
64 {
65 	mutex_lock(&swap_slots_cache_mutex);
66 	swap_slot_cache_active = true;
67 	trace_android_vh_swap_slot_cache_active(true);
68 	mutex_unlock(&swap_slots_cache_mutex);
69 }
70 
71 /* Must not be called with cpu hot plug lock */
disable_swap_slots_cache_lock(void)72 void disable_swap_slots_cache_lock(void)
73 {
74 	mutex_lock(&swap_slots_cache_enable_mutex);
75 	swap_slot_cache_enabled = false;
76 	if (swap_slot_cache_initialized) {
77 		/* serialize with cpu hotplug operations */
78 		get_online_cpus();
79 		__drain_swap_slots_cache(SLOTS_CACHE|SLOTS_CACHE_RET);
80 		put_online_cpus();
81 	}
82 }
83 
__reenable_swap_slots_cache(void)84 static void __reenable_swap_slots_cache(void)
85 {
86 	swap_slot_cache_enabled = has_usable_swap();
87 }
88 
reenable_swap_slots_cache_unlock(void)89 void reenable_swap_slots_cache_unlock(void)
90 {
91 	__reenable_swap_slots_cache();
92 	mutex_unlock(&swap_slots_cache_enable_mutex);
93 }
94 
is_swap_slot_cache_enabled(void)95 bool is_swap_slot_cache_enabled(void)
96 {
97 	return swap_slot_cache_enabled;
98 }
99 EXPORT_SYMBOL_GPL(is_swap_slot_cache_enabled);
100 
check_cache_active(void)101 bool check_cache_active(void)
102 {
103 	long pages;
104 
105 	if (!swap_slot_cache_enabled)
106 		return false;
107 
108 	pages = get_nr_swap_pages();
109 	if (!swap_slot_cache_active) {
110 		if (pages > num_online_cpus() *
111 		    THRESHOLD_ACTIVATE_SWAP_SLOTS_CACHE)
112 			reactivate_swap_slots_cache();
113 		goto out;
114 	}
115 
116 	/* if global pool of slot caches too low, deactivate cache */
117 	if (pages < num_online_cpus() * THRESHOLD_DEACTIVATE_SWAP_SLOTS_CACHE)
118 		deactivate_swap_slots_cache();
119 out:
120 	return swap_slot_cache_active;
121 }
122 EXPORT_SYMBOL_GPL(check_cache_active);
123 
alloc_swap_slot_cache(unsigned int cpu)124 static int alloc_swap_slot_cache(unsigned int cpu)
125 {
126 	struct swap_slots_cache *cache;
127 	swp_entry_t *slots, *slots_ret;
128 	bool skip = false;
129 	int ret = 0;
130 
131 	/*
132 	 * Do allocation outside swap_slots_cache_mutex
133 	 * as kvzalloc could trigger reclaim and get_swap_page,
134 	 * which can lock swap_slots_cache_mutex.
135 	 */
136 	trace_android_rvh_alloc_swap_slot_cache(&per_cpu(swp_slots, cpu),
137 		&ret, &skip);
138 	trace_android_vh_alloc_swap_slot_cache(&per_cpu(swp_slots, cpu),
139 		&ret, &skip);
140 	if (skip)
141 		return ret;
142 	slots = kvcalloc(SWAP_SLOTS_CACHE_SIZE, sizeof(swp_entry_t),
143 			 GFP_KERNEL);
144 	if (!slots)
145 		return -ENOMEM;
146 
147 	slots_ret = kvcalloc(SWAP_SLOTS_CACHE_SIZE, sizeof(swp_entry_t),
148 			     GFP_KERNEL);
149 	if (!slots_ret) {
150 		kvfree(slots);
151 		return -ENOMEM;
152 	}
153 
154 	mutex_lock(&swap_slots_cache_mutex);
155 	cache = &per_cpu(swp_slots, cpu);
156 	if (cache->slots || cache->slots_ret) {
157 		/* cache already allocated */
158 		mutex_unlock(&swap_slots_cache_mutex);
159 
160 		kvfree(slots);
161 		kvfree(slots_ret);
162 
163 		return 0;
164 	}
165 
166 	if (!cache->lock_initialized) {
167 		mutex_init(&cache->alloc_lock);
168 		spin_lock_init(&cache->free_lock);
169 		cache->lock_initialized = true;
170 	}
171 	cache->nr = 0;
172 	cache->cur = 0;
173 	cache->n_ret = 0;
174 	/*
175 	 * We initialized alloc_lock and free_lock earlier.  We use
176 	 * !cache->slots or !cache->slots_ret to know if it is safe to acquire
177 	 * the corresponding lock and use the cache.  Memory barrier below
178 	 * ensures the assumption.
179 	 */
180 	mb();
181 	cache->slots = slots;
182 	cache->slots_ret = slots_ret;
183 	mutex_unlock(&swap_slots_cache_mutex);
184 	return 0;
185 }
186 
drain_slots_cache_cpu(unsigned int cpu,unsigned int type,bool free_slots)187 static void drain_slots_cache_cpu(unsigned int cpu, unsigned int type,
188 				  bool free_slots)
189 {
190 	struct swap_slots_cache *cache;
191 	swp_entry_t *slots = NULL;
192 	bool skip = false;
193 
194 	cache = &per_cpu(swp_slots, cpu);
195 	trace_android_rvh_drain_slots_cache_cpu(cache, type,
196 		free_slots, &skip);
197 	trace_android_vh_drain_slots_cache_cpu(cache, type,
198 		free_slots, &skip);
199 	if (skip)
200 		return;
201 	if ((type & SLOTS_CACHE) && cache->slots) {
202 		mutex_lock(&cache->alloc_lock);
203 		swapcache_free_entries(cache->slots + cache->cur, cache->nr);
204 		cache->cur = 0;
205 		cache->nr = 0;
206 		if (free_slots && cache->slots) {
207 			kvfree(cache->slots);
208 			cache->slots = NULL;
209 		}
210 		mutex_unlock(&cache->alloc_lock);
211 	}
212 	if ((type & SLOTS_CACHE_RET) && cache->slots_ret) {
213 		spin_lock_irq(&cache->free_lock);
214 		swapcache_free_entries(cache->slots_ret, cache->n_ret);
215 		cache->n_ret = 0;
216 		if (free_slots && cache->slots_ret) {
217 			slots = cache->slots_ret;
218 			cache->slots_ret = NULL;
219 		}
220 		spin_unlock_irq(&cache->free_lock);
221 		if (slots)
222 			kvfree(slots);
223 	}
224 }
225 
__drain_swap_slots_cache(unsigned int type)226 static void __drain_swap_slots_cache(unsigned int type)
227 {
228 	unsigned int cpu;
229 
230 	/*
231 	 * This function is called during
232 	 *	1) swapoff, when we have to make sure no
233 	 *	   left over slots are in cache when we remove
234 	 *	   a swap device;
235 	 *      2) disabling of swap slot cache, when we run low
236 	 *	   on swap slots when allocating memory and need
237 	 *	   to return swap slots to global pool.
238 	 *
239 	 * We cannot acquire cpu hot plug lock here as
240 	 * this function can be invoked in the cpu
241 	 * hot plug path:
242 	 * cpu_up -> lock cpu_hotplug -> cpu hotplug state callback
243 	 *   -> memory allocation -> direct reclaim -> get_swap_page
244 	 *   -> drain_swap_slots_cache
245 	 *
246 	 * Hence the loop over current online cpu below could miss cpu that
247 	 * is being brought online but not yet marked as online.
248 	 * That is okay as we do not schedule and run anything on a
249 	 * cpu before it has been marked online. Hence, we will not
250 	 * fill any swap slots in slots cache of such cpu.
251 	 * There are no slots on such cpu that need to be drained.
252 	 */
253 	for_each_online_cpu(cpu)
254 		drain_slots_cache_cpu(cpu, type, false);
255 }
256 
free_slot_cache(unsigned int cpu)257 static int free_slot_cache(unsigned int cpu)
258 {
259 	mutex_lock(&swap_slots_cache_mutex);
260 	drain_slots_cache_cpu(cpu, SLOTS_CACHE | SLOTS_CACHE_RET, true);
261 	mutex_unlock(&swap_slots_cache_mutex);
262 	return 0;
263 }
264 
enable_swap_slots_cache(void)265 void enable_swap_slots_cache(void)
266 {
267 	mutex_lock(&swap_slots_cache_enable_mutex);
268 	if (!swap_slot_cache_initialized) {
269 		int ret;
270 
271 		ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "swap_slots_cache",
272 					alloc_swap_slot_cache, free_slot_cache);
273 		if (WARN_ONCE(ret < 0, "Cache allocation failed (%s), operating "
274 				       "without swap slots cache.\n", __func__))
275 			goto out_unlock;
276 
277 		swap_slot_cache_initialized = true;
278 	}
279 
280 	__reenable_swap_slots_cache();
281 out_unlock:
282 	mutex_unlock(&swap_slots_cache_enable_mutex);
283 }
284 
285 /* called with swap slot cache's alloc lock held */
refill_swap_slots_cache(struct swap_slots_cache * cache)286 static int refill_swap_slots_cache(struct swap_slots_cache *cache)
287 {
288 	if (!use_swap_slot_cache || cache->nr)
289 		return 0;
290 
291 	cache->cur = 0;
292 	if (swap_slot_cache_active)
293 		cache->nr = get_swap_pages(SWAP_SLOTS_CACHE_SIZE,
294 					   cache->slots, 1);
295 
296 	return cache->nr;
297 }
298 
free_swap_slot(swp_entry_t entry)299 int free_swap_slot(swp_entry_t entry)
300 {
301 	struct swap_slots_cache *cache;
302 	bool skip = false;
303 
304 	cache = raw_cpu_ptr(&swp_slots);
305 	trace_android_rvh_free_swap_slot(entry, cache, &skip);
306 	trace_android_vh_free_swap_slot(entry, cache, &skip);
307 	if (skip)
308 		return 0;
309 	if (likely(use_swap_slot_cache && cache->slots_ret)) {
310 		spin_lock_irq(&cache->free_lock);
311 		/* Swap slots cache may be deactivated before acquiring lock */
312 		if (!use_swap_slot_cache || !cache->slots_ret) {
313 			spin_unlock_irq(&cache->free_lock);
314 			goto direct_free;
315 		}
316 		if (cache->n_ret >= SWAP_SLOTS_CACHE_SIZE) {
317 			/*
318 			 * Return slots to global pool.
319 			 * The current swap_map value is SWAP_HAS_CACHE.
320 			 * Set it to 0 to indicate it is available for
321 			 * allocation in global pool
322 			 */
323 			swapcache_free_entries(cache->slots_ret, cache->n_ret);
324 			cache->n_ret = 0;
325 		}
326 		cache->slots_ret[cache->n_ret++] = entry;
327 		spin_unlock_irq(&cache->free_lock);
328 	} else {
329 direct_free:
330 		swapcache_free_entries(&entry, 1);
331 	}
332 
333 	return 0;
334 }
335 
get_swap_page(struct page * page)336 swp_entry_t get_swap_page(struct page *page)
337 {
338 	swp_entry_t entry;
339 	struct swap_slots_cache *cache;
340 	bool found = false;
341 	entry.val = 0;
342 
343 	trace_android_rvh_get_swap_page(page, &entry, raw_cpu_ptr(&swp_slots), &found);
344 	trace_android_vh_get_swap_page(page, &entry, raw_cpu_ptr(&swp_slots), &found);
345 	if (found)
346 		goto out;
347 
348 	if (PageTransHuge(page)) {
349 		if (IS_ENABLED(CONFIG_THP_SWAP))
350 			get_swap_pages(1, &entry, HPAGE_PMD_NR);
351 		goto out;
352 	}
353 
354 	/*
355 	 * Preemption is allowed here, because we may sleep
356 	 * in refill_swap_slots_cache().  But it is safe, because
357 	 * accesses to the per-CPU data structure are protected by the
358 	 * mutex cache->alloc_lock.
359 	 *
360 	 * The alloc path here does not touch cache->slots_ret
361 	 * so cache->free_lock is not taken.
362 	 */
363 	cache = raw_cpu_ptr(&swp_slots);
364 
365 	if (likely(check_cache_active() && cache->slots)) {
366 		mutex_lock(&cache->alloc_lock);
367 		if (cache->slots) {
368 repeat:
369 			if (cache->nr) {
370 				entry = cache->slots[cache->cur];
371 				cache->slots[cache->cur++].val = 0;
372 				cache->nr--;
373 			} else if (refill_swap_slots_cache(cache)) {
374 				goto repeat;
375 			}
376 		}
377 		mutex_unlock(&cache->alloc_lock);
378 		if (entry.val)
379 			goto out;
380 	}
381 
382 	get_swap_pages(1, &entry, 1);
383 out:
384 	if (mem_cgroup_try_charge_swap(page, entry)) {
385 		put_swap_page(page, entry);
386 		entry.val = 0;
387 	}
388 	return entry;
389 }
390