diff options
| author | Ingo Molnar <mingo@elte.hu> | 2008-10-06 02:13:18 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2008-10-06 02:13:18 -0400 |
| commit | 2c10c22af088ab5d94fae93ce3fe6436b2a208b4 (patch) | |
| tree | db27721001f194327ddbdcd6c983c4ec68b77c00 /mm | |
| parent | f6121f4f8708195e88cbdf8dd8d171b226b3f858 (diff) | |
| parent | fec6ed1d1f9b78a6acb4a3eb2c46c812ac2e96f0 (diff) | |
Merge branch 'linus' into sched/devel
Diffstat (limited to 'mm')
| -rw-r--r-- | mm/memcontrol.c | 18 | ||||
| -rw-r--r-- | mm/page_alloc.c | 13 | ||||
| -rw-r--r-- | mm/page_isolation.c | 12 | ||||
| -rw-r--r-- | mm/tiny-shmem.c | 26 |
4 files changed, 47 insertions, 22 deletions
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 0f1f7a7374ba..36896f3eb7f5 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
| @@ -250,6 +250,14 @@ static struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont) | |||
| 250 | 250 | ||
| 251 | struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p) | 251 | struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p) |
| 252 | { | 252 | { |
| 253 | /* | ||
| 254 | * mm_update_next_owner() may clear mm->owner to NULL | ||
| 255 | * if it races with swapoff, page migration, etc. | ||
| 256 | * So this can be called with p == NULL. | ||
| 257 | */ | ||
| 258 | if (unlikely(!p)) | ||
| 259 | return NULL; | ||
| 260 | |||
| 253 | return container_of(task_subsys_state(p, mem_cgroup_subsys_id), | 261 | return container_of(task_subsys_state(p, mem_cgroup_subsys_id), |
| 254 | struct mem_cgroup, css); | 262 | struct mem_cgroup, css); |
| 255 | } | 263 | } |
| @@ -549,6 +557,11 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm, | |||
| 549 | if (likely(!memcg)) { | 557 | if (likely(!memcg)) { |
| 550 | rcu_read_lock(); | 558 | rcu_read_lock(); |
| 551 | mem = mem_cgroup_from_task(rcu_dereference(mm->owner)); | 559 | mem = mem_cgroup_from_task(rcu_dereference(mm->owner)); |
| 560 | if (unlikely(!mem)) { | ||
| 561 | rcu_read_unlock(); | ||
| 562 | kmem_cache_free(page_cgroup_cache, pc); | ||
| 563 | return 0; | ||
| 564 | } | ||
| 552 | /* | 565 | /* |
| 553 | * For every charge from the cgroup, increment reference count | 566 | * For every charge from the cgroup, increment reference count |
| 554 | */ | 567 | */ |
| @@ -801,11 +814,16 @@ int mem_cgroup_shrink_usage(struct mm_struct *mm, gfp_t gfp_mask) | |||
| 801 | 814 | ||
| 802 | rcu_read_lock(); | 815 | rcu_read_lock(); |
| 803 | mem = mem_cgroup_from_task(rcu_dereference(mm->owner)); | 816 | mem = mem_cgroup_from_task(rcu_dereference(mm->owner)); |
| 817 | if (unlikely(!mem)) { | ||
| 818 | rcu_read_unlock(); | ||
| 819 | return 0; | ||
| 820 | } | ||
| 804 | css_get(&mem->css); | 821 | css_get(&mem->css); |
| 805 | rcu_read_unlock(); | 822 | rcu_read_unlock(); |
| 806 | 823 | ||
| 807 | do { | 824 | do { |
| 808 | progress = try_to_free_mem_cgroup_pages(mem, gfp_mask); | 825 | progress = try_to_free_mem_cgroup_pages(mem, gfp_mask); |
| 826 | progress += res_counter_check_under_limit(&mem->res); | ||
| 809 | } while (!progress && --retry); | 827 | } while (!progress && --retry); |
| 810 | 828 | ||
| 811 | css_put(&mem->css); | 829 | css_put(&mem->css); |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e293c58bea58..27b8681139fd 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -268,13 +268,14 @@ void prep_compound_page(struct page *page, unsigned long order) | |||
| 268 | { | 268 | { |
| 269 | int i; | 269 | int i; |
| 270 | int nr_pages = 1 << order; | 270 | int nr_pages = 1 << order; |
| 271 | struct page *p = page + 1; | ||
| 271 | 272 | ||
| 272 | set_compound_page_dtor(page, free_compound_page); | 273 | set_compound_page_dtor(page, free_compound_page); |
| 273 | set_compound_order(page, order); | 274 | set_compound_order(page, order); |
| 274 | __SetPageHead(page); | 275 | __SetPageHead(page); |
| 275 | for (i = 1; i < nr_pages; i++) { | 276 | for (i = 1; i < nr_pages; i++, p++) { |
| 276 | struct page *p = page + i; | 277 | if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0)) |
| 277 | 278 | p = pfn_to_page(page_to_pfn(page) + i); | |
| 278 | __SetPageTail(p); | 279 | __SetPageTail(p); |
| 279 | p->first_page = page; | 280 | p->first_page = page; |
| 280 | } | 281 | } |
| @@ -284,6 +285,7 @@ static void destroy_compound_page(struct page *page, unsigned long order) | |||
| 284 | { | 285 | { |
| 285 | int i; | 286 | int i; |
| 286 | int nr_pages = 1 << order; | 287 | int nr_pages = 1 << order; |
| 288 | struct page *p = page + 1; | ||
| 287 | 289 | ||
| 288 | if (unlikely(compound_order(page) != order)) | 290 | if (unlikely(compound_order(page) != order)) |
| 289 | bad_page(page); | 291 | bad_page(page); |
| @@ -291,8 +293,9 @@ static void destroy_compound_page(struct page *page, unsigned long order) | |||
| 291 | if (unlikely(!PageHead(page))) | 293 | if (unlikely(!PageHead(page))) |
| 292 | bad_page(page); | 294 | bad_page(page); |
| 293 | __ClearPageHead(page); | 295 | __ClearPageHead(page); |
| 294 | for (i = 1; i < nr_pages; i++) { | 296 | for (i = 1; i < nr_pages; i++, p++) { |
| 295 | struct page *p = page + i; | 297 | if (unlikely((i & (MAX_ORDER_NR_PAGES - 1)) == 0)) |
| 298 | p = pfn_to_page(page_to_pfn(page) + i); | ||
| 296 | 299 | ||
| 297 | if (unlikely(!PageTail(p) | | 300 | if (unlikely(!PageTail(p) | |
| 298 | (p->first_page != page))) | 301 | (p->first_page != page))) |
diff --git a/mm/page_isolation.c b/mm/page_isolation.c index c69f84fe038d..b70a7fec1ff6 100644 --- a/mm/page_isolation.c +++ b/mm/page_isolation.c | |||
| @@ -114,8 +114,10 @@ __test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn) | |||
| 114 | 114 | ||
| 115 | int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn) | 115 | int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn) |
| 116 | { | 116 | { |
| 117 | unsigned long pfn; | 117 | unsigned long pfn, flags; |
| 118 | struct page *page; | 118 | struct page *page; |
| 119 | struct zone *zone; | ||
| 120 | int ret; | ||
| 119 | 121 | ||
| 120 | pfn = start_pfn; | 122 | pfn = start_pfn; |
| 121 | /* | 123 | /* |
| @@ -131,7 +133,9 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn) | |||
| 131 | if (pfn < end_pfn) | 133 | if (pfn < end_pfn) |
| 132 | return -EBUSY; | 134 | return -EBUSY; |
| 133 | /* Check all pages are free or Marked as ISOLATED */ | 135 | /* Check all pages are free or Marked as ISOLATED */ |
| 134 | if (__test_page_isolated_in_pageblock(start_pfn, end_pfn)) | 136 | zone = page_zone(pfn_to_page(pfn)); |
| 135 | return 0; | 137 | spin_lock_irqsave(&zone->lock, flags); |
| 136 | return -EBUSY; | 138 | ret = __test_page_isolated_in_pageblock(start_pfn, end_pfn); |
| 139 | spin_unlock_irqrestore(&zone->lock, flags); | ||
| 140 | return ret ? 0 : -EBUSY; | ||
| 137 | } | 141 | } |
diff --git a/mm/tiny-shmem.c b/mm/tiny-shmem.c index ae532f501943..8d7a27a6335c 100644 --- a/mm/tiny-shmem.c +++ b/mm/tiny-shmem.c | |||
| @@ -65,31 +65,31 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) | |||
| 65 | if (!dentry) | 65 | if (!dentry) |
| 66 | goto put_memory; | 66 | goto put_memory; |
| 67 | 67 | ||
| 68 | error = -ENFILE; | ||
| 69 | file = get_empty_filp(); | ||
| 70 | if (!file) | ||
| 71 | goto put_dentry; | ||
| 72 | |||
| 68 | error = -ENOSPC; | 73 | error = -ENOSPC; |
| 69 | inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0); | 74 | inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0); |
| 70 | if (!inode) | 75 | if (!inode) |
| 71 | goto put_dentry; | 76 | goto close_file; |
| 72 | 77 | ||
| 73 | d_instantiate(dentry, inode); | 78 | d_instantiate(dentry, inode); |
| 74 | error = -ENFILE; | 79 | inode->i_size = size; |
| 75 | file = alloc_file(shm_mnt, dentry, FMODE_WRITE | FMODE_READ, | ||
| 76 | &ramfs_file_operations); | ||
| 77 | if (!file) | ||
| 78 | goto put_dentry; | ||
| 79 | |||
| 80 | inode->i_nlink = 0; /* It is unlinked */ | 80 | inode->i_nlink = 0; /* It is unlinked */ |
| 81 | init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ, | ||
| 82 | &ramfs_file_operations); | ||
| 81 | 83 | ||
| 82 | /* notify everyone as to the change of file size */ | 84 | #ifndef CONFIG_MMU |
| 83 | error = do_truncate(dentry, size, 0, file); | 85 | error = ramfs_nommu_expand_for_mapping(inode, size); |
| 84 | if (error < 0) | 86 | if (error) |
| 85 | goto close_file; | 87 | goto close_file; |
| 86 | 88 | #endif | |
| 87 | return file; | 89 | return file; |
| 88 | 90 | ||
| 89 | close_file: | 91 | close_file: |
| 90 | put_filp(file); | 92 | put_filp(file); |
| 91 | return ERR_PTR(error); | ||
| 92 | |||
| 93 | put_dentry: | 93 | put_dentry: |
| 94 | dput(dentry); | 94 | dput(dentry); |
| 95 | put_memory: | 95 | put_memory: |
