diff options
| -rw-r--r-- | include/linux/memcontrol.h | 38 | ||||
| -rw-r--r-- | include/linux/swap.h | 2 | ||||
| -rw-r--r-- | mm/memcontrol.c | 190 | ||||
| -rw-r--r-- | mm/vmscan.c | 19 | ||||
| -rw-r--r-- | mm/workingset.c | 6 |
5 files changed, 111 insertions, 144 deletions
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index f4963ee4fdbc..b759827b2f1e 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h | |||
| @@ -60,7 +60,7 @@ enum mem_cgroup_stat_index { | |||
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | struct mem_cgroup_reclaim_cookie { | 62 | struct mem_cgroup_reclaim_cookie { |
| 63 | struct zone *zone; | 63 | pg_data_t *pgdat; |
| 64 | int priority; | 64 | int priority; |
| 65 | unsigned int generation; | 65 | unsigned int generation; |
| 66 | }; | 66 | }; |
| @@ -118,7 +118,7 @@ struct mem_cgroup_reclaim_iter { | |||
| 118 | /* | 118 | /* |
| 119 | * per-zone information in memory controller. | 119 | * per-zone information in memory controller. |
| 120 | */ | 120 | */ |
| 121 | struct mem_cgroup_per_zone { | 121 | struct mem_cgroup_per_node { |
| 122 | struct lruvec lruvec; | 122 | struct lruvec lruvec; |
| 123 | unsigned long lru_size[NR_LRU_LISTS]; | 123 | unsigned long lru_size[NR_LRU_LISTS]; |
| 124 | 124 | ||
| @@ -132,10 +132,6 @@ struct mem_cgroup_per_zone { | |||
| 132 | /* use container_of */ | 132 | /* use container_of */ |
| 133 | }; | 133 | }; |
| 134 | 134 | ||
| 135 | struct mem_cgroup_per_node { | ||
| 136 | struct mem_cgroup_per_zone zoneinfo[MAX_NR_ZONES]; | ||
| 137 | }; | ||
| 138 | |||
| 139 | struct mem_cgroup_threshold { | 135 | struct mem_cgroup_threshold { |
| 140 | struct eventfd_ctx *eventfd; | 136 | struct eventfd_ctx *eventfd; |
| 141 | unsigned long threshold; | 137 | unsigned long threshold; |
| @@ -314,19 +310,15 @@ void mem_cgroup_uncharge_list(struct list_head *page_list); | |||
| 314 | 310 | ||
| 315 | void mem_cgroup_migrate(struct page *oldpage, struct page *newpage); | 311 | void mem_cgroup_migrate(struct page *oldpage, struct page *newpage); |
| 316 | 312 | ||
| 317 | static inline struct mem_cgroup_per_zone * | 313 | static struct mem_cgroup_per_node * |
| 318 | mem_cgroup_zone_zoneinfo(struct mem_cgroup *memcg, struct zone *zone) | 314 | mem_cgroup_nodeinfo(struct mem_cgroup *memcg, int nid) |
| 319 | { | 315 | { |
| 320 | int nid = zone_to_nid(zone); | 316 | return memcg->nodeinfo[nid]; |
| 321 | int zid = zone_idx(zone); | ||
| 322 | |||
| 323 | return &memcg->nodeinfo[nid]->zoneinfo[zid]; | ||
| 324 | } | 317 | } |
| 325 | 318 | ||
| 326 | /** | 319 | /** |
| 327 | * mem_cgroup_lruvec - get the lru list vector for a node or a memcg zone | 320 | * mem_cgroup_lruvec - get the lru list vector for a node or a memcg zone |
| 328 | * @node: node of the wanted lruvec | 321 | * @node: node of the wanted lruvec |
| 329 | * @zone: zone of the wanted lruvec | ||
| 330 | * @memcg: memcg of the wanted lruvec | 322 | * @memcg: memcg of the wanted lruvec |
| 331 | * | 323 | * |
| 332 | * Returns the lru list vector holding pages for a given @node or a given | 324 | * Returns the lru list vector holding pages for a given @node or a given |
| @@ -334,9 +326,9 @@ mem_cgroup_zone_zoneinfo(struct mem_cgroup *memcg, struct zone *zone) | |||
| 334 | * is disabled. | 326 | * is disabled. |
| 335 | */ | 327 | */ |
| 336 | static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat, | 328 | static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat, |
| 337 | struct zone *zone, struct mem_cgroup *memcg) | 329 | struct mem_cgroup *memcg) |
| 338 | { | 330 | { |
| 339 | struct mem_cgroup_per_zone *mz; | 331 | struct mem_cgroup_per_node *mz; |
| 340 | struct lruvec *lruvec; | 332 | struct lruvec *lruvec; |
| 341 | 333 | ||
| 342 | if (mem_cgroup_disabled()) { | 334 | if (mem_cgroup_disabled()) { |
| @@ -344,7 +336,7 @@ static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat, | |||
| 344 | goto out; | 336 | goto out; |
| 345 | } | 337 | } |
| 346 | 338 | ||
| 347 | mz = mem_cgroup_zone_zoneinfo(memcg, zone); | 339 | mz = mem_cgroup_nodeinfo(memcg, pgdat->node_id); |
| 348 | lruvec = &mz->lruvec; | 340 | lruvec = &mz->lruvec; |
| 349 | out: | 341 | out: |
| 350 | /* | 342 | /* |
| @@ -352,8 +344,8 @@ out: | |||
| 352 | * we have to be prepared to initialize lruvec->pgdat here; | 344 | * we have to be prepared to initialize lruvec->pgdat here; |
| 353 | * and if offlined then reonlined, we need to reinitialize it. | 345 | * and if offlined then reonlined, we need to reinitialize it. |
| 354 | */ | 346 | */ |
| 355 | if (unlikely(lruvec->pgdat != zone->zone_pgdat)) | 347 | if (unlikely(lruvec->pgdat != pgdat)) |
| 356 | lruvec->pgdat = zone->zone_pgdat; | 348 | lruvec->pgdat = pgdat; |
| 357 | return lruvec; | 349 | return lruvec; |
| 358 | } | 350 | } |
| 359 | 351 | ||
| @@ -446,9 +438,9 @@ unsigned long mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg, | |||
| 446 | static inline | 438 | static inline |
| 447 | unsigned long mem_cgroup_get_lru_size(struct lruvec *lruvec, enum lru_list lru) | 439 | unsigned long mem_cgroup_get_lru_size(struct lruvec *lruvec, enum lru_list lru) |
| 448 | { | 440 | { |
| 449 | struct mem_cgroup_per_zone *mz; | 441 | struct mem_cgroup_per_node *mz; |
| 450 | 442 | ||
| 451 | mz = container_of(lruvec, struct mem_cgroup_per_zone, lruvec); | 443 | mz = container_of(lruvec, struct mem_cgroup_per_node, lruvec); |
| 452 | return mz->lru_size[lru]; | 444 | return mz->lru_size[lru]; |
| 453 | } | 445 | } |
| 454 | 446 | ||
| @@ -519,7 +511,7 @@ static inline void mem_cgroup_dec_page_stat(struct page *page, | |||
| 519 | mem_cgroup_update_page_stat(page, idx, -1); | 511 | mem_cgroup_update_page_stat(page, idx, -1); |
| 520 | } | 512 | } |
| 521 | 513 | ||
| 522 | unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, | 514 | unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, |
| 523 | gfp_t gfp_mask, | 515 | gfp_t gfp_mask, |
| 524 | unsigned long *total_scanned); | 516 | unsigned long *total_scanned); |
| 525 | 517 | ||
| @@ -611,7 +603,7 @@ static inline void mem_cgroup_migrate(struct page *old, struct page *new) | |||
| 611 | } | 603 | } |
| 612 | 604 | ||
| 613 | static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat, | 605 | static inline struct lruvec *mem_cgroup_lruvec(struct pglist_data *pgdat, |
| 614 | struct zone *zone, struct mem_cgroup *memcg) | 606 | struct mem_cgroup *memcg) |
| 615 | { | 607 | { |
| 616 | return node_lruvec(pgdat); | 608 | return node_lruvec(pgdat); |
| 617 | } | 609 | } |
| @@ -723,7 +715,7 @@ static inline void mem_cgroup_dec_page_stat(struct page *page, | |||
| 723 | } | 715 | } |
| 724 | 716 | ||
| 725 | static inline | 717 | static inline |
| 726 | unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, | 718 | unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, |
| 727 | gfp_t gfp_mask, | 719 | gfp_t gfp_mask, |
| 728 | unsigned long *total_scanned) | 720 | unsigned long *total_scanned) |
| 729 | { | 721 | { |
diff --git a/include/linux/swap.h b/include/linux/swap.h index 0ad616d7c381..2a23ddc96edd 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h | |||
| @@ -318,7 +318,7 @@ extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg, | |||
| 318 | bool may_swap); | 318 | bool may_swap); |
| 319 | extern unsigned long mem_cgroup_shrink_node(struct mem_cgroup *mem, | 319 | extern unsigned long mem_cgroup_shrink_node(struct mem_cgroup *mem, |
| 320 | gfp_t gfp_mask, bool noswap, | 320 | gfp_t gfp_mask, bool noswap, |
| 321 | struct zone *zone, | 321 | pg_data_t *pgdat, |
| 322 | unsigned long *nr_scanned); | 322 | unsigned long *nr_scanned); |
| 323 | extern unsigned long shrink_all_memory(unsigned long nr_pages); | 323 | extern unsigned long shrink_all_memory(unsigned long nr_pages); |
| 324 | extern int vm_swappiness; | 324 | extern int vm_swappiness; |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index c9ebec98e92a..9cbd40ebccd1 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
| @@ -132,15 +132,11 @@ static const char * const mem_cgroup_lru_names[] = { | |||
| 132 | * their hierarchy representation | 132 | * their hierarchy representation |
| 133 | */ | 133 | */ |
| 134 | 134 | ||
| 135 | struct mem_cgroup_tree_per_zone { | 135 | struct mem_cgroup_tree_per_node { |
| 136 | struct rb_root rb_root; | 136 | struct rb_root rb_root; |
| 137 | spinlock_t lock; | 137 | spinlock_t lock; |
| 138 | }; | 138 | }; |
| 139 | 139 | ||
| 140 | struct mem_cgroup_tree_per_node { | ||
| 141 | struct mem_cgroup_tree_per_zone rb_tree_per_zone[MAX_NR_ZONES]; | ||
| 142 | }; | ||
| 143 | |||
| 144 | struct mem_cgroup_tree { | 140 | struct mem_cgroup_tree { |
| 145 | struct mem_cgroup_tree_per_node *rb_tree_per_node[MAX_NUMNODES]; | 141 | struct mem_cgroup_tree_per_node *rb_tree_per_node[MAX_NUMNODES]; |
| 146 | }; | 142 | }; |
| @@ -374,37 +370,35 @@ ino_t page_cgroup_ino(struct page *page) | |||
| 374 | return ino; | 370 | return ino; |
| 375 | } | 371 | } |
| 376 | 372 | ||
| 377 | static struct mem_cgroup_per_zone * | 373 | static struct mem_cgroup_per_node * |
| 378 | mem_cgroup_page_zoneinfo(struct mem_cgroup *memcg, struct page *page) | 374 | mem_cgroup_page_nodeinfo(struct mem_cgroup *memcg, struct page *page) |
| 379 | { | 375 | { |
| 380 | int nid = page_to_nid(page); | 376 | int nid = page_to_nid(page); |
| 381 | int zid = page_zonenum(page); | ||
| 382 | 377 | ||
| 383 | return &memcg->nodeinfo[nid]->zoneinfo[zid]; | 378 | return memcg->nodeinfo[nid]; |
| 384 | } | 379 | } |
| 385 | 380 | ||
| 386 | static struct mem_cgroup_tree_per_zone * | 381 | static struct mem_cgroup_tree_per_node * |
| 387 | soft_limit_tree_node_zone(int nid, int zid) | 382 | soft_limit_tree_node(int nid) |
| 388 | { | 383 | { |
| 389 | return &soft_limit_tree.rb_tree_per_node[nid]->rb_tree_per_zone[zid]; | 384 | return soft_limit_tree.rb_tree_per_node[nid]; |
| 390 | } | 385 | } |
| 391 | 386 | ||
| 392 | static struct mem_cgroup_tree_per_zone * | 387 | static struct mem_cgroup_tree_per_node * |
| 393 | soft_limit_tree_from_page(struct page *page) | 388 | soft_limit_tree_from_page(struct page *page) |
| 394 | { | 389 | { |
| 395 | int nid = page_to_nid(page); | 390 | int nid = page_to_nid(page); |
| 396 | int zid = page_zonenum(page); | ||
| 397 | 391 | ||
| 398 | return &soft_limit_tree.rb_tree_per_node[nid]->rb_tree_per_zone[zid]; | 392 | return soft_limit_tree.rb_tree_per_node[nid]; |
| 399 | } | 393 | } |
| 400 | 394 | ||
| 401 | static void __mem_cgroup_insert_exceeded(struct mem_cgroup_per_zone *mz, | 395 | static void __mem_cgroup_insert_exceeded(struct mem_cgroup_per_node *mz, |
| 402 | struct mem_cgroup_tree_per_zone *mctz, | 396 | struct mem_cgroup_tree_per_node *mctz, |
| 403 | unsigned long new_usage_in_excess) | 397 | unsigned long new_usage_in_excess) |
| 404 | { | 398 | { |
| 405 | struct rb_node **p = &mctz->rb_root.rb_node; | 399 | struct rb_node **p = &mctz->rb_root.rb_node; |
| 406 | struct rb_node *parent = NULL; | 400 | struct rb_node *parent = NULL; |
| 407 | struct mem_cgroup_per_zone *mz_node; | 401 | struct mem_cgroup_per_node *mz_node; |
| 408 | 402 | ||
| 409 | if (mz->on_tree) | 403 | if (mz->on_tree) |
| 410 | return; | 404 | return; |
| @@ -414,7 +408,7 @@ static void __mem_cgroup_insert_exceeded(struct mem_cgroup_per_zone *mz, | |||
| 414 | return; | 408 | return; |
| 415 | while (*p) { | 409 | while (*p) { |
| 416 | parent = *p; | 410 | parent = *p; |
| 417 | mz_node = rb_entry(parent, struct mem_cgroup_per_zone, | 411 | mz_node = rb_entry(parent, struct mem_cgroup_per_node, |
| 418 | tree_node); | 412 | tree_node); |
| 419 | if (mz->usage_in_excess < mz_node->usage_in_excess) | 413 | if (mz->usage_in_excess < mz_node->usage_in_excess) |
| 420 | p = &(*p)->rb_left; | 414 | p = &(*p)->rb_left; |
| @@ -430,8 +424,8 @@ static void __mem_cgroup_insert_exceeded(struct mem_cgroup_per_zone *mz, | |||
| 430 | mz->on_tree = true; | 424 | mz->on_tree = true; |
| 431 | } | 425 | } |
| 432 | 426 | ||
| 433 | static void __mem_cgroup_remove_exceeded(struct mem_cgroup_per_zone *mz, | 427 | static void __mem_cgroup_remove_exceeded(struct mem_cgroup_per_node *mz, |
| 434 | struct mem_cgroup_tree_per_zone *mctz) | 428 | struct mem_cgroup_tree_per_node *mctz) |
| 435 | { | 429 | { |
| 436 | if (!mz->on_tree) | 430 | if (!mz->on_tree) |
| 437 | return; | 431 | return; |
| @@ -439,8 +433,8 @@ static void __mem_cgroup_remove_exceeded(struct mem_cgroup_per_zone *mz, | |||
| 439 | mz->on_tree = false; | 433 | mz->on_tree = false; |
| 440 | } | 434 | } |
| 441 | 435 | ||
| 442 | static void mem_cgroup_remove_exceeded(struct mem_cgroup_per_zone *mz, | 436 | static void mem_cgroup_remove_exceeded(struct mem_cgroup_per_node *mz, |
| 443 | struct mem_cgroup_tree_per_zone *mctz) | 437 | struct mem_cgroup_tree_per_node *mctz) |
| 444 | { | 438 | { |
| 445 | unsigned long flags; | 439 | unsigned long flags; |
| 446 | 440 | ||
| @@ -464,8 +458,8 @@ static unsigned long soft_limit_excess(struct mem_cgroup *memcg) | |||
| 464 | static void mem_cgroup_update_tree(struct mem_cgroup *memcg, struct page *page) | 458 | static void mem_cgroup_update_tree(struct mem_cgroup *memcg, struct page *page) |
| 465 | { | 459 | { |
| 466 | unsigned long excess; | 460 | unsigned long excess; |
| 467 | struct mem_cgroup_per_zone *mz; | 461 | struct mem_cgroup_per_node *mz; |
| 468 | struct mem_cgroup_tree_per_zone *mctz; | 462 | struct mem_cgroup_tree_per_node *mctz; |
| 469 | 463 | ||
| 470 | mctz = soft_limit_tree_from_page(page); | 464 | mctz = soft_limit_tree_from_page(page); |
| 471 | /* | 465 | /* |
| @@ -473,7 +467,7 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, struct page *page) | |||
| 473 | * because their event counter is not touched. | 467 | * because their event counter is not touched. |
| 474 | */ | 468 | */ |
| 475 | for (; memcg; memcg = parent_mem_cgroup(memcg)) { | 469 | for (; memcg; memcg = parent_mem_cgroup(memcg)) { |
| 476 | mz = mem_cgroup_page_zoneinfo(memcg, page); | 470 | mz = mem_cgroup_page_nodeinfo(memcg, page); |
| 477 | excess = soft_limit_excess(memcg); | 471 | excess = soft_limit_excess(memcg); |
| 478 | /* | 472 | /* |
| 479 | * We have to update the tree if mz is on RB-tree or | 473 | * We have to update the tree if mz is on RB-tree or |
| @@ -498,24 +492,22 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, struct page *page) | |||
| 498 | 492 | ||
| 499 | static void mem_cgroup_remove_from_trees(struct mem_cgroup *memcg) | 493 | static void mem_cgroup_remove_from_trees(struct mem_cgroup *memcg) |
| 500 | { | 494 | { |
| 501 | struct mem_cgroup_tree_per_zone *mctz; | 495 | struct mem_cgroup_tree_per_node *mctz; |
| 502 | struct mem_cgroup_per_zone *mz; | 496 | struct mem_cgroup_per_node *mz; |
| 503 | int nid, zid; | 497 | int nid; |
| 504 | 498 | ||
| 505 | for_each_node(nid) { | 499 | for_each_node(nid) { |
| 506 | for (zid = 0; zid < MAX_NR_ZONES; zid++) { | 500 | mz = mem_cgroup_nodeinfo(memcg, nid); |
| 507 | mz = &memcg->nodeinfo[nid]->zoneinfo[zid]; | 501 | mctz = soft_limit_tree_node(nid); |
| 508 | mctz = soft_limit_tree_node_zone(nid, zid); | 502 | mem_cgroup_remove_exceeded(mz, mctz); |
| 509 | mem_cgroup_remove_exceeded(mz, mctz); | ||
| 510 | } | ||
| 511 | } | 503 | } |
| 512 | } | 504 | } |
| 513 | 505 | ||
| 514 | static struct mem_cgroup_per_zone * | 506 | static struct mem_cgroup_per_node * |
| 515 | __mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz) | 507 | __mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_node *mctz) |
| 516 | { | 508 | { |
| 517 | struct rb_node *rightmost = NULL; | 509 | struct rb_node *rightmost = NULL; |
| 518 | struct mem_cgroup_per_zone *mz; | 510 | struct mem_cgroup_per_node *mz; |
| 519 | 511 | ||
| 520 | retry: | 512 | retry: |
| 521 | mz = NULL; | 513 | mz = NULL; |
| @@ -523,7 +515,7 @@ retry: | |||
| 523 | if (!rightmost) | 515 | if (!rightmost) |
| 524 | goto done; /* Nothing to reclaim from */ | 516 | goto done; /* Nothing to reclaim from */ |
| 525 | 517 | ||
| 526 | mz = rb_entry(rightmost, struct mem_cgroup_per_zone, tree_node); | 518 | mz = rb_entry(rightmost, struct mem_cgroup_per_node, tree_node); |
| 527 | /* | 519 | /* |
| 528 | * Remove the node now but someone else can add it back, | 520 | * Remove the node now but someone else can add it back, |
| 529 | * we will to add it back at the end of reclaim to its correct | 521 | * we will to add it back at the end of reclaim to its correct |
| @@ -537,10 +529,10 @@ done: | |||
| 537 | return mz; | 529 | return mz; |
| 538 | } | 530 | } |
| 539 | 531 | ||
| 540 | static struct mem_cgroup_per_zone * | 532 | static struct mem_cgroup_per_node * |
| 541 | mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_zone *mctz) | 533 | mem_cgroup_largest_soft_limit_node(struct mem_cgroup_tree_per_node *mctz) |
| 542 | { | 534 | { |
| 543 | struct mem_cgroup_per_zone *mz; | 535 | struct mem_cgroup_per_node *mz; |
| 544 | 536 | ||
| 545 | spin_lock_irq(&mctz->lock); | 537 | spin_lock_irq(&mctz->lock); |
| 546 | mz = __mem_cgroup_largest_soft_limit_node(mctz); | 538 | mz = __mem_cgroup_largest_soft_limit_node(mctz); |
| @@ -634,20 +626,16 @@ unsigned long mem_cgroup_node_nr_lru_pages(struct mem_cgroup *memcg, | |||
| 634 | int nid, unsigned int lru_mask) | 626 | int nid, unsigned int lru_mask) |
| 635 | { | 627 | { |
| 636 | unsigned long nr = 0; | 628 | unsigned long nr = 0; |
| 637 | int zid; | 629 | struct mem_cgroup_per_node *mz; |
| 630 | enum lru_list lru; | ||
| 638 | 631 | ||
| 639 | VM_BUG_ON((unsigned)nid >= nr_node_ids); | 632 | VM_BUG_ON((unsigned)nid >= nr_node_ids); |
| 640 | 633 | ||
| 641 | for (zid = 0; zid < MAX_NR_ZONES; zid++) { | 634 | for_each_lru(lru) { |
| 642 | struct mem_cgroup_per_zone *mz; | 635 | if (!(BIT(lru) & lru_mask)) |
| 643 | enum lru_list lru; | 636 | continue; |
| 644 | 637 | mz = mem_cgroup_nodeinfo(memcg, nid); | |
| 645 | for_each_lru(lru) { | 638 | nr += mz->lru_size[lru]; |
| 646 | if (!(BIT(lru) & lru_mask)) | ||
| 647 | continue; | ||
| 648 | mz = &memcg->nodeinfo[nid]->zoneinfo[zid]; | ||
| 649 | nr += mz->lru_size[lru]; | ||
| 650 | } | ||
| 651 | } | 639 | } |
| 652 | return nr; | 640 | return nr; |
| 653 | } | 641 | } |
| @@ -800,9 +788,9 @@ struct mem_cgroup *mem_cgroup_iter(struct mem_cgroup *root, | |||
| 800 | rcu_read_lock(); | 788 | rcu_read_lock(); |
| 801 | 789 | ||
| 802 | if (reclaim) { | 790 | if (reclaim) { |
| 803 | struct mem_cgroup_per_zone *mz; | 791 | struct mem_cgroup_per_node *mz; |
| 804 | 792 | ||
| 805 | mz = mem_cgroup_zone_zoneinfo(root, reclaim->zone); | 793 | mz = mem_cgroup_nodeinfo(root, reclaim->pgdat->node_id); |
| 806 | iter = &mz->iter[reclaim->priority]; | 794 | iter = &mz->iter[reclaim->priority]; |
| 807 | 795 | ||
| 808 | if (prev && reclaim->generation != iter->generation) | 796 | if (prev && reclaim->generation != iter->generation) |
| @@ -901,19 +889,17 @@ static void invalidate_reclaim_iterators(struct mem_cgroup *dead_memcg) | |||
| 901 | { | 889 | { |
| 902 | struct mem_cgroup *memcg = dead_memcg; | 890 | struct mem_cgroup *memcg = dead_memcg; |
| 903 | struct mem_cgroup_reclaim_iter *iter; | 891 | struct mem_cgroup_reclaim_iter *iter; |
| 904 | struct mem_cgroup_per_zone *mz; | 892 | struct mem_cgroup_per_node *mz; |
| 905 | int nid, zid; | 893 | int nid; |
| 906 | int i; | 894 | int i; |
| 907 | 895 | ||
| 908 | while ((memcg = parent_mem_cgroup(memcg))) { | 896 | while ((memcg = parent_mem_cgroup(memcg))) { |
| 909 | for_each_node(nid) { | 897 | for_each_node(nid) { |
| 910 | for (zid = 0; zid < MAX_NR_ZONES; zid++) { | 898 | mz = mem_cgroup_nodeinfo(memcg, nid); |
| 911 | mz = &memcg->nodeinfo[nid]->zoneinfo[zid]; | 899 | for (i = 0; i <= DEF_PRIORITY; i++) { |
| 912 | for (i = 0; i <= DEF_PRIORITY; i++) { | 900 | iter = &mz->iter[i]; |
| 913 | iter = &mz->iter[i]; | 901 | cmpxchg(&iter->position, |
| 914 | cmpxchg(&iter->position, | 902 | dead_memcg, NULL); |
| 915 | dead_memcg, NULL); | ||
| 916 | } | ||
| 917 | } | 903 | } |
| 918 | } | 904 | } |
| 919 | } | 905 | } |
| @@ -945,7 +931,7 @@ static void invalidate_reclaim_iterators(struct mem_cgroup *dead_memcg) | |||
| 945 | */ | 931 | */ |
| 946 | struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct pglist_data *pgdat) | 932 | struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct pglist_data *pgdat) |
| 947 | { | 933 | { |
| 948 | struct mem_cgroup_per_zone *mz; | 934 | struct mem_cgroup_per_node *mz; |
| 949 | struct mem_cgroup *memcg; | 935 | struct mem_cgroup *memcg; |
| 950 | struct lruvec *lruvec; | 936 | struct lruvec *lruvec; |
| 951 | 937 | ||
| @@ -962,7 +948,7 @@ struct lruvec *mem_cgroup_page_lruvec(struct page *page, struct pglist_data *pgd | |||
| 962 | if (!memcg) | 948 | if (!memcg) |
| 963 | memcg = root_mem_cgroup; | 949 | memcg = root_mem_cgroup; |
| 964 | 950 | ||
| 965 | mz = mem_cgroup_page_zoneinfo(memcg, page); | 951 | mz = mem_cgroup_page_nodeinfo(memcg, page); |
| 966 | lruvec = &mz->lruvec; | 952 | lruvec = &mz->lruvec; |
| 967 | out: | 953 | out: |
| 968 | /* | 954 | /* |
| @@ -989,7 +975,7 @@ out: | |||
| 989 | void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru, | 975 | void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru, |
| 990 | enum zone_type zid, int nr_pages) | 976 | enum zone_type zid, int nr_pages) |
| 991 | { | 977 | { |
| 992 | struct mem_cgroup_per_zone *mz; | 978 | struct mem_cgroup_per_node *mz; |
| 993 | unsigned long *lru_size; | 979 | unsigned long *lru_size; |
| 994 | long size; | 980 | long size; |
| 995 | bool empty; | 981 | bool empty; |
| @@ -999,7 +985,7 @@ void mem_cgroup_update_lru_size(struct lruvec *lruvec, enum lru_list lru, | |||
| 999 | if (mem_cgroup_disabled()) | 985 | if (mem_cgroup_disabled()) |
| 1000 | return; | 986 | return; |
| 1001 | 987 | ||
| 1002 | mz = container_of(lruvec, struct mem_cgroup_per_zone, lruvec); | 988 | mz = container_of(lruvec, struct mem_cgroup_per_node, lruvec); |
| 1003 | lru_size = mz->lru_size + lru; | 989 | lru_size = mz->lru_size + lru; |
| 1004 | empty = list_empty(lruvec->lists + lru); | 990 | empty = list_empty(lruvec->lists + lru); |
| 1005 | 991 | ||
| @@ -1392,7 +1378,7 @@ int mem_cgroup_select_victim_node(struct mem_cgroup *memcg) | |||
| 1392 | #endif | 1378 | #endif |
| 1393 | 1379 | ||
| 1394 | static int mem_cgroup_soft_reclaim(struct mem_cgroup *root_memcg, | 1380 | static int mem_cgroup_soft_reclaim(struct mem_cgroup *root_memcg, |
| 1395 | struct zone *zone, | 1381 | pg_data_t *pgdat, |
| 1396 | gfp_t gfp_mask, | 1382 | gfp_t gfp_mask, |
| 1397 | unsigned long *total_scanned) | 1383 | unsigned long *total_scanned) |
| 1398 | { | 1384 | { |
| @@ -1402,7 +1388,7 @@ static int mem_cgroup_soft_reclaim(struct mem_cgroup *root_memcg, | |||
| 1402 | unsigned long excess; | 1388 | unsigned long excess; |
| 1403 | unsigned long nr_scanned; | 1389 | unsigned long nr_scanned; |
| 1404 | struct mem_cgroup_reclaim_cookie reclaim = { | 1390 | struct mem_cgroup_reclaim_cookie reclaim = { |
| 1405 | .zone = zone, | 1391 | .pgdat = pgdat, |
| 1406 | .priority = 0, | 1392 | .priority = 0, |
| 1407 | }; | 1393 | }; |
| 1408 | 1394 | ||
| @@ -1433,7 +1419,7 @@ static int mem_cgroup_soft_reclaim(struct mem_cgroup *root_memcg, | |||
| 1433 | continue; | 1419 | continue; |
| 1434 | } | 1420 | } |
| 1435 | total += mem_cgroup_shrink_node(victim, gfp_mask, false, | 1421 | total += mem_cgroup_shrink_node(victim, gfp_mask, false, |
| 1436 | zone, &nr_scanned); | 1422 | pgdat, &nr_scanned); |
| 1437 | *total_scanned += nr_scanned; | 1423 | *total_scanned += nr_scanned; |
| 1438 | if (!soft_limit_excess(root_memcg)) | 1424 | if (!soft_limit_excess(root_memcg)) |
| 1439 | break; | 1425 | break; |
| @@ -2560,22 +2546,22 @@ static int mem_cgroup_resize_memsw_limit(struct mem_cgroup *memcg, | |||
| 2560 | return ret; | 2546 | return ret; |
| 2561 | } | 2547 | } |
| 2562 | 2548 | ||
| 2563 | unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, | 2549 | unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order, |
| 2564 | gfp_t gfp_mask, | 2550 | gfp_t gfp_mask, |
| 2565 | unsigned long *total_scanned) | 2551 | unsigned long *total_scanned) |
| 2566 | { | 2552 | { |
| 2567 | unsigned long nr_reclaimed = 0; | 2553 | unsigned long nr_reclaimed = 0; |
| 2568 | struct mem_cgroup_per_zone *mz, *next_mz = NULL; | 2554 | struct mem_cgroup_per_node *mz, *next_mz = NULL; |
| 2569 | unsigned long reclaimed; | 2555 | unsigned long reclaimed; |
| 2570 | int loop = 0; | 2556 | int loop = 0; |
| 2571 | struct mem_cgroup_tree_per_zone *mctz; | 2557 | struct mem_cgroup_tree_per_node *mctz; |
| 2572 | unsigned long excess; | 2558 | unsigned long excess; |
| 2573 | unsigned long nr_scanned; | 2559 | unsigned long nr_scanned; |
| 2574 | 2560 | ||
| 2575 | if (order > 0) | 2561 | if (order > 0) |
| 2576 | return 0; | 2562 | return 0; |
| 2577 | 2563 | ||
| 2578 | mctz = soft_limit_tree_node_zone(zone_to_nid(zone), zone_idx(zone)); | 2564 | mctz = soft_limit_tree_node(pgdat->node_id); |
| 2579 | /* | 2565 | /* |
| 2580 | * This loop can run a while, specially if mem_cgroup's continuously | 2566 | * This loop can run a while, specially if mem_cgroup's continuously |
| 2581 | * keep exceeding their soft limit and putting the system under | 2567 | * keep exceeding their soft limit and putting the system under |
| @@ -2590,7 +2576,7 @@ unsigned long mem_cgroup_soft_limit_reclaim(struct zone *zone, int order, | |||
| 2590 | break; | 2576 | break; |
| 2591 | 2577 | ||
| 2592 | nr_scanned = 0; | 2578 | nr_scanned = 0; |
| 2593 | reclaimed = mem_cgroup_soft_reclaim(mz->memcg, zone, | 2579 | reclaimed = mem_cgroup_soft_reclaim(mz->memcg, pgdat, |
| 2594 | gfp_mask, &nr_scanned); | 2580 | gfp_mask, &nr_scanned); |
| 2595 | nr_reclaimed += reclaimed; | 2581 | nr_reclaimed += reclaimed; |
| 2596 | *total_scanned += nr_scanned; | 2582 | *total_scanned += nr_scanned; |
| @@ -3211,22 +3197,21 @@ static int memcg_stat_show(struct seq_file *m, void *v) | |||
| 3211 | 3197 | ||
| 3212 | #ifdef CONFIG_DEBUG_VM | 3198 | #ifdef CONFIG_DEBUG_VM |
| 3213 | { | 3199 | { |
| 3214 | int nid, zid; | 3200 | pg_data_t *pgdat; |
| 3215 | struct mem_cgroup_per_zone *mz; | 3201 | struct mem_cgroup_per_node *mz; |
| 3216 | struct zone_reclaim_stat *rstat; | 3202 | struct zone_reclaim_stat *rstat; |
| 3217 | unsigned long recent_rotated[2] = {0, 0}; | 3203 | unsigned long recent_rotated[2] = {0, 0}; |
| 3218 | unsigned long recent_scanned[2] = {0, 0}; | 3204 | unsigned long recent_scanned[2] = {0, 0}; |
| 3219 | 3205 | ||
| 3220 | for_each_online_node(nid) | 3206 | for_each_online_pgdat(pgdat) { |
| 3221 | for (zid = 0; zid < MAX_NR_ZONES; zid++) { | 3207 | mz = mem_cgroup_nodeinfo(memcg, pgdat->node_id); |
| 3222 | mz = &memcg->nodeinfo[nid]->zoneinfo[zid]; | 3208 | rstat = &mz->lruvec.reclaim_stat; |
| 3223 | rstat = &mz->lruvec.reclaim_stat; | ||
| 3224 | 3209 | ||
| 3225 | recent_rotated[0] += rstat->recent_rotated[0]; | 3210 | recent_rotated[0] += rstat->recent_rotated[0]; |
| 3226 | recent_rotated[1] += rstat->recent_rotated[1]; | 3211 | recent_rotated[1] += rstat->recent_rotated[1]; |
| 3227 | recent_scanned[0] += rstat->recent_scanned[0]; | 3212 | recent_scanned[0] += rstat->recent_scanned[0]; |
| 3228 | recent_scanned[1] += rstat->recent_scanned[1]; | 3213 | recent_scanned[1] += rstat->recent_scanned[1]; |
| 3229 | } | 3214 | } |
| 3230 | seq_printf(m, "recent_rotated_anon %lu\n", recent_rotated[0]); | 3215 | seq_printf(m, "recent_rotated_anon %lu\n", recent_rotated[0]); |
| 3231 | seq_printf(m, "recent_rotated_file %lu\n", recent_rotated[1]); | 3216 | seq_printf(m, "recent_rotated_file %lu\n", recent_rotated[1]); |
| 3232 | seq_printf(m, "recent_scanned_anon %lu\n", recent_scanned[0]); | 3217 | seq_printf(m, "recent_scanned_anon %lu\n", recent_scanned[0]); |
| @@ -4106,11 +4091,10 @@ struct mem_cgroup *mem_cgroup_from_id(unsigned short id) | |||
| 4106 | return idr_find(&mem_cgroup_idr, id); | 4091 | return idr_find(&mem_cgroup_idr, id); |
| 4107 | } | 4092 | } |
| 4108 | 4093 | ||
| 4109 | static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node) | 4094 | static int alloc_mem_cgroup_per_node_info(struct mem_cgroup *memcg, int node) |
| 4110 | { | 4095 | { |
| 4111 | struct mem_cgroup_per_node *pn; | 4096 | struct mem_cgroup_per_node *pn; |
| 4112 | struct mem_cgroup_per_zone *mz; | 4097 | int tmp = node; |
| 4113 | int zone, tmp = node; | ||
| 4114 | /* | 4098 | /* |
| 4115 | * This routine is called against possible nodes. | 4099 | * This routine is called against possible nodes. |
| 4116 | * But it's BUG to call kmalloc() against offline node. | 4100 | * But it's BUG to call kmalloc() against offline node. |
| @@ -4125,18 +4109,16 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node) | |||
| 4125 | if (!pn) | 4109 | if (!pn) |
| 4126 | return 1; | 4110 | return 1; |
| 4127 | 4111 | ||
| 4128 | for (zone = 0; zone < MAX_NR_ZONES; zone++) { | 4112 | lruvec_init(&pn->lruvec); |
| 4129 | mz = &pn->zoneinfo[zone]; | 4113 | pn->usage_in_excess = 0; |
| 4130 | lruvec_init(&mz->lruvec); | 4114 | pn->on_tree = false; |
| 4131 | mz->usage_in_excess = 0; | 4115 | pn->memcg = memcg; |
| 4132 | mz->on_tree = false; | 4116 | |
| 4133 | mz->memcg = memcg; | ||
| 4134 | } | ||
| 4135 | memcg->nodeinfo[node] = pn; | 4117 | memcg->nodeinfo[node] = pn; |
| 4136 | return 0; | 4118 | return 0; |
| 4137 | } | 4119 | } |
| 4138 | 4120 | ||
| 4139 | static void free_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node) | 4121 | static void free_mem_cgroup_per_node_info(struct mem_cgroup *memcg, int node) |
| 4140 | { | 4122 | { |
| 4141 | kfree(memcg->nodeinfo[node]); | 4123 | kfree(memcg->nodeinfo[node]); |
| 4142 | } | 4124 | } |
| @@ -4147,7 +4129,7 @@ static void mem_cgroup_free(struct mem_cgroup *memcg) | |||
| 4147 | 4129 | ||
| 4148 | memcg_wb_domain_exit(memcg); | 4130 | memcg_wb_domain_exit(memcg); |
| 4149 | for_each_node(node) | 4131 | for_each_node(node) |
| 4150 | free_mem_cgroup_per_zone_info(memcg, node); | 4132 | free_mem_cgroup_per_node_info(memcg, node); |
| 4151 | free_percpu(memcg->stat); | 4133 | free_percpu(memcg->stat); |
| 4152 | kfree(memcg); | 4134 | kfree(memcg); |
| 4153 | } | 4135 | } |
| @@ -4176,7 +4158,7 @@ static struct mem_cgroup *mem_cgroup_alloc(void) | |||
| 4176 | goto fail; | 4158 | goto fail; |
| 4177 | 4159 | ||
| 4178 | for_each_node(node) | 4160 | for_each_node(node) |
| 4179 | if (alloc_mem_cgroup_per_zone_info(memcg, node)) | 4161 | if (alloc_mem_cgroup_per_node_info(memcg, node)) |
| 4180 | goto fail; | 4162 | goto fail; |
| 4181 | 4163 | ||
| 4182 | if (memcg_wb_domain_init(memcg, GFP_KERNEL)) | 4164 | if (memcg_wb_domain_init(memcg, GFP_KERNEL)) |
| @@ -5779,18 +5761,12 @@ static int __init mem_cgroup_init(void) | |||
| 5779 | 5761 | ||
| 5780 | for_each_node(node) { | 5762 | for_each_node(node) { |
| 5781 | struct mem_cgroup_tree_per_node *rtpn; | 5763 | struct mem_cgroup_tree_per_node *rtpn; |
| 5782 | int zone; | ||
| 5783 | 5764 | ||
| 5784 | rtpn = kzalloc_node(sizeof(*rtpn), GFP_KERNEL, | 5765 | rtpn = kzalloc_node(sizeof(*rtpn), GFP_KERNEL, |
| 5785 | node_online(node) ? node : NUMA_NO_NODE); | 5766 | node_online(node) ? node : NUMA_NO_NODE); |
| 5786 | 5767 | ||
| 5787 | for (zone = 0; zone < MAX_NR_ZONES; zone++) { | 5768 | rtpn->rb_root = RB_ROOT; |
| 5788 | struct mem_cgroup_tree_per_zone *rtpz; | 5769 | spin_lock_init(&rtpn->lock); |
| 5789 | |||
| 5790 | rtpz = &rtpn->rb_tree_per_zone[zone]; | ||
| 5791 | rtpz->rb_root = RB_ROOT; | ||
| 5792 | spin_lock_init(&rtpz->lock); | ||
| 5793 | } | ||
| 5794 | soft_limit_tree.rb_tree_per_node[node] = rtpn; | 5770 | soft_limit_tree.rb_tree_per_node[node] = rtpn; |
| 5795 | } | 5771 | } |
| 5796 | 5772 | ||
diff --git a/mm/vmscan.c b/mm/vmscan.c index 46f7a71ed13b..9f6e673efba7 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
| @@ -2229,8 +2229,7 @@ static inline void init_tlb_ubc(void) | |||
| 2229 | static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memcg, | 2229 | static void shrink_node_memcg(struct pglist_data *pgdat, struct mem_cgroup *memcg, |
| 2230 | struct scan_control *sc, unsigned long *lru_pages) | 2230 | struct scan_control *sc, unsigned long *lru_pages) |
| 2231 | { | 2231 | { |
| 2232 | struct zone *zone = &pgdat->node_zones[sc->reclaim_idx]; | 2232 | struct lruvec *lruvec = mem_cgroup_lruvec(pgdat, memcg); |
| 2233 | struct lruvec *lruvec = mem_cgroup_lruvec(pgdat, zone, memcg); | ||
| 2234 | unsigned long nr[NR_LRU_LISTS]; | 2233 | unsigned long nr[NR_LRU_LISTS]; |
| 2235 | unsigned long targets[NR_LRU_LISTS]; | 2234 | unsigned long targets[NR_LRU_LISTS]; |
| 2236 | unsigned long nr_to_scan; | 2235 | unsigned long nr_to_scan; |
| @@ -2439,7 +2438,7 @@ static bool shrink_node(pg_data_t *pgdat, struct scan_control *sc, | |||
| 2439 | do { | 2438 | do { |
| 2440 | struct mem_cgroup *root = sc->target_mem_cgroup; | 2439 | struct mem_cgroup *root = sc->target_mem_cgroup; |
| 2441 | struct mem_cgroup_reclaim_cookie reclaim = { | 2440 | struct mem_cgroup_reclaim_cookie reclaim = { |
| 2442 | .zone = &pgdat->node_zones[classzone_idx], | 2441 | .pgdat = pgdat, |
| 2443 | .priority = sc->priority, | 2442 | .priority = sc->priority, |
| 2444 | }; | 2443 | }; |
| 2445 | unsigned long node_lru_pages = 0; | 2444 | unsigned long node_lru_pages = 0; |
| @@ -2647,7 +2646,7 @@ static void shrink_zones(struct zonelist *zonelist, struct scan_control *sc) | |||
| 2647 | * and balancing, not for a memcg's limit. | 2646 | * and balancing, not for a memcg's limit. |
| 2648 | */ | 2647 | */ |
| 2649 | nr_soft_scanned = 0; | 2648 | nr_soft_scanned = 0; |
| 2650 | nr_soft_reclaimed = mem_cgroup_soft_limit_reclaim(zone, | 2649 | nr_soft_reclaimed = mem_cgroup_soft_limit_reclaim(zone->zone_pgdat, |
| 2651 | sc->order, sc->gfp_mask, | 2650 | sc->order, sc->gfp_mask, |
| 2652 | &nr_soft_scanned); | 2651 | &nr_soft_scanned); |
| 2653 | sc->nr_reclaimed += nr_soft_reclaimed; | 2652 | sc->nr_reclaimed += nr_soft_reclaimed; |
| @@ -2917,7 +2916,7 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order, | |||
| 2917 | 2916 | ||
| 2918 | unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg, | 2917 | unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg, |
| 2919 | gfp_t gfp_mask, bool noswap, | 2918 | gfp_t gfp_mask, bool noswap, |
| 2920 | struct zone *zone, | 2919 | pg_data_t *pgdat, |
| 2921 | unsigned long *nr_scanned) | 2920 | unsigned long *nr_scanned) |
| 2922 | { | 2921 | { |
| 2923 | struct scan_control sc = { | 2922 | struct scan_control sc = { |
| @@ -2944,7 +2943,7 @@ unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg, | |||
| 2944 | * will pick up pages from other mem cgroup's as well. We hack | 2943 | * will pick up pages from other mem cgroup's as well. We hack |
| 2945 | * the priority and make it zero. | 2944 | * the priority and make it zero. |
| 2946 | */ | 2945 | */ |
| 2947 | shrink_node_memcg(zone->zone_pgdat, memcg, &sc, &lru_pages); | 2946 | shrink_node_memcg(pgdat, memcg, &sc, &lru_pages); |
| 2948 | 2947 | ||
| 2949 | trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed); | 2948 | trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed); |
| 2950 | 2949 | ||
| @@ -2994,7 +2993,7 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg, | |||
| 2994 | #endif | 2993 | #endif |
| 2995 | 2994 | ||
| 2996 | static void age_active_anon(struct pglist_data *pgdat, | 2995 | static void age_active_anon(struct pglist_data *pgdat, |
| 2997 | struct zone *zone, struct scan_control *sc) | 2996 | struct scan_control *sc) |
| 2998 | { | 2997 | { |
| 2999 | struct mem_cgroup *memcg; | 2998 | struct mem_cgroup *memcg; |
| 3000 | 2999 | ||
| @@ -3003,7 +3002,7 @@ static void age_active_anon(struct pglist_data *pgdat, | |||
| 3003 | 3002 | ||
| 3004 | memcg = mem_cgroup_iter(NULL, NULL, NULL); | 3003 | memcg = mem_cgroup_iter(NULL, NULL, NULL); |
| 3005 | do { | 3004 | do { |
| 3006 | struct lruvec *lruvec = mem_cgroup_lruvec(pgdat, zone, memcg); | 3005 | struct lruvec *lruvec = mem_cgroup_lruvec(pgdat, memcg); |
| 3007 | 3006 | ||
| 3008 | if (inactive_list_is_low(lruvec, false)) | 3007 | if (inactive_list_is_low(lruvec, false)) |
| 3009 | shrink_active_list(SWAP_CLUSTER_MAX, lruvec, | 3008 | shrink_active_list(SWAP_CLUSTER_MAX, lruvec, |
| @@ -3193,7 +3192,7 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx) | |||
| 3193 | * pages are rotated regardless of classzone as this is | 3192 | * pages are rotated regardless of classzone as this is |
| 3194 | * about consistent aging. | 3193 | * about consistent aging. |
| 3195 | */ | 3194 | */ |
| 3196 | age_active_anon(pgdat, &pgdat->node_zones[MAX_NR_ZONES - 1], &sc); | 3195 | age_active_anon(pgdat, &sc); |
| 3197 | 3196 | ||
| 3198 | /* | 3197 | /* |
| 3199 | * If we're getting trouble reclaiming, start doing writepage | 3198 | * If we're getting trouble reclaiming, start doing writepage |
| @@ -3205,7 +3204,7 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int classzone_idx) | |||
| 3205 | /* Call soft limit reclaim before calling shrink_node. */ | 3204 | /* Call soft limit reclaim before calling shrink_node. */ |
| 3206 | sc.nr_scanned = 0; | 3205 | sc.nr_scanned = 0; |
| 3207 | nr_soft_scanned = 0; | 3206 | nr_soft_scanned = 0; |
| 3208 | nr_soft_reclaimed = mem_cgroup_soft_limit_reclaim(zone, sc.order, | 3207 | nr_soft_reclaimed = mem_cgroup_soft_limit_reclaim(pgdat, sc.order, |
| 3209 | sc.gfp_mask, &nr_soft_scanned); | 3208 | sc.gfp_mask, &nr_soft_scanned); |
| 3210 | sc.nr_reclaimed += nr_soft_reclaimed; | 3209 | sc.nr_reclaimed += nr_soft_reclaimed; |
| 3211 | 3210 | ||
diff --git a/mm/workingset.c b/mm/workingset.c index df0dacaf54ee..2af14bb5a349 100644 --- a/mm/workingset.c +++ b/mm/workingset.c | |||
| @@ -218,7 +218,7 @@ void *workingset_eviction(struct address_space *mapping, struct page *page) | |||
| 218 | VM_BUG_ON_PAGE(page_count(page), page); | 218 | VM_BUG_ON_PAGE(page_count(page), page); |
| 219 | VM_BUG_ON_PAGE(!PageLocked(page), page); | 219 | VM_BUG_ON_PAGE(!PageLocked(page), page); |
| 220 | 220 | ||
| 221 | lruvec = mem_cgroup_lruvec(zone->zone_pgdat, zone, memcg); | 221 | lruvec = mem_cgroup_lruvec(zone->zone_pgdat, memcg); |
| 222 | eviction = atomic_long_inc_return(&lruvec->inactive_age); | 222 | eviction = atomic_long_inc_return(&lruvec->inactive_age); |
| 223 | return pack_shadow(memcgid, zone, eviction); | 223 | return pack_shadow(memcgid, zone, eviction); |
| 224 | } | 224 | } |
| @@ -267,7 +267,7 @@ bool workingset_refault(void *shadow) | |||
| 267 | rcu_read_unlock(); | 267 | rcu_read_unlock(); |
| 268 | return false; | 268 | return false; |
| 269 | } | 269 | } |
| 270 | lruvec = mem_cgroup_lruvec(zone->zone_pgdat, zone, memcg); | 270 | lruvec = mem_cgroup_lruvec(zone->zone_pgdat, memcg); |
| 271 | refault = atomic_long_read(&lruvec->inactive_age); | 271 | refault = atomic_long_read(&lruvec->inactive_age); |
| 272 | active_file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE); | 272 | active_file = lruvec_lru_size(lruvec, LRU_ACTIVE_FILE); |
| 273 | rcu_read_unlock(); | 273 | rcu_read_unlock(); |
| @@ -319,7 +319,7 @@ void workingset_activation(struct page *page) | |||
| 319 | memcg = page_memcg_rcu(page); | 319 | memcg = page_memcg_rcu(page); |
| 320 | if (!mem_cgroup_disabled() && !memcg) | 320 | if (!mem_cgroup_disabled() && !memcg) |
| 321 | goto out; | 321 | goto out; |
| 322 | lruvec = mem_cgroup_lruvec(page_pgdat(page), page_zone(page), memcg); | 322 | lruvec = mem_cgroup_lruvec(page_pgdat(page), memcg); |
| 323 | atomic_long_inc(&lruvec->inactive_age); | 323 | atomic_long_inc(&lruvec->inactive_age); |
| 324 | out: | 324 | out: |
| 325 | rcu_read_unlock(); | 325 | rcu_read_unlock(); |
