.. | .. |
---|
148 | 148 | * We always assume that blocks are of size PAGE_SIZE. |
---|
149 | 149 | */ |
---|
150 | 150 | struct swap_extent { |
---|
151 | | - struct list_head list; |
---|
| 151 | + struct rb_node rb_node; |
---|
152 | 152 | pgoff_t start_page; |
---|
153 | 153 | pgoff_t nr_pages; |
---|
154 | 154 | sector_t start_block; |
---|
.. | .. |
---|
169 | 169 | SWP_SOLIDSTATE = (1 << 4), /* blkdev seeks are cheap */ |
---|
170 | 170 | SWP_CONTINUED = (1 << 5), /* swap_map has count continuation */ |
---|
171 | 171 | SWP_BLKDEV = (1 << 6), /* its a block device */ |
---|
172 | | - SWP_FILE = (1 << 7), /* set after swap_activate success */ |
---|
173 | | - SWP_AREA_DISCARD = (1 << 8), /* single-time swap area discards */ |
---|
174 | | - SWP_PAGE_DISCARD = (1 << 9), /* freed swap page-cluster discards */ |
---|
175 | | - SWP_STABLE_WRITES = (1 << 10), /* no overwrite PG_writeback pages */ |
---|
176 | | - SWP_SYNCHRONOUS_IO = (1 << 11), /* synchronous IO is efficient */ |
---|
| 172 | + SWP_ACTIVATED = (1 << 7), /* set after swap_activate success */ |
---|
| 173 | + SWP_FS_OPS = (1 << 8), /* swapfile operations go through fs */ |
---|
| 174 | + SWP_AREA_DISCARD = (1 << 9), /* single-time swap area discards */ |
---|
| 175 | + SWP_PAGE_DISCARD = (1 << 10), /* freed swap page-cluster discards */ |
---|
| 176 | + SWP_STABLE_WRITES = (1 << 11), /* no overwrite PG_writeback pages */ |
---|
| 177 | + SWP_SYNCHRONOUS_IO = (1 << 12), /* synchronous IO is efficient */ |
---|
| 178 | + SWP_VALID = (1 << 13), /* swap is valid to be operated on? */ |
---|
177 | 179 | /* add others here before... */ |
---|
178 | | - SWP_SCANNING = (1 << 12), /* refcount in scan_swap_map */ |
---|
| 180 | + SWP_SCANNING = (1 << 14), /* refcount in scan_swap_map */ |
---|
179 | 181 | }; |
---|
180 | 182 | |
---|
181 | 183 | #define SWAP_CLUSTER_MAX 32UL |
---|
182 | 184 | #define COMPACT_CLUSTER_MAX SWAP_CLUSTER_MAX |
---|
183 | 185 | |
---|
184 | | -#define SWAP_MAP_MAX 0x3e /* Max duplication count, in first swap_map */ |
---|
185 | | -#define SWAP_MAP_BAD 0x3f /* Note pageblock is bad, in first swap_map */ |
---|
| 186 | +/* Bit flag in swap_map */ |
---|
186 | 187 | #define SWAP_HAS_CACHE 0x40 /* Flag page is cached, in first swap_map */ |
---|
187 | | -#define SWAP_CONT_MAX 0x7f /* Max count, in each swap_map continuation */ |
---|
188 | | -#define COUNT_CONTINUED 0x80 /* See swap_map continuation for full count */ |
---|
189 | | -#define SWAP_MAP_SHMEM 0xbf /* Owned by shmem/tmpfs, in first swap_map */ |
---|
| 188 | +#define COUNT_CONTINUED 0x80 /* Flag swap_map continuation for full count */ |
---|
| 189 | + |
---|
| 190 | +/* Special value in first swap_map */ |
---|
| 191 | +#define SWAP_MAP_MAX 0x3e /* Max count */ |
---|
| 192 | +#define SWAP_MAP_BAD 0x3f /* Note page is bad */ |
---|
| 193 | +#define SWAP_MAP_SHMEM 0xbf /* Owned by shmem/tmpfs */ |
---|
| 194 | + |
---|
| 195 | +/* Special value in each swap_map continuation */ |
---|
| 196 | +#define SWAP_CONT_MAX 0x7f /* Max count */ |
---|
190 | 197 | |
---|
191 | 198 | /* |
---|
192 | 199 | * We use this to track usage of a cluster. A cluster is a block of swap disk |
---|
.. | .. |
---|
245 | 252 | unsigned int inuse_pages; /* number of those currently in use */ |
---|
246 | 253 | unsigned int cluster_next; /* likely index for next allocation */ |
---|
247 | 254 | unsigned int cluster_nr; /* countdown to next cluster search */ |
---|
| 255 | + unsigned int __percpu *cluster_next_cpu; /*percpu index for next allocation */ |
---|
248 | 256 | struct percpu_cluster __percpu *percpu_cluster; /* per cpu's swap location */ |
---|
249 | | - struct swap_extent *curr_swap_extent; |
---|
250 | | - struct swap_extent first_swap_extent; |
---|
| 257 | + struct rb_root swap_extent_root;/* root of the swap extent rbtree */ |
---|
251 | 258 | struct block_device *bdev; /* swap device or bdev of swap file */ |
---|
252 | 259 | struct file *swap_file; /* seldom referenced */ |
---|
253 | 260 | unsigned int old_block_size; /* seldom referenced */ |
---|
.. | .. |
---|
274 | 281 | */ |
---|
275 | 282 | struct work_struct discard_work; /* discard worker */ |
---|
276 | 283 | struct swap_cluster_list discard_clusters; /* discard clusters list */ |
---|
277 | | - unsigned int write_pending; |
---|
278 | | - unsigned int max_writes; |
---|
279 | | - struct plist_node avail_lists[0]; /* |
---|
| 284 | + struct plist_node avail_lists[]; /* |
---|
280 | 285 | * entries in swap_avail_heads, one |
---|
281 | 286 | * entry per node. |
---|
282 | 287 | * Must be last as the number of the |
---|
.. | .. |
---|
308 | 313 | }; |
---|
309 | 314 | |
---|
310 | 315 | /* linux/mm/workingset.c */ |
---|
311 | | -void *workingset_eviction(struct address_space *mapping, struct page *page); |
---|
| 316 | +void workingset_age_nonresident(struct lruvec *lruvec, unsigned long nr_pages); |
---|
| 317 | +void *workingset_eviction(struct page *page, struct mem_cgroup *target_memcg); |
---|
312 | 318 | void workingset_refault(struct page *page, void *shadow); |
---|
313 | 319 | void workingset_activation(struct page *page); |
---|
314 | 320 | |
---|
315 | | -/* Do not use directly, use workingset_lookup_update */ |
---|
316 | | -void workingset_update_node(struct radix_tree_node *node); |
---|
317 | | - |
---|
318 | | -/* Returns workingset_update_node() if the mapping has shadow entries. */ |
---|
319 | | -#define workingset_lookup_update(mapping) \ |
---|
320 | | -({ \ |
---|
321 | | - radix_tree_update_node_t __helper = workingset_update_node; \ |
---|
322 | | - if (dax_mapping(mapping) || shmem_mapping(mapping)) \ |
---|
323 | | - __helper = NULL; \ |
---|
324 | | - __helper; \ |
---|
325 | | -}) |
---|
| 321 | +/* Only track the nodes of mappings with shadow entries */ |
---|
| 322 | +void workingset_update_node(struct xa_node *node); |
---|
| 323 | +#define mapping_set_update(xas, mapping) do { \ |
---|
| 324 | + if (!dax_mapping(mapping) && !shmem_mapping(mapping)) \ |
---|
| 325 | + xas_set_update(xas, workingset_update_node); \ |
---|
| 326 | +} while (0) |
---|
326 | 327 | |
---|
327 | 328 | /* linux/mm/page_alloc.c */ |
---|
328 | | -extern unsigned long totalram_pages; |
---|
329 | 329 | extern unsigned long totalreserve_pages; |
---|
330 | 330 | extern unsigned long nr_free_buffer_pages(void); |
---|
331 | | -extern unsigned long nr_free_pagecache_pages(void); |
---|
332 | 331 | |
---|
333 | 332 | /* Definition of global_zone_page_state not available yet */ |
---|
334 | 333 | #define nr_free_pages() global_zone_page_state(NR_FREE_PAGES) |
---|
335 | 334 | |
---|
336 | 335 | |
---|
337 | 336 | /* linux/mm/swap.c */ |
---|
| 337 | +extern void lru_note_cost(struct lruvec *lruvec, bool file, |
---|
| 338 | + unsigned int nr_pages); |
---|
| 339 | +extern void lru_note_cost_page(struct page *); |
---|
338 | 340 | extern void lru_cache_add(struct page *); |
---|
339 | | -extern void lru_cache_add_anon(struct page *page); |
---|
340 | | -extern void lru_cache_add_file(struct page *page); |
---|
341 | 341 | extern void lru_add_page_tail(struct page *page, struct page *page_tail, |
---|
342 | 342 | struct lruvec *lruvec, struct list_head *head); |
---|
343 | | -extern void activate_page(struct page *); |
---|
344 | 343 | extern void mark_page_accessed(struct page *); |
---|
| 344 | + |
---|
| 345 | +extern bool lru_cache_disabled(void); |
---|
| 346 | +extern void lru_cache_disable(void); |
---|
| 347 | +extern void lru_cache_enable(void); |
---|
345 | 348 | extern void lru_add_drain(void); |
---|
346 | 349 | extern void lru_add_drain_cpu(int cpu); |
---|
| 350 | +extern void lru_add_drain_cpu_zone(struct zone *zone); |
---|
347 | 351 | extern void lru_add_drain_all(void); |
---|
348 | 352 | extern void rotate_reclaimable_page(struct page *page); |
---|
349 | 353 | extern void deactivate_file_page(struct page *page); |
---|
| 354 | +extern void deactivate_page(struct page *page); |
---|
350 | 355 | extern void mark_page_lazyfree(struct page *page); |
---|
| 356 | +extern void mark_page_lazyfree_movetail(struct page *page, bool tail); |
---|
351 | 357 | extern void swap_setup(void); |
---|
352 | 358 | |
---|
353 | | -extern void lru_cache_add_active_or_unevictable(struct page *page, |
---|
354 | | - struct vm_area_struct *vma); |
---|
| 359 | +extern void __lru_cache_add_inactive_or_unevictable(struct page *page, |
---|
| 360 | + unsigned long vma_flags); |
---|
| 361 | + |
---|
| 362 | +static inline void lru_cache_add_inactive_or_unevictable(struct page *page, |
---|
| 363 | + struct vm_area_struct *vma) |
---|
| 364 | +{ |
---|
| 365 | + return __lru_cache_add_inactive_or_unevictable(page, vma->vm_flags); |
---|
| 366 | +} |
---|
355 | 367 | |
---|
356 | 368 | /* linux/mm/vmscan.c */ |
---|
357 | 369 | extern unsigned long zone_reclaimable_pages(struct zone *zone); |
---|
.. | .. |
---|
369 | 381 | extern unsigned long shrink_all_memory(unsigned long nr_pages); |
---|
370 | 382 | extern int vm_swappiness; |
---|
371 | 383 | extern int remove_mapping(struct address_space *mapping, struct page *page); |
---|
372 | | -extern unsigned long vm_total_pages; |
---|
373 | 384 | |
---|
| 385 | +extern unsigned long reclaim_pages(struct list_head *page_list); |
---|
374 | 386 | #ifdef CONFIG_NUMA |
---|
375 | 387 | extern int node_reclaim_mode; |
---|
376 | 388 | extern int sysctl_min_unmapped_ratio; |
---|
.. | .. |
---|
379 | 391 | #define node_reclaim_mode 0 |
---|
380 | 392 | #endif |
---|
381 | 393 | |
---|
382 | | -extern int page_evictable(struct page *page); |
---|
383 | 394 | extern void check_move_unevictable_pages(struct pagevec *pvec); |
---|
384 | 395 | |
---|
385 | 396 | extern int kswapd_run(int nid); |
---|
.. | .. |
---|
413 | 424 | extern unsigned long total_swapcache_pages(void); |
---|
414 | 425 | extern void show_swap_cache_info(void); |
---|
415 | 426 | extern int add_to_swap(struct page *page); |
---|
416 | | -extern int add_to_swap_cache(struct page *, swp_entry_t, gfp_t); |
---|
417 | | -extern int __add_to_swap_cache(struct page *page, swp_entry_t entry); |
---|
418 | | -extern void __delete_from_swap_cache(struct page *); |
---|
| 427 | +extern void *get_shadow_from_swap_cache(swp_entry_t entry); |
---|
| 428 | +extern int add_to_swap_cache(struct page *page, swp_entry_t entry, |
---|
| 429 | + gfp_t gfp, void **shadowp); |
---|
| 430 | +extern void __delete_from_swap_cache(struct page *page, |
---|
| 431 | + swp_entry_t entry, void *shadow); |
---|
419 | 432 | extern void delete_from_swap_cache(struct page *); |
---|
| 433 | +extern void clear_shadow_from_swap_cache(int type, unsigned long begin, |
---|
| 434 | + unsigned long end); |
---|
420 | 435 | extern void free_page_and_swap_cache(struct page *); |
---|
421 | 436 | extern void free_pages_and_swap_cache(struct page **, int); |
---|
422 | 437 | extern struct page *lookup_swap_cache(swp_entry_t entry, |
---|
423 | 438 | struct vm_area_struct *vma, |
---|
424 | 439 | unsigned long addr); |
---|
| 440 | +struct page *find_get_incore_page(struct address_space *mapping, pgoff_t index); |
---|
425 | 441 | extern struct page *read_swap_cache_async(swp_entry_t, gfp_t, |
---|
426 | 442 | struct vm_area_struct *vma, unsigned long addr, |
---|
427 | 443 | bool do_poll); |
---|
.. | .. |
---|
462 | 478 | extern void swap_free(swp_entry_t); |
---|
463 | 479 | extern void swapcache_free_entries(swp_entry_t *entries, int n); |
---|
464 | 480 | extern int free_swap_and_cache(swp_entry_t); |
---|
465 | | -extern int swap_type_of(dev_t, sector_t, struct block_device **); |
---|
| 481 | +int swap_type_of(dev_t device, sector_t offset); |
---|
| 482 | +int find_first_swap(dev_t *device); |
---|
466 | 483 | extern unsigned int count_swap_pages(int, int); |
---|
467 | 484 | extern sector_t map_swap_page(struct page *, struct block_device **); |
---|
468 | 485 | extern sector_t swapdev_block(int, pgoff_t); |
---|
469 | 486 | extern int page_swapcount(struct page *); |
---|
470 | | -extern int __swap_count(struct swap_info_struct *si, swp_entry_t entry); |
---|
| 487 | +extern int __swap_count(swp_entry_t entry); |
---|
471 | 488 | extern int __swp_swapcount(swp_entry_t entry); |
---|
472 | 489 | extern int swp_swapcount(swp_entry_t entry); |
---|
473 | 490 | extern struct swap_info_struct *page_swap_info(struct page *); |
---|
.. | .. |
---|
477 | 494 | struct backing_dev_info; |
---|
478 | 495 | extern int init_swap_address_space(unsigned int type, unsigned long nr_pages); |
---|
479 | 496 | extern void exit_swap_address_space(unsigned int type); |
---|
| 497 | +extern struct swap_info_struct *get_swap_device(swp_entry_t entry); |
---|
| 498 | +sector_t swap_page_sector(struct page *page); |
---|
| 499 | + |
---|
| 500 | +static inline void put_swap_device(struct swap_info_struct *si) |
---|
| 501 | +{ |
---|
| 502 | + rcu_read_unlock(); |
---|
| 503 | +} |
---|
480 | 504 | |
---|
481 | 505 | #else /* CONFIG_SWAP */ |
---|
482 | 506 | |
---|
.. | .. |
---|
558 | 582 | return NULL; |
---|
559 | 583 | } |
---|
560 | 584 | |
---|
| 585 | +static inline |
---|
| 586 | +struct page *find_get_incore_page(struct address_space *mapping, pgoff_t index) |
---|
| 587 | +{ |
---|
| 588 | + return find_get_page(mapping, index); |
---|
| 589 | +} |
---|
| 590 | + |
---|
561 | 591 | static inline int add_to_swap(struct page *page) |
---|
562 | 592 | { |
---|
563 | 593 | return 0; |
---|
564 | 594 | } |
---|
565 | 595 | |
---|
| 596 | +static inline void *get_shadow_from_swap_cache(swp_entry_t entry) |
---|
| 597 | +{ |
---|
| 598 | + return NULL; |
---|
| 599 | +} |
---|
| 600 | + |
---|
566 | 601 | static inline int add_to_swap_cache(struct page *page, swp_entry_t entry, |
---|
567 | | - gfp_t gfp_mask) |
---|
| 602 | + gfp_t gfp_mask, void **shadowp) |
---|
568 | 603 | { |
---|
569 | 604 | return -1; |
---|
570 | 605 | } |
---|
571 | 606 | |
---|
572 | | -static inline void __delete_from_swap_cache(struct page *page) |
---|
| 607 | +static inline void __delete_from_swap_cache(struct page *page, |
---|
| 608 | + swp_entry_t entry, void *shadow) |
---|
573 | 609 | { |
---|
574 | 610 | } |
---|
575 | 611 | |
---|
576 | 612 | static inline void delete_from_swap_cache(struct page *page) |
---|
| 613 | +{ |
---|
| 614 | +} |
---|
| 615 | + |
---|
| 616 | +static inline void clear_shadow_from_swap_cache(int type, unsigned long begin, |
---|
| 617 | + unsigned long end) |
---|
577 | 618 | { |
---|
578 | 619 | } |
---|
579 | 620 | |
---|
.. | .. |
---|
582 | 623 | return 0; |
---|
583 | 624 | } |
---|
584 | 625 | |
---|
585 | | -static inline int __swap_count(struct swap_info_struct *si, swp_entry_t entry) |
---|
| 626 | +static inline int __swap_count(swp_entry_t entry) |
---|
586 | 627 | { |
---|
587 | 628 | return 0; |
---|
588 | 629 | } |
---|
.. | .. |
---|
631 | 672 | return vm_swappiness; |
---|
632 | 673 | |
---|
633 | 674 | /* root ? */ |
---|
634 | | - if (mem_cgroup_disabled() || !memcg->css.parent) |
---|
| 675 | + if (mem_cgroup_disabled() || mem_cgroup_is_root(memcg)) |
---|
635 | 676 | return vm_swappiness; |
---|
636 | 677 | |
---|
637 | 678 | return memcg->swappiness; |
---|
.. | .. |
---|
644 | 685 | #endif |
---|
645 | 686 | |
---|
646 | 687 | #if defined(CONFIG_SWAP) && defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP) |
---|
647 | | -extern void mem_cgroup_throttle_swaprate(struct mem_cgroup *memcg, int node, |
---|
648 | | - gfp_t gfp_mask); |
---|
| 688 | +extern void __cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask); |
---|
| 689 | +static inline void cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask) |
---|
| 690 | +{ |
---|
| 691 | + if (mem_cgroup_disabled()) |
---|
| 692 | + return; |
---|
| 693 | + __cgroup_throttle_swaprate(page, gfp_mask); |
---|
| 694 | +} |
---|
649 | 695 | #else |
---|
650 | | -static inline void mem_cgroup_throttle_swaprate(struct mem_cgroup *memcg, |
---|
651 | | - int node, gfp_t gfp_mask) |
---|
| 696 | +static inline void cgroup_throttle_swaprate(struct page *page, gfp_t gfp_mask) |
---|
652 | 697 | { |
---|
653 | 698 | } |
---|
654 | 699 | #endif |
---|
655 | 700 | |
---|
656 | 701 | #ifdef CONFIG_MEMCG_SWAP |
---|
657 | 702 | extern void mem_cgroup_swapout(struct page *page, swp_entry_t entry); |
---|
658 | | -extern int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry); |
---|
659 | | -extern void mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_pages); |
---|
| 703 | +extern int __mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry); |
---|
| 704 | +static inline int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry) |
---|
| 705 | +{ |
---|
| 706 | + if (mem_cgroup_disabled()) |
---|
| 707 | + return 0; |
---|
| 708 | + return __mem_cgroup_try_charge_swap(page, entry); |
---|
| 709 | +} |
---|
| 710 | + |
---|
| 711 | +extern void __mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_pages); |
---|
| 712 | +static inline void mem_cgroup_uncharge_swap(swp_entry_t entry, unsigned int nr_pages) |
---|
| 713 | +{ |
---|
| 714 | + if (mem_cgroup_disabled()) |
---|
| 715 | + return; |
---|
| 716 | + __mem_cgroup_uncharge_swap(entry, nr_pages); |
---|
| 717 | +} |
---|
| 718 | + |
---|
660 | 719 | extern long mem_cgroup_get_nr_swap_pages(struct mem_cgroup *memcg); |
---|
661 | 720 | extern bool mem_cgroup_swap_full(struct page *page); |
---|
662 | 721 | #else |
---|