From: Weilong Chen chenweilong@huawei.com
ascend inclusion category: feature bugzilla: NA CVE: NA
-------------------------------------------------
Sharepool applies for a dedicated interface for large pages, which optimizes the efficiency of memory application
Reviewed-by: Ding Tianhong dingtianhong@huawei.com Signed-off-by: Weilong Chen chenweilong@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- include/linux/hugetlb.h | 4 ++ include/linux/share_pool.h | 5 +++ mm/hugetlb.c | 22 +++++++--- mm/share_pool.c | 90 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 6 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index bd658f44e133..be649e5ba322 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -645,4 +645,8 @@ static inline spinlock_t *huge_pte_lock(struct hstate *h, return ptl; }
+#ifdef CONFIG_ASCEND_SHARE_POOL +pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page, int writable); +#endif + #endif /* _LINUX_HUGETLB_H */ diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h index 2557ef138122..47d8579c23ec 100644 --- a/include/linux/share_pool.h +++ b/include/linux/share_pool.h @@ -220,6 +220,11 @@ static inline void sp_dump_stack(void) dump_stack(); }
+vm_fault_t sharepool_no_page(struct mm_struct *mm, + struct vm_area_struct *vma, + struct address_space *mapping, pgoff_t idx, + unsigned long address, pte_t *ptep, unsigned int flags); + #else
static inline int sp_group_add_task(int pid, int spg_id) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 9d2035632aed..a68e7e1afd82 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -3352,8 +3352,13 @@ const struct vm_operations_struct hugetlb_vm_ops = { .pagesize = hugetlb_vm_op_pagesize, };
+#ifdef CONFIG_ASCEND_SHARE_POOL +pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page, + int writable) +#else static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page, int writable) +#endif { pte_t entry;
@@ -3370,6 +3375,9 @@ static pte_t make_huge_pte(struct vm_area_struct *vma, struct page *page,
return entry; } +#ifdef CONFIG_ASCEND_SHARE_POOL +EXPORT_SYMBOL(make_huge_pte); +#endif
static void set_huge_ptep_writable(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) @@ -3962,12 +3970,6 @@ static vm_fault_t hugetlb_no_page(struct mm_struct *mm, }
page = alloc_huge_page(vma, haddr, 0); - if (IS_ERR(page) && sp_check_vm_share_pool(vma->vm_flags)) { - page = alloc_huge_page_node(hstate_file(vma->vm_file), - numa_mem_id()); - if (!page) - page = ERR_PTR(-ENOMEM); - } if (IS_ERR(page)) { /* * Returning error will result in faulting task being @@ -4155,7 +4157,15 @@ vm_fault_t hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma,
entry = huge_ptep_get(ptep); if (huge_pte_none(entry)) { +#ifdef CONFIG_ASCEND_SHARE_POOL + if (sp_check_vm_share_pool(vma->vm_flags)) { + ret = sharepool_no_page(mm, vma, mapping, idx, address, ptep, flags); + } else { + ret = hugetlb_no_page(mm, vma, mapping, idx, address, ptep, flags); + } +#else ret = hugetlb_no_page(mm, vma, mapping, idx, address, ptep, flags); +#endif goto out_mutex; }
diff --git a/mm/share_pool.c b/mm/share_pool.c index 23195a76c2c6..286e74f99360 100644 --- a/mm/share_pool.c +++ b/mm/share_pool.c @@ -41,6 +41,8 @@ #include <linux/idr.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/rmap.h> +#include <linux/hugetlb.h>
/* access control mode macros */ #define AC_NONE 0 @@ -2399,6 +2401,94 @@ static int spa_stat_show(struct seq_file *seq, void *offset) return 0; }
+vm_fault_t sharepool_no_page(struct mm_struct *mm, + struct vm_area_struct *vma, + struct address_space *mapping, pgoff_t idx, + unsigned long address, pte_t *ptep, unsigned int flags) +{ + struct hstate *h = hstate_vma(vma); + vm_fault_t ret = VM_FAULT_SIGBUS; + unsigned long size; + struct page *page; + pte_t new_pte; + spinlock_t *ptl; + unsigned long haddr = address & huge_page_mask(h); + bool new_page = false; + int err; + +retry: + page = find_lock_page(mapping, idx); + if (!page) { + size = i_size_read(mapping->host) >> huge_page_shift(h); + if (idx >= size) + goto out; + + page = alloc_huge_page(vma, haddr, 0); + if (IS_ERR(page)) { + page = alloc_huge_page_node(hstate_file(vma->vm_file), + numa_mem_id()); + if (!page) + page = ERR_PTR(-ENOMEM); + } + if (IS_ERR(page)) { + ptl = huge_pte_lock(h, mm, ptep); + if (!huge_pte_none(huge_ptep_get(ptep))) { + ret = 0; + spin_unlock(ptl); + goto out; + } + spin_unlock(ptl); + ret = vmf_error(PTR_ERR(page)); + goto out; + } + __SetPageUptodate(page); + new_page = true; + + /* sharepool pages are all shared */ + err = huge_add_to_page_cache(page, mapping, idx); + if (err) { + put_page(page); + if (err == -EEXIST) + goto retry; + goto out; + } + } + + + ptl = huge_pte_lock(h, mm, ptep); + size = i_size_read(mapping->host) >> huge_page_shift(h); + if (idx >= size) + goto backout; + + ret = 0; + if (!huge_pte_none(huge_ptep_get(ptep))) + goto backout; + + page_dup_rmap(page, true); + new_pte = make_huge_pte(vma, page, ((vma->vm_flags & VM_WRITE) + && (vma->vm_flags & VM_SHARED))); + set_huge_pte_at(mm, haddr, ptep, new_pte); + + hugetlb_count_add(pages_per_huge_page(h), mm); + + spin_unlock(ptl); + + if (new_page) { + SetPagePrivate(&page[1]); + } + + unlock_page(page); +out: + return ret; + +backout: + spin_unlock(ptl); + unlock_page(page); + put_page(page); + goto out; +} +EXPORT_SYMBOL(sharepool_no_page); + /* * Called by proc_root_init() to initialize the /proc/sharepool subtree */
From: Weilong Chen chenweilong@huawei.com
ascend inclusion category: feature bugzilla: NA CVE: NA
-------------------------------------------------
Add a flag VM_SHAREPOOL to avoid vfree() a shared kva.
Reviewed-by: Ding Tianhong dingtianhong@huawei.com Signed-off-by: Weilong Chen chenweilong@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- include/linux/hugetlb.h | 3 +++ include/linux/share_pool.h | 2 -- include/linux/vmalloc.h | 4 +++ mm/hugetlb.c | 7 +++++ mm/memory.c | 3 ++- mm/share_pool.c | 53 +++++++++++++++++++++++++++++++++----- mm/vmalloc.c | 8 ++++++ 7 files changed, 71 insertions(+), 9 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index be649e5ba322..debd4603991e 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -384,6 +384,9 @@ struct page *hugetlb_alloc_hugepage(int nid); int hugetlb_insert_hugepage_pte(struct mm_struct *mm, unsigned long addr, pgprot_t prot, struct page *hpage); #endif +int hugetlb_insert_hugepage_pte_by_pa(struct mm_struct *mm, + unsigned long vir_addr, + pgprot_t prot, unsigned long phy_addr); int hugetlb_insert_hugepage(struct vm_area_struct *vma, unsigned long addr, struct page *hpage, pgprot_t prot);
diff --git a/include/linux/share_pool.h b/include/linux/share_pool.h index 47d8579c23ec..933b77be8ff8 100644 --- a/include/linux/share_pool.h +++ b/include/linux/share_pool.h @@ -24,8 +24,6 @@
#define MAX_DEVID 1 /* the max num of Da-vinci devices */
-#define VM_HUGE_PAGES 0x00001000 /* use for huge pages */ - /* to align the pointer to the (next) PMD boundary */ #define PMD_ALIGN(addr) ALIGN(addr, PMD_SIZE)
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 244eedb7591a..6383d6989c0f 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -23,6 +23,10 @@ struct notifier_block; /* in notifier.h */ #define VM_UNINITIALIZED 0x00000020 /* vm_struct is not fully initialized */ #define VM_NO_GUARD 0x00000040 /* don't add guard page */ #define VM_KASAN 0x00000080 /* has allocated kasan shadow memory */ +#ifdef CONFIG_ASCEND_SHARE_POOL +#define VM_HUGE_PAGES 0x00001000 /* use for huge pages */ +#define VM_SHAREPOOL 0x00002000 /* remapped to sharepool */ +#endif /* bits [20..32] reserved for arch specific ioremap internals */
/* diff --git a/mm/hugetlb.c b/mm/hugetlb.c index a68e7e1afd82..4cc8e041299a 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -3598,6 +3598,13 @@ void __unmap_hugepage_range(struct mmu_gather *tlb, struct vm_area_struct *vma,
pte = huge_ptep_get_and_clear(mm, address, ptep); tlb_remove_huge_tlb_entry(h, tlb, ptep, address); + + /* sharepool k2u mapped pages are marked special */ + if (sp_check_vm_share_pool(vma->vm_flags) && pte_special(pte)) { + spin_unlock(ptl); + continue; + } + if (huge_pte_dirty(pte)) set_page_dirty(page);
diff --git a/mm/memory.c b/mm/memory.c index e369f3961ad2..b69f8bd23ca6 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1532,7 +1532,8 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, }
if (sp_check_hugepage(page)) - return hugetlb_insert_hugepage(vma, addr, page, vma->vm_page_prot); + return hugetlb_insert_hugepage_pte_by_pa(vma->vm_mm, addr, + vma->vm_page_prot, page_to_phys(page)); else return insert_page(vma, addr, page, vma->vm_page_prot); } diff --git a/mm/share_pool.c b/mm/share_pool.c index 286e74f99360..d39c2c3d728c 100644 --- a/mm/share_pool.c +++ b/mm/share_pool.c @@ -178,6 +178,7 @@ struct sp_area { struct sp_group *spg; enum spa_type type; /* where spa born from */ struct mm_struct *mm; /* owner of k2u(task) */ + unsigned long kva; /* shared kva */ }; static DEFINE_SPINLOCK(sp_area_lock); static struct rb_root sp_area_root = RB_ROOT; @@ -1393,6 +1394,17 @@ static int is_vmap_hugepage(unsigned long addr) return 0; }
+static unsigned long __sp_remap_get_pfn(unsigned long kva) +{ + unsigned long pfn; + if (is_vmalloc_addr((void *)kva)) + pfn = vmalloc_to_pfn((void *)kva); + else + pfn = virt_to_pfn(kva); + + return pfn; +} + static unsigned long sp_remap_kva_to_vma(unsigned long kva, struct sp_area *spa, struct mm_struct *mm) { @@ -1403,6 +1415,7 @@ static unsigned long sp_remap_kva_to_vma(unsigned long kva, struct sp_area *spa, int ret = 0; struct user_struct *user = NULL; int hsize_log = MAP_HUGE_2MB >> MAP_HUGE_SHIFT; + unsigned long addr, buf, offset;
if (spa->is_hugepage) { file = hugetlb_file_setup(HUGETLB_ANON_FILE, spa_size(spa), VM_NORESERVE, @@ -1437,13 +1450,23 @@ static unsigned long sp_remap_kva_to_vma(unsigned long kva, struct sp_area *spa, ret_addr = ret; goto out; } + vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; } else { - ret = remap_vmalloc_range(vma, (void *)kva, 0); - if (ret) { - pr_err("share pool: remap vmalloc failed, ret %d\n", ret); - ret_addr = ret; - goto out; - } + buf = ret_addr; + addr = kva; + offset = 0; + do { + ret = remap_pfn_range(vma, buf, __sp_remap_get_pfn(addr), PAGE_SIZE, + __pgprot(vma->vm_page_prot.pgprot)); + if (ret) { + pr_err("share pool: remap_pfn_range failed, ret %d\n", ret); + ret_addr = ret; + goto out; + } + offset += PAGE_SIZE; + buf += PAGE_SIZE; + addr += PAGE_SIZE; + } while (offset < spa_size(spa)); }
out: @@ -1551,6 +1574,7 @@ void *sp_make_share_k2u(unsigned long kva, unsigned long size, unsigned int page_size = PAGE_SIZE; enum spa_type type; int ret; + struct vm_struct *area;
if (sp_flags & ~SP_DVPP) { if (printk_ratelimit()) @@ -1632,6 +1656,12 @@ void *sp_make_share_k2u(unsigned long kva, unsigned long size, type, current->comm, current->tgid, current->pid, spg_id, (void *)spa->va_start, spa->real_size); sp_dump_stack(); + + /* associate vma and spa */ + area = find_vm_area((void *)kva); + if (area) + area->flags |= VM_SHAREPOOL; + spa->kva = kva; }
return uva; @@ -1901,6 +1931,7 @@ static int sp_unshare_uva(unsigned long uva, unsigned long size, int pid, int sp unsigned long uva_aligned; unsigned long size_aligned; unsigned int page_size; + struct vm_struct *area;
mutex_lock(&sp_mutex); /* @@ -2031,6 +2062,10 @@ static int sp_unshare_uva(unsigned long uva, unsigned long size, int pid, int sp }
out_drop_area: + /* deassociate vma and spa */ + area = find_vm_area((void *)spa->kva); + if (area) + area->flags &= ~VM_SHAREPOOL; __sp_area_drop(spa); out_unlock: mutex_unlock(&sp_mutex); @@ -2045,6 +2080,7 @@ static int sp_unshare_kva(unsigned long kva, unsigned long size) unsigned long step; bool is_hugepage = true; int ret; + struct vm_struct *area;
ret = is_vmap_hugepage(kva); if (ret > 0) { @@ -2080,6 +2116,11 @@ static int sp_unshare_kva(unsigned long kva, unsigned long size) (void *)addr); }
+ /* deassociate vma and spa */ + area = find_vm_area((void *)kva_aligned); + if (area) + area->flags &= ~VM_SHAREPOOL; + vunmap((void *)kva_aligned);
return 0; diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 78f56e719e1d..aa2415741d13 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -2369,6 +2369,14 @@ static void __vunmap(const void *addr, int deallocate_pages) return; }
+#ifdef CONFIG_ASCEND_SHARE_POOL + /* unmap a sharepool vm area will cause meamleak! */ + if (area->flags & VM_SHAREPOOL) { + WARN(1, KERN_ERR "Memory leak due to vfree() sharepool vm area (%p) !\n", addr); + return; + } +#endif + debug_check_no_locks_freed(area->addr, get_vm_area_size(area)); debug_check_no_obj_freed(area->addr, get_vm_area_size(area));
From: Chenguangli chenguangli2@huawei.com
driver inclusion category: bugfix bugzilla: NA
-----------------------------------------------------------------------
This patch is used to solve the issue that the NPIV cannot be deleted.
Signed-off-by: Chenguangli chenguangli2@huawei.com Reviewed-by: Zengweiliang zengweiliang.zengweiliang@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/scsi/huawei/hifc/unf_common.h | 2 +- drivers/scsi/huawei/hifc/unf_npiv.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/huawei/hifc/unf_common.h b/drivers/scsi/huawei/hifc/unf_common.h index 7f5161676ebb..c338ef1c7e4e 100644 --- a/drivers/scsi/huawei/hifc/unf_common.h +++ b/drivers/scsi/huawei/hifc/unf_common.h @@ -13,7 +13,7 @@ /* B version, B0XX Corresponding x.x */ #define UNF_B_VERSION "5.0" /* Indicates the minor version number of the driver */ -#define UNF_DRIVER_VERSION "8" +#define UNF_DRIVER_VERSION "9" /* version num */ #define UNF_FC_VERSION UNF_MAJOR_VERSION "." UNF_B_VERSION "." UNF_DRIVER_VERSION extern unsigned int unf_dbg_level; diff --git a/drivers/scsi/huawei/hifc/unf_npiv.c b/drivers/scsi/huawei/hifc/unf_npiv.c index 1c3e3e99272e..be7772cb5b74 100644 --- a/drivers/scsi/huawei/hifc/unf_npiv.c +++ b/drivers/scsi/huawei/hifc/unf_npiv.c @@ -357,10 +357,16 @@ void unf_check_vport_pool_status(struct unf_lport_s *v_lport) void unf_vport_fabric_logo(struct unf_lport_s *v_vport) { struct unf_rport_s *rport = NULL; + unsigned long flag = 0;
rport = unf_get_rport_by_nport_id(v_vport, UNF_FC_FID_FLOGI); + UNF_CHECK_VALID(0x1970, UNF_TRUE, rport, return); - (void)unf_send_logo(v_vport, rport); + spin_lock_irqsave(&rport->rport_state_lock, flag); + unf_rport_state_ma(rport, UNF_EVENT_RPORT_LOGO); + spin_unlock_irqrestore(&rport->rport_state_lock, flag); + + unf_rport_enter_logo(v_vport, rport); }
void unf_vport_deinit(void *v_vport)
From: Fang Lijun fanglijun3@huawei.com
ascend inclusion category: bugfix bugzilla: NA CVE: NA
-------------------------------------------------
Dvpp use flags MAP_CHECKNODE to enable check node hugetlb. The global variable numanode will cause the mmap not be reenterable, so use the flags BITS[26:31] directly.
Fixes: cbdbfc7514ab ("mm: Check numa node hugepages enough when mmap hugetlb") Signed-off-by: Fang Lijun fanglijun3@huawei.com Reviewed-by: Ding Tianhong dingtianhong@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- fs/hugetlbfs/inode.c | 2 +- include/linux/mm.h | 2 ++ include/uapi/asm-generic/mman.h | 1 + mm/hugetlb.c | 2 +- mm/mmap.c | 28 ++++++++++++++++------------ 5 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 7a8994585b89..a878f009347c 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -211,7 +211,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma) inode_lock(inode); file_accessed(file);
- if (is_set_cdmmask()) { + if (is_set_cdmmask() && (vma->vm_flags & VM_CHECKNODE)) { ret = hugetlb_checknode(vma, len >> huge_page_shift(h)); if (ret < 0) goto out; diff --git a/include/linux/mm.h b/include/linux/mm.h index ef86e61e02eb..e2ae17c9a68f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -238,6 +238,8 @@ extern unsigned int kobjsize(const void *objp); #define VM_CDM 0x100000000 /* Contains coherent device memory */ #endif
+#define VM_CHECKNODE 0x200000000 + #ifdef CONFIG_ARCH_USES_HIGH_VMA_FLAGS #define VM_HIGH_ARCH_BIT_0 32 /* bit only usable on 64-bit architectures */ #define VM_HIGH_ARCH_BIT_1 33 /* bit only usable on 64-bit architectures */ diff --git a/include/uapi/asm-generic/mman.h b/include/uapi/asm-generic/mman.h index 1915bcc107eb..233a5e82407c 100644 --- a/include/uapi/asm-generic/mman.h +++ b/include/uapi/asm-generic/mman.h @@ -5,6 +5,7 @@ #include <asm-generic/mman-common.h>
#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ +#define MAP_CHECKNODE 0x0400 /* hugetlb numa node check */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ #define MAP_LOCKED 0x2000 /* pages are locked */ diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 4cc8e041299a..7afe926d7b58 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -971,7 +971,7 @@ static struct page *dequeue_huge_page_vma(struct hstate *h, if (page && !avoid_reserve && vma_has_reserves(vma, chg)) { SetPagePrivate(page); h->resv_huge_pages--; - if (is_set_cdmmask()) + if (is_set_cdmmask() && (vma->vm_flags & VM_CHECKNODE)) h->resv_huge_pages_node[vma->vm_flags >> CHECKNODE_BITS]--; }
diff --git a/mm/mmap.c b/mm/mmap.c index e1069c42ec8e..6fdd884eab90 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -70,7 +70,6 @@ const int mmap_rnd_compat_bits_max = CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX; int mmap_rnd_compat_bits __read_mostly = CONFIG_ARCH_MMAP_RND_COMPAT_BITS; #endif
-static unsigned long numanode; static bool ignore_rlimit_data; core_param(ignore_rlimit_data, ignore_rlimit_data, bool, 0644);
@@ -1579,8 +1578,9 @@ unsigned long __do_mmap(struct mm_struct *mm, struct file *file, /* set numa node id into vm_flags, * hugetlbfs file mmap will use it to check node */ - if (is_set_cdmmask()) - vm_flags |= ((numanode << CHECKNODE_BITS) & CHECKNODE_MASK); + if (is_set_cdmmask() && (flags & MAP_CHECKNODE)) + vm_flags |= VM_CHECKNODE | ((((flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK) + << CHECKNODE_BITS) & CHECKNODE_MASK);
addr = __mmap_region(mm, file, addr, len, vm_flags, pgoff, uf); if (!IS_ERR_VALUE(addr) && @@ -1608,12 +1608,6 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, struct file *file = NULL; unsigned long retval;
- /* get mmap numa node id */ - if (is_set_cdmmask()) { - numanode = (flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK; - flags &= ~(MAP_HUGE_MASK << MAP_HUGE_SHIFT); - } - if (!(flags & MAP_ANONYMOUS)) { audit_mmap_fd(fd, flags); file = fget(fd); @@ -1627,12 +1621,23 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, } else if (flags & MAP_HUGETLB) { struct user_struct *user = NULL; struct hstate *hs; + int page_size_log;
- hs = hstate_sizelog((flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK); + /* + * If config cdm node, flags bits [26:31] used for + * mmap hugetlb check node + */ + if (is_set_cdmmask()) + page_size_log = 0; + else + page_size_log = (flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK; + + hs = hstate_sizelog(page_size_log); if (!hs) return -EINVAL;
len = ALIGN(len, huge_page_size(hs)); + /* * VM_NORESERVE is used because the reservations will be * taken when vm_ops->mmap() is called @@ -1641,8 +1646,7 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, */ file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, VM_NORESERVE, - &user, HUGETLB_ANONHUGE_INODE, - (flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK); + &user, HUGETLB_ANONHUGE_INODE, page_size_log); if (IS_ERR(file)) return PTR_ERR(file); }
From: Xu Qiang xuqiang36@huawei.com
ascend inclusion category: feature bugzilla: NA CVE: NA
---------------------------------------
For Ascend platform,automatically opens enable_pseudo_nmi and pmu_nmi_enable.
Signed-off-by: Xu Qiang xuqiang36@huawei.com Reviewed-by: Ding Tianhong dingtianhong@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- arch/arm64/include/asm/cpufeature.h | 4 ++++ arch/arm64/kernel/cpufeature.c | 2 +- arch/arm64/mm/init.c | 12 +++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index e2637094ca6f..48f3da8996b0 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -84,6 +84,10 @@ extern struct arm64_ftr_reg arm64_ftr_reg_ctrel0;
int arm64_cpu_ftr_regs_traverse(int (*op)(u32, u64, void *), void *argp);
+#ifdef CONFIG_ARM64_PSEUDO_NMI +extern bool enable_pseudo_nmi; +#endif + /* * CPU capabilities: * diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 80d0e8bb0d10..c7b17e0e3e32 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1363,7 +1363,7 @@ static void cpu_enable_e0pd(struct arm64_cpu_capabilities const *cap) #endif /* CONFIG_ARM64_E0PD */
#ifdef CONFIG_ARM64_PSEUDO_NMI -static bool enable_pseudo_nmi; +bool enable_pseudo_nmi;
static int __init early_enable_pseudo_nmi(char *p) { diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index f23da539a476..a6b9048ea1a4 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -769,6 +769,9 @@ __setup("keepinitrd", keepinitrd_setup); #endif
#ifdef CONFIG_ASCEND_FEATURES + +#include <linux/perf/arm_pmu.h> + void ascend_enable_all_features(void) { if (IS_ENABLED(CONFIG_ASCEND_DVPP_MMAP)) @@ -782,6 +785,13 @@ void ascend_enable_all_features(void)
if (IS_ENABLED(CONFIG_SUSPEND)) mem_sleep_current = PM_SUSPEND_ON; + + if (IS_ENABLED(CONFIG_PMU_WATCHDOG)) + pmu_nmi_enable = true; + +#ifdef CONFIG_ARM64_PSEUDO_NMI + enable_pseudo_nmi = true; +#endif }
static int __init ascend_enable_setup(char *__unused) @@ -791,7 +801,7 @@ static int __init ascend_enable_setup(char *__unused) return 1; }
-__setup("ascend_enable_all", ascend_enable_setup); +early_param("ascend_enable_all", ascend_enable_setup); #endif
From: Chiqijun chiqijun@huawei.com
driver inclusion category: bugfix bugzilla: NA
-----------------------------------------------------------------------
When multiple VFs do FLR at the same time, the firmware is processed serially, resulting in some VF FLRs being delayed more than 100ms, when the virtual machine restarts and the device driver is loaded, the firmware is doing the corresponding VF FLR, causing the driver to fail to load.
To solve this problem, add host and firmware status synchronization during FLR.
Linux kernel patchwork: http://patchwork.ozlabs.org/project/linux-pci/patch/20201202113450.22 83-1-chiqijun@huawei.com/
Signed-off-by: Chiqijun chiqijun@huawei.com Reviewed-by: Zengweiliang zengweiliang.zengweiliang@huawei.com Reviewed-by: Hanjun Guo guohanjun@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/pci/quirks.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 049eb2793e55..8be46bc3d32f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3875,6 +3875,79 @@ static int delay_250ms_after_flr(struct pci_dev *dev, int probe) return 0; }
+#define PCI_DEVICE_ID_HINIC_VF 0x375E +#define HINIC_VF_FLR_TYPE 0x1000 +#define HINIC_VF_FLR_CAP_BIT_SHIFT 6 +#define HINIC_VF_OP 0xE80 +#define HINIC_VF_FLR_PROC_BIT_SHIFT 10 +#define HINIC_OPERATION_TIMEOUT 15000 + +/* Device-specific reset method for Huawei Intelligent NIC virtual functions */ +static int reset_hinic_vf_dev(struct pci_dev *pdev, int probe) +{ + unsigned long timeout; + void __iomem *bar; + u16 old_command; + u32 val; + + if (probe) + return 0; + + bar = pci_iomap(pdev, 0, 0); + if (!bar) + return -ENOTTY; + + pci_read_config_word(pdev, PCI_COMMAND, &old_command); + + /* + * FLR cap bit bit30, FLR processing bit: bit18, to avoid big-endian + * conversion the big-endian bit6, bit10 is directly operated here. + * + * Get and check firmware capabilities. + */ + val = readl(bar + HINIC_VF_FLR_TYPE); + if (!(val & (1UL << HINIC_VF_FLR_CAP_BIT_SHIFT))) { + pci_iounmap(pdev, bar); + return -ENOTTY; + } + + /* + * Set the processing bit for the start of FLR, which will be cleared + * by the firmware after FLR is completed. + */ + val = readl(bar + HINIC_VF_OP); + val = val | (1UL << HINIC_VF_FLR_PROC_BIT_SHIFT); + writel(val, bar + HINIC_VF_OP); + + /* Perform the actual device function reset */ + pcie_flr(pdev); + + pci_write_config_word(pdev, PCI_COMMAND, + old_command | PCI_COMMAND_MEMORY); + + /* Waiting for device reset complete */ + timeout = jiffies + msecs_to_jiffies(HINIC_OPERATION_TIMEOUT); + do { + val = readl(bar + HINIC_VF_OP); + if (!(val & (1UL << HINIC_VF_FLR_PROC_BIT_SHIFT))) + goto reset_complete; + msleep(20); + } while (time_before(jiffies, timeout)); + + val = readl(bar + HINIC_VF_OP); + if (!(val & (1UL << HINIC_VF_FLR_PROC_BIT_SHIFT))) + goto reset_complete; + + pci_warn(pdev, "Reset dev timeout, flr ack reg: %x\n", + be32_to_cpu(val)); + +reset_complete: + pci_write_config_word(pdev, PCI_COMMAND, old_command); + pci_iounmap(pdev, bar); + + return 0; +} + static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82599_SFP_VF, reset_intel_82599_sfp_virtfn }, @@ -3886,6 +3959,8 @@ static const struct pci_dev_reset_methods pci_dev_reset_methods[] = { { PCI_VENDOR_ID_INTEL, 0x0953, delay_250ms_after_flr }, { PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID, reset_chelsio_generic_dev }, + { PCI_VENDOR_ID_HUAWEI, PCI_DEVICE_ID_HINIC_VF, + reset_hinic_vf_dev }, { 0 } };
From: Wang Wensheng wangwensheng4@huawei.com
ascend inclusion category: bugfix bugzilla: NA
-------------------
This flag is used by watchdog-core to determine the visibility of the attributes associated with pretimout when the watchdog-core probes the device. If we set the flag after that process those attributes could not be create properly.
Fixes: 569f7c7750c1 ("sbsa_gwdt: Introduce a panic notifier") Signed-off-by: Wang Wensheng wangwensheng4@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- drivers/watchdog/sbsa_gwdt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c index 00723fb9e4ca..8045a66cdb69 100644 --- a/drivers/watchdog/sbsa_gwdt.c +++ b/drivers/watchdog/sbsa_gwdt.c @@ -214,11 +214,14 @@ static irqreturn_t sbsa_gwdt_interrupt(int irq, void *dev_id) return IRQ_HANDLED; }
-static struct watchdog_info sbsa_gwdt_info = { +static const struct watchdog_info sbsa_gwdt_info = { .identity = WATCHDOG_NAME, .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE | +#ifdef CONFIG_ARM_SBSA_WATCHDOG_PANIC_NOTIFIER + WDIOF_PRETIMEOUT | +#endif WDIOF_CARDRESET, };
@@ -369,7 +372,6 @@ static int sbsa_gwdt_probe(struct platform_device *pdev) * Add WDIOF_PRETIMEOUT flags to enable user to configure it. */ gwdt->wdd.pretimeout = gwdt->wdd.timeout - 1; - sbsa_gwdt_info.options |= WDIOF_PRETIMEOUT;
sbsa_register_panic_notifier(gwdt); }