Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc

Pull sparc fixes from David Miller:
"A couple small fixes for sparc including some THP brown-paper-bag
material:

1) During the merging of all the THP support for various
architectures, sparc missed adding a
HAVE_ARCH_TRANSPARENT_HUGEPAGE to it's Kconfig, oops.

2) Sparc needs to be mindful of hugepages in get_user_pages_fast().

3) Fix memory leak in SBUS probe, from Cong Ding.

4) The sunvdc virtual disk client driver has a test of the bitmask of
vdisk server supported operations which was off by one bit"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
sunvdc: Fix off-by-one in generic_request().
sparc64: Fix get_user_pages_fast() wrt. THP.
sparc64: Add missing HAVE_ARCH_TRANSPARENT_HUGEPAGE.
sparc: kernel/sbus.c: fix memory leakage

+68 -14
+1
arch/sparc/Kconfig
··· 61 61 select HAVE_MEMBLOCK 62 62 select HAVE_MEMBLOCK_NODE_MAP 63 63 select HAVE_SYSCALL_WRAPPERS 64 + select HAVE_ARCH_TRANSPARENT_HUGEPAGE 64 65 select HAVE_DYNAMIC_FTRACE 65 66 select HAVE_FTRACE_MCOUNT_RECORD 66 67 select HAVE_SYSCALL_TRACEPOINTS
+6 -8
arch/sparc/include/asm/pgtable_64.h
··· 71 71 #define PMD_PADDR _AC(0xfffffffe,UL) 72 72 #define PMD_PADDR_SHIFT _AC(11,UL) 73 73 74 - #ifdef CONFIG_TRANSPARENT_HUGEPAGE 75 74 #define PMD_ISHUGE _AC(0x00000001,UL) 76 75 77 76 /* This is the PMD layout when PMD_ISHUGE is set. With 4MB huge ··· 85 86 #define PMD_HUGE_ACCESSED _AC(0x00000080,UL) 86 87 #define PMD_HUGE_EXEC _AC(0x00000040,UL) 87 88 #define PMD_HUGE_SPLITTING _AC(0x00000020,UL) 88 - #endif 89 89 90 90 /* PGDs point to PMD tables which are 8K aligned. */ 91 91 #define PGD_PADDR _AC(0xfffffffc,UL) ··· 626 628 return pte_val(pte) & _PAGE_SPECIAL; 627 629 } 628 630 631 + static inline int pmd_large(pmd_t pmd) 632 + { 633 + return (pmd_val(pmd) & (PMD_ISHUGE | PMD_HUGE_PRESENT)) == 634 + (PMD_ISHUGE | PMD_HUGE_PRESENT); 635 + } 636 + 629 637 #ifdef CONFIG_TRANSPARENT_HUGEPAGE 630 638 static inline int pmd_young(pmd_t pmd) 631 639 { ··· 648 644 unsigned long val = pmd_val(pmd) & PMD_HUGE_PADDR; 649 645 650 646 return val >> (PAGE_SHIFT - PMD_PADDR_SHIFT); 651 - } 652 - 653 - static inline int pmd_large(pmd_t pmd) 654 - { 655 - return (pmd_val(pmd) & (PMD_ISHUGE | PMD_HUGE_PRESENT)) == 656 - (PMD_ISHUGE | PMD_HUGE_PRESENT); 657 647 } 658 648 659 649 static inline int pmd_trans_splitting(pmd_t pmd)
+3 -3
arch/sparc/kernel/sbus.c
··· 554 554 regs = pr->phys_addr; 555 555 556 556 iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC); 557 - if (!iommu) 558 - goto fatal_memory_error; 559 557 strbuf = kzalloc(sizeof(*strbuf), GFP_ATOMIC); 560 - if (!strbuf) 558 + if (!iommu || !strbuf) 561 559 goto fatal_memory_error; 562 560 563 561 op->dev.archdata.iommu = iommu; ··· 654 656 return; 655 657 656 658 fatal_memory_error: 659 + kfree(iommu); 660 + kfree(strbuf); 657 661 prom_printf("sbus_iommu_init: Fatal memory allocation error.\n"); 658 662 } 659 663
+57 -2
arch/sparc/mm/gup.c
··· 66 66 return 1; 67 67 } 68 68 69 + static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, 70 + unsigned long end, int write, struct page **pages, 71 + int *nr) 72 + { 73 + struct page *head, *page, *tail; 74 + u32 mask; 75 + int refs; 76 + 77 + mask = PMD_HUGE_PRESENT; 78 + if (write) 79 + mask |= PMD_HUGE_WRITE; 80 + if ((pmd_val(pmd) & mask) != mask) 81 + return 0; 82 + 83 + refs = 0; 84 + head = pmd_page(pmd); 85 + page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT); 86 + tail = page; 87 + do { 88 + VM_BUG_ON(compound_head(page) != head); 89 + pages[*nr] = page; 90 + (*nr)++; 91 + page++; 92 + refs++; 93 + } while (addr += PAGE_SIZE, addr != end); 94 + 95 + if (!page_cache_add_speculative(head, refs)) { 96 + *nr -= refs; 97 + return 0; 98 + } 99 + 100 + if (unlikely(pmd_val(pmd) != pmd_val(*pmdp))) { 101 + *nr -= refs; 102 + while (refs--) 103 + put_page(head); 104 + return 0; 105 + } 106 + 107 + /* Any tail page need their mapcount reference taken before we 108 + * return. 109 + */ 110 + while (refs--) { 111 + if (PageTail(tail)) 112 + get_huge_page_tail(tail); 113 + tail++; 114 + } 115 + 116 + return 1; 117 + } 118 + 69 119 static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end, 70 120 int write, struct page **pages, int *nr) 71 121 { ··· 127 77 pmd_t pmd = *pmdp; 128 78 129 79 next = pmd_addr_end(addr, end); 130 - if (pmd_none(pmd)) 80 + if (pmd_none(pmd) || pmd_trans_splitting(pmd)) 131 81 return 0; 132 - if (!gup_pte_range(pmd, addr, next, write, pages, nr)) 82 + if (unlikely(pmd_large(pmd))) { 83 + if (!gup_huge_pmd(pmdp, pmd, addr, next, 84 + write, pages, nr)) 85 + return 0; 86 + } else if (!gup_pte_range(pmd, addr, next, write, 87 + pages, nr)) 133 88 return 0; 134 89 } while (pmdp++, addr = next, addr != end); 135 90
+1 -1
drivers/block/sunvdc.c
··· 461 461 int op_len, err; 462 462 void *req_buf; 463 463 464 - if (!(((u64)1 << ((u64)op - 1)) & port->operations)) 464 + if (!(((u64)1 << (u64)op) & port->operations)) 465 465 return -EOPNOTSUPP; 466 466 467 467 switch (op) {