diff options
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/mm/gup.c | 12 | ||||
-rw-r--r-- | arch/powerpc/mm/hugetlbpage.c | 21 | ||||
-rw-r--r-- | arch/powerpc/sysdev/fsl_rio.c | 1 |
3 files changed, 17 insertions, 17 deletions
diff --git a/arch/powerpc/mm/gup.c b/arch/powerpc/mm/gup.c index fec13200868f..d7efdbf640c7 100644 --- a/arch/powerpc/mm/gup.c +++ b/arch/powerpc/mm/gup.c | |||
@@ -16,16 +16,6 @@ | |||
16 | 16 | ||
17 | #ifdef __HAVE_ARCH_PTE_SPECIAL | 17 | #ifdef __HAVE_ARCH_PTE_SPECIAL |
18 | 18 | ||
19 | static inline void get_huge_page_tail(struct page *page) | ||
20 | { | ||
21 | /* | ||
22 | * __split_huge_page_refcount() cannot run | ||
23 | * from under us. | ||
24 | */ | ||
25 | VM_BUG_ON(atomic_read(&page->_count) < 0); | ||
26 | atomic_inc(&page->_count); | ||
27 | } | ||
28 | |||
29 | /* | 19 | /* |
30 | * The performance critical leaf functions are made noinline otherwise gcc | 20 | * The performance critical leaf functions are made noinline otherwise gcc |
31 | * inlines everything into a single function which results in too much | 21 | * inlines everything into a single function which results in too much |
@@ -57,8 +47,6 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr, | |||
57 | put_page(page); | 47 | put_page(page); |
58 | return 0; | 48 | return 0; |
59 | } | 49 | } |
60 | if (PageTail(page)) | ||
61 | get_huge_page_tail(page); | ||
62 | pages[*nr] = page; | 50 | pages[*nr] = page; |
63 | (*nr)++; | 51 | (*nr)++; |
64 | 52 | ||
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 0b9a5c1901b9..da5eb3885702 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c | |||
@@ -390,7 +390,7 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add | |||
390 | { | 390 | { |
391 | unsigned long mask; | 391 | unsigned long mask; |
392 | unsigned long pte_end; | 392 | unsigned long pte_end; |
393 | struct page *head, *page; | 393 | struct page *head, *page, *tail; |
394 | pte_t pte; | 394 | pte_t pte; |
395 | int refs; | 395 | int refs; |
396 | 396 | ||
@@ -413,6 +413,7 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add | |||
413 | head = pte_page(pte); | 413 | head = pte_page(pte); |
414 | 414 | ||
415 | page = head + ((addr & (sz-1)) >> PAGE_SHIFT); | 415 | page = head + ((addr & (sz-1)) >> PAGE_SHIFT); |
416 | tail = page; | ||
416 | do { | 417 | do { |
417 | VM_BUG_ON(compound_head(page) != head); | 418 | VM_BUG_ON(compound_head(page) != head); |
418 | pages[*nr] = page; | 419 | pages[*nr] = page; |
@@ -428,10 +429,20 @@ static noinline int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long add | |||
428 | 429 | ||
429 | if (unlikely(pte_val(pte) != pte_val(*ptep))) { | 430 | if (unlikely(pte_val(pte) != pte_val(*ptep))) { |
430 | /* Could be optimized better */ | 431 | /* Could be optimized better */ |
431 | while (*nr) { | 432 | *nr -= refs; |
432 | put_page(page); | 433 | while (refs--) |
433 | (*nr)--; | 434 | put_page(head); |
434 | } | 435 | return 0; |
436 | } | ||
437 | |||
438 | /* | ||
439 | * Any tail page need their mapcount reference taken before we | ||
440 | * return. | ||
441 | */ | ||
442 | while (refs--) { | ||
443 | if (PageTail(tail)) | ||
444 | get_huge_page_tail(tail); | ||
445 | tail++; | ||
435 | } | 446 | } |
436 | 447 | ||
437 | return 1; | 448 | return 1; |
diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index c65f75aa7ff7..22ffccd8bef5 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c | |||
@@ -1608,6 +1608,7 @@ int fsl_rio_setup(struct platform_device *dev) | |||
1608 | return 0; | 1608 | return 0; |
1609 | err: | 1609 | err: |
1610 | iounmap(priv->regs_win); | 1610 | iounmap(priv->regs_win); |
1611 | release_resource(&port->iores); | ||
1611 | err_res: | 1612 | err_res: |
1612 | kfree(priv); | 1613 | kfree(priv); |
1613 | err_priv: | 1614 | err_priv: |