diff options
| -rw-r--r-- | include/linux/page_cgroup.h | 4 | ||||
| -rw-r--r-- | mm/memcontrol.c | 4 | ||||
| -rw-r--r-- | mm/page_cgroup.c | 56 |
3 files changed, 24 insertions, 40 deletions
diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h index aaa60da8783c..1153095ee457 100644 --- a/include/linux/page_cgroup.h +++ b/include/linux/page_cgroup.h | |||
| @@ -149,7 +149,7 @@ static inline void __init page_cgroup_init_flatmem(void) | |||
| 149 | extern unsigned short swap_cgroup_cmpxchg(swp_entry_t ent, | 149 | extern unsigned short swap_cgroup_cmpxchg(swp_entry_t ent, |
| 150 | unsigned short old, unsigned short new); | 150 | unsigned short old, unsigned short new); |
| 151 | extern unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id); | 151 | extern unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id); |
| 152 | extern unsigned short lookup_swap_cgroup(swp_entry_t ent); | 152 | extern unsigned short lookup_swap_cgroup_id(swp_entry_t ent); |
| 153 | extern int swap_cgroup_swapon(int type, unsigned long max_pages); | 153 | extern int swap_cgroup_swapon(int type, unsigned long max_pages); |
| 154 | extern void swap_cgroup_swapoff(int type); | 154 | extern void swap_cgroup_swapoff(int type); |
| 155 | #else | 155 | #else |
| @@ -161,7 +161,7 @@ unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id) | |||
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | static inline | 163 | static inline |
| 164 | unsigned short lookup_swap_cgroup(swp_entry_t ent) | 164 | unsigned short lookup_swap_cgroup_id(swp_entry_t ent) |
| 165 | { | 165 | { |
| 166 | return 0; | 166 | return 0; |
| 167 | } | 167 | } |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 71a9774e6ead..4c53e971749e 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
| @@ -2474,7 +2474,7 @@ struct mem_cgroup *try_get_mem_cgroup_from_page(struct page *page) | |||
| 2474 | memcg = NULL; | 2474 | memcg = NULL; |
| 2475 | } else if (PageSwapCache(page)) { | 2475 | } else if (PageSwapCache(page)) { |
| 2476 | ent.val = page_private(page); | 2476 | ent.val = page_private(page); |
| 2477 | id = lookup_swap_cgroup(ent); | 2477 | id = lookup_swap_cgroup_id(ent); |
| 2478 | rcu_read_lock(); | 2478 | rcu_read_lock(); |
| 2479 | memcg = mem_cgroup_lookup(id); | 2479 | memcg = mem_cgroup_lookup(id); |
| 2480 | if (memcg && !css_tryget(&memcg->css)) | 2480 | if (memcg && !css_tryget(&memcg->css)) |
| @@ -5264,7 +5264,7 @@ static int is_target_pte_for_mc(struct vm_area_struct *vma, | |||
| 5264 | } | 5264 | } |
| 5265 | /* There is a swap entry and a page doesn't exist or isn't charged */ | 5265 | /* There is a swap entry and a page doesn't exist or isn't charged */ |
| 5266 | if (ent.val && !ret && | 5266 | if (ent.val && !ret && |
| 5267 | css_id(&mc.from->css) == lookup_swap_cgroup(ent)) { | 5267 | css_id(&mc.from->css) == lookup_swap_cgroup_id(ent)) { |
| 5268 | ret = MC_TARGET_SWAP; | 5268 | ret = MC_TARGET_SWAP; |
| 5269 | if (target) | 5269 | if (target) |
| 5270 | target->ent = ent; | 5270 | target->ent = ent; |
diff --git a/mm/page_cgroup.c b/mm/page_cgroup.c index e910524e5a08..b99d19edf89b 100644 --- a/mm/page_cgroup.c +++ b/mm/page_cgroup.c | |||
| @@ -334,7 +334,6 @@ struct swap_cgroup { | |||
| 334 | unsigned short id; | 334 | unsigned short id; |
| 335 | }; | 335 | }; |
| 336 | #define SC_PER_PAGE (PAGE_SIZE/sizeof(struct swap_cgroup)) | 336 | #define SC_PER_PAGE (PAGE_SIZE/sizeof(struct swap_cgroup)) |
| 337 | #define SC_POS_MASK (SC_PER_PAGE - 1) | ||
| 338 | 337 | ||
| 339 | /* | 338 | /* |
| 340 | * SwapCgroup implements "lookup" and "exchange" operations. | 339 | * SwapCgroup implements "lookup" and "exchange" operations. |
| @@ -376,6 +375,21 @@ not_enough_page: | |||
| 376 | return -ENOMEM; | 375 | return -ENOMEM; |
| 377 | } | 376 | } |
| 378 | 377 | ||
| 378 | static struct swap_cgroup *lookup_swap_cgroup(swp_entry_t ent, | ||
| 379 | struct swap_cgroup_ctrl **ctrlp) | ||
| 380 | { | ||
| 381 | pgoff_t offset = swp_offset(ent); | ||
| 382 | struct swap_cgroup_ctrl *ctrl; | ||
| 383 | struct page *mappage; | ||
| 384 | |||
| 385 | ctrl = &swap_cgroup_ctrl[swp_type(ent)]; | ||
| 386 | if (ctrlp) | ||
| 387 | *ctrlp = ctrl; | ||
| 388 | |||
| 389 | mappage = ctrl->map[offset / SC_PER_PAGE]; | ||
| 390 | return page_address(mappage) + offset % SC_PER_PAGE; | ||
| 391 | } | ||
| 392 | |||
| 379 | /** | 393 | /** |
| 380 | * swap_cgroup_cmpxchg - cmpxchg mem_cgroup's id for this swp_entry. | 394 | * swap_cgroup_cmpxchg - cmpxchg mem_cgroup's id for this swp_entry. |
| 381 | * @end: swap entry to be cmpxchged | 395 | * @end: swap entry to be cmpxchged |
| @@ -388,21 +402,13 @@ not_enough_page: | |||
| 388 | unsigned short swap_cgroup_cmpxchg(swp_entry_t ent, | 402 | unsigned short swap_cgroup_cmpxchg(swp_entry_t ent, |
| 389 | unsigned short old, unsigned short new) | 403 | unsigned short old, unsigned short new) |
| 390 | { | 404 | { |
| 391 | int type = swp_type(ent); | ||
| 392 | unsigned long offset = swp_offset(ent); | ||
| 393 | unsigned long idx = offset / SC_PER_PAGE; | ||
| 394 | unsigned long pos = offset & SC_POS_MASK; | ||
| 395 | struct swap_cgroup_ctrl *ctrl; | 405 | struct swap_cgroup_ctrl *ctrl; |
| 396 | struct page *mappage; | ||
| 397 | struct swap_cgroup *sc; | 406 | struct swap_cgroup *sc; |
| 398 | unsigned long flags; | 407 | unsigned long flags; |
| 399 | unsigned short retval; | 408 | unsigned short retval; |
| 400 | 409 | ||
| 401 | ctrl = &swap_cgroup_ctrl[type]; | 410 | sc = lookup_swap_cgroup(ent, &ctrl); |
| 402 | 411 | ||
| 403 | mappage = ctrl->map[idx]; | ||
| 404 | sc = page_address(mappage); | ||
| 405 | sc += pos; | ||
| 406 | spin_lock_irqsave(&ctrl->lock, flags); | 412 | spin_lock_irqsave(&ctrl->lock, flags); |
| 407 | retval = sc->id; | 413 | retval = sc->id; |
| 408 | if (retval == old) | 414 | if (retval == old) |
| @@ -423,21 +429,13 @@ unsigned short swap_cgroup_cmpxchg(swp_entry_t ent, | |||
| 423 | */ | 429 | */ |
| 424 | unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id) | 430 | unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id) |
| 425 | { | 431 | { |
| 426 | int type = swp_type(ent); | ||
| 427 | unsigned long offset = swp_offset(ent); | ||
| 428 | unsigned long idx = offset / SC_PER_PAGE; | ||
| 429 | unsigned long pos = offset & SC_POS_MASK; | ||
| 430 | struct swap_cgroup_ctrl *ctrl; | 432 | struct swap_cgroup_ctrl *ctrl; |
| 431 | struct page *mappage; | ||
| 432 | struct swap_cgroup *sc; | 433 | struct swap_cgroup *sc; |
| 433 | unsigned short old; | 434 | unsigned short old; |
| 434 | unsigned long flags; | 435 | unsigned long flags; |
| 435 | 436 | ||
| 436 | ctrl = &swap_cgroup_ctrl[type]; | 437 | sc = lookup_swap_cgroup(ent, &ctrl); |
| 437 | 438 | ||
| 438 | mappage = ctrl->map[idx]; | ||
| 439 | sc = page_address(mappage); | ||
| 440 | sc += pos; | ||
| 441 | spin_lock_irqsave(&ctrl->lock, flags); | 439 | spin_lock_irqsave(&ctrl->lock, flags); |
| 442 | old = sc->id; | 440 | old = sc->id; |
| 443 | sc->id = id; | 441 | sc->id = id; |
| @@ -447,28 +445,14 @@ unsigned short swap_cgroup_record(swp_entry_t ent, unsigned short id) | |||
| 447 | } | 445 | } |
| 448 | 446 | ||
| 449 | /** | 447 | /** |
| 450 | * lookup_swap_cgroup - lookup mem_cgroup tied to swap entry | 448 | * lookup_swap_cgroup_id - lookup mem_cgroup id tied to swap entry |
| 451 | * @ent: swap entry to be looked up. | 449 | * @ent: swap entry to be looked up. |
| 452 | * | 450 | * |
| 453 | * Returns CSS ID of mem_cgroup at success. 0 at failure. (0 is invalid ID) | 451 | * Returns CSS ID of mem_cgroup at success. 0 at failure. (0 is invalid ID) |
| 454 | */ | 452 | */ |
| 455 | unsigned short lookup_swap_cgroup(swp_entry_t ent) | 453 | unsigned short lookup_swap_cgroup_id(swp_entry_t ent) |
| 456 | { | 454 | { |
| 457 | int type = swp_type(ent); | 455 | return lookup_swap_cgroup(ent, NULL)->id; |
| 458 | unsigned long offset = swp_offset(ent); | ||
| 459 | unsigned long idx = offset / SC_PER_PAGE; | ||
| 460 | unsigned long pos = offset & SC_POS_MASK; | ||
| 461 | struct swap_cgroup_ctrl *ctrl; | ||
| 462 | struct page *mappage; | ||
| 463 | struct swap_cgroup *sc; | ||
| 464 | unsigned short ret; | ||
| 465 | |||
| 466 | ctrl = &swap_cgroup_ctrl[type]; | ||
| 467 | mappage = ctrl->map[idx]; | ||
| 468 | sc = page_address(mappage); | ||
| 469 | sc += pos; | ||
| 470 | ret = sc->id; | ||
| 471 | return ret; | ||
| 472 | } | 456 | } |
| 473 | 457 | ||
| 474 | int swap_cgroup_swapon(int type, unsigned long max_pages) | 458 | int swap_cgroup_swapon(int type, unsigned long max_pages) |
