This is the 6.1.99 stable release
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEZH8oZUiU471FcZm+ONu9yGCSaT4FAmaUzokACgkQONu9yGCS aT6cCxAAx/YMg+sxsr9HAUoESTGzBVbo+3rrcTT7/rjtanuuJh0qOEtUJgkagvBp vs3JVUItKCNaHvP+F8oFdhLcmUXIMCdwr+q5pDcxSu/RPJsGuipJeCyERqq1kJnZ f5JIha7jYxooSG7gMJZ8KT/MZ4h7EMl5izm3Nm1iRhX1TWUQWXuJL7YypjmfANj9 5Oono+UFhxd2OSE4HINFugKxuTwftq76Al8L1KCOdlhdi1P6r1KKJIk8zOviemDy qdNq5RIr2EvMK2c2wpfIPP/12qMS82BHnPm+C/x/gi71wkk2HerYcli55xymq9ku 4gxCrPrnYom/bKOqFt2tyD4lSBhaQvQVcK6Qsr9XD0SD/jNAF+qOG53mMTA2A4wJ FTayYD5ZCeIHpRGf/JH3IwmV0PZa4dcWT/0emHLRVMLKhfUsDJEeR+s5VUoH3bl0 Zt5ephiaM4XebbYmWrrl2/xHZXxqbBNTDRcwrLQV19VNJ3PC2F35G5srquKgQKHt B0VuK8DV0YL9bR8+8z2e1cI6KzWFAqK2mn6FsR7/vl2HNr+L1aUbs2YwP52jf09v TkuM8NrTqcm4D16M2gfdTS/RGD9ZkoQEwQmHvT3TrMqMKS9MENVpIQ0RpcZsFcUG WejfybtvWP1sXeJ0mR4nzcksW/RqjnpAI0cUuDKs/cQpoAtHKRg= =qb6c -----END PGP SIGNATURE----- Merge tag 'v6.1.99' This is the 6.1.99 stable release * tag 'v6.1.99': (1975 commits) Linux 6.1.99 Revert "usb: xhci: prevent potential failure in handle_tx_event() for Transfer events without TRB" Linux 6.1.98 nilfs2: fix incorrect inode allocation from reserved inodes null_blk: Do not allow runt zone with zone capacity smaller then zone size spi: cadence: Ensure data lines set to low during dummy-cycle period nfc/nci: Add the inconsistency check between the input data length and count kbuild: fix short log for AS in link-vmlinux.sh nvmet: fix a possible leak when destroy a ctrl during qp establishment platform/x86: touchscreen_dmi: Add info for the EZpad 6s Pro platform/x86: touchscreen_dmi: Add info for GlobalSpace SolT IVW 11.6" tablet regmap-i2c: Subtract reg size from max_write nvme: adjust multiples of NVME_CTRL_PAGE_SIZE in offset dma-mapping: benchmark: avoid needless copy_to_user if benchmark fails nvme-multipath: find NUMA path only for online numa-node ALSA: hda/realtek: Enable headset mic of JP-IK LEAP W502 with ALC897 fs/ntfs3: Mark volume as dirty if xattr is broken i2c: pnx: Fix potential deadlock warning from del_timer_sync() call in isr clk: mediatek: mt8183: Only enable runtime PM on mt8183-mfgcfg clk: mediatek: clk-mtk: Register MFG notifier in mtk_clk_simple_probe() ... Change-Id: Ibf9c2caa3bbffb7a960e82ec6c2b0b497753778c Conflicts: arch/arm64/boot/dts/rockchip/rk3328.dtsi drivers/gpu/drm/rockchip/rockchip_drm_vop2.c drivers/phy/rockchip/phy-rockchip-snps-pcie3.c drivers/pinctrl/pinctrl-rockchip.c drivers/usb/gadget/function/u_audio.c include/linux/usb/quirks.h mm/cma.c sound/soc/rockchip/rockchip_i2s_tdm.c
This commit is contained in:
commit
495fe343ce
1822 changed files with 20361 additions and 12465 deletions
4
mm/cma.c
4
mm/cma.c
|
|
@ -192,10 +192,6 @@ int __init cma_init_reserved_mem(phys_addr_t base, phys_addr_t size,
|
|||
return -EINVAL;
|
||||
|
||||
#if !IS_ENABLED(CONFIG_CMA_INACTIVE)
|
||||
/* alignment should be aligned with order_per_bit */
|
||||
if (!IS_ALIGNED(CMA_MIN_ALIGNMENT_PAGES, 1 << order_per_bit))
|
||||
return -EINVAL;
|
||||
|
||||
/* ensure minimal alignment required by mm core */
|
||||
if (!IS_ALIGNED(base | size, CMA_MIN_ALIGNMENT_BYTES))
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -2108,32 +2108,11 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
|||
return __split_huge_zero_page_pmd(vma, haddr, pmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Up to this point the pmd is present and huge and userland has the
|
||||
* whole access to the hugepage during the split (which happens in
|
||||
* place). If we overwrite the pmd with the not-huge version pointing
|
||||
* to the pte here (which of course we could if all CPUs were bug
|
||||
* free), userland could trigger a small page size TLB miss on the
|
||||
* small sized TLB while the hugepage TLB entry is still established in
|
||||
* the huge TLB. Some CPU doesn't like that.
|
||||
* See http://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf, Erratum
|
||||
* 383 on page 105. Intel should be safe but is also warns that it's
|
||||
* only safe if the permission and cache attributes of the two entries
|
||||
* loaded in the two TLB is identical (which should be the case here).
|
||||
* But it is generally safer to never allow small and huge TLB entries
|
||||
* for the same virtual address to be loaded simultaneously. So instead
|
||||
* of doing "pmd_populate(); flush_pmd_tlb_range();" we first mark the
|
||||
* current pmd notpresent (atomically because here the pmd_trans_huge
|
||||
* must remain set at all times on the pmd until the split is complete
|
||||
* for this pmd), then we flush the SMP TLB and finally we write the
|
||||
* non-huge version of the pmd entry with pmd_populate.
|
||||
*/
|
||||
old_pmd = pmdp_invalidate(vma, haddr, pmd);
|
||||
|
||||
pmd_migration = is_pmd_migration_entry(old_pmd);
|
||||
pmd_migration = is_pmd_migration_entry(*pmd);
|
||||
if (unlikely(pmd_migration)) {
|
||||
swp_entry_t entry;
|
||||
|
||||
old_pmd = *pmd;
|
||||
entry = pmd_to_swp_entry(old_pmd);
|
||||
page = pfn_swap_entry_to_page(entry);
|
||||
write = is_writable_migration_entry(entry);
|
||||
|
|
@ -2144,6 +2123,30 @@ static void __split_huge_pmd_locked(struct vm_area_struct *vma, pmd_t *pmd,
|
|||
soft_dirty = pmd_swp_soft_dirty(old_pmd);
|
||||
uffd_wp = pmd_swp_uffd_wp(old_pmd);
|
||||
} else {
|
||||
/*
|
||||
* Up to this point the pmd is present and huge and userland has
|
||||
* the whole access to the hugepage during the split (which
|
||||
* happens in place). If we overwrite the pmd with the not-huge
|
||||
* version pointing to the pte here (which of course we could if
|
||||
* all CPUs were bug free), userland could trigger a small page
|
||||
* size TLB miss on the small sized TLB while the hugepage TLB
|
||||
* entry is still established in the huge TLB. Some CPU doesn't
|
||||
* like that. See
|
||||
* http://support.amd.com/TechDocs/41322_10h_Rev_Gd.pdf, Erratum
|
||||
* 383 on page 105. Intel should be safe but is also warns that
|
||||
* it's only safe if the permission and cache attributes of the
|
||||
* two entries loaded in the two TLB is identical (which should
|
||||
* be the case here). But it is generally safer to never allow
|
||||
* small and huge TLB entries for the same virtual address to be
|
||||
* loaded simultaneously. So instead of doing "pmd_populate();
|
||||
* flush_pmd_tlb_range();" we first mark the current pmd
|
||||
* notpresent (atomically because here the pmd_trans_huge must
|
||||
* remain set at all times on the pmd until the split is
|
||||
* complete for this pmd), then we flush the SMP TLB and finally
|
||||
* we write the non-huge version of the pmd entry with
|
||||
* pmd_populate.
|
||||
*/
|
||||
old_pmd = pmdp_invalidate(vma, haddr, pmd);
|
||||
page = pmd_page(old_pmd);
|
||||
if (pmd_dirty(old_pmd)) {
|
||||
dirty = true;
|
||||
|
|
|
|||
61
mm/hugetlb.c
61
mm/hugetlb.c
|
|
@ -1661,9 +1661,10 @@ static void __remove_hugetlb_page(struct hstate *h, struct page *page,
|
|||
bool demote)
|
||||
{
|
||||
int nid = page_to_nid(page);
|
||||
struct folio *folio = page_folio(page);
|
||||
|
||||
VM_BUG_ON_PAGE(hugetlb_cgroup_from_page(page), page);
|
||||
VM_BUG_ON_PAGE(hugetlb_cgroup_from_page_rsvd(page), page);
|
||||
VM_BUG_ON_FOLIO(hugetlb_cgroup_from_folio(folio), folio);
|
||||
VM_BUG_ON_FOLIO(hugetlb_cgroup_from_folio_rsvd(folio), folio);
|
||||
|
||||
lockdep_assert_held(&hugetlb_lock);
|
||||
if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
|
||||
|
|
@ -1761,7 +1762,6 @@ static void __update_and_free_page(struct hstate *h, struct page *page)
|
|||
{
|
||||
int i;
|
||||
struct page *subpage;
|
||||
bool clear_dtor = HPageVmemmapOptimized(page);
|
||||
|
||||
if (hstate_is_gigantic(h) && !gigantic_page_runtime_supported())
|
||||
return;
|
||||
|
|
@ -1796,7 +1796,7 @@ static void __update_and_free_page(struct hstate *h, struct page *page)
|
|||
* If vmemmap pages were allocated above, then we need to clear the
|
||||
* hugetlb destructor under the hugetlb lock.
|
||||
*/
|
||||
if (clear_dtor) {
|
||||
if (PageHuge(page)) {
|
||||
spin_lock_irq(&hugetlb_lock);
|
||||
__clear_hugetlb_destructor(h, page);
|
||||
spin_unlock_irq(&hugetlb_lock);
|
||||
|
|
@ -1917,21 +1917,22 @@ void free_huge_page(struct page *page)
|
|||
* Can't pass hstate in here because it is called from the
|
||||
* compound page destructor.
|
||||
*/
|
||||
struct hstate *h = page_hstate(page);
|
||||
int nid = page_to_nid(page);
|
||||
struct hugepage_subpool *spool = hugetlb_page_subpool(page);
|
||||
struct folio *folio = page_folio(page);
|
||||
struct hstate *h = folio_hstate(folio);
|
||||
int nid = folio_nid(folio);
|
||||
struct hugepage_subpool *spool = hugetlb_folio_subpool(folio);
|
||||
bool restore_reserve;
|
||||
unsigned long flags;
|
||||
|
||||
VM_BUG_ON_PAGE(page_count(page), page);
|
||||
VM_BUG_ON_PAGE(page_mapcount(page), page);
|
||||
VM_BUG_ON_FOLIO(folio_ref_count(folio), folio);
|
||||
VM_BUG_ON_FOLIO(folio_mapcount(folio), folio);
|
||||
|
||||
hugetlb_set_page_subpool(page, NULL);
|
||||
if (PageAnon(page))
|
||||
__ClearPageAnonExclusive(page);
|
||||
page->mapping = NULL;
|
||||
restore_reserve = HPageRestoreReserve(page);
|
||||
ClearHPageRestoreReserve(page);
|
||||
hugetlb_set_folio_subpool(folio, NULL);
|
||||
if (folio_test_anon(folio))
|
||||
__ClearPageAnonExclusive(&folio->page);
|
||||
folio->mapping = NULL;
|
||||
restore_reserve = folio_test_hugetlb_restore_reserve(folio);
|
||||
folio_clear_hugetlb_restore_reserve(folio);
|
||||
|
||||
/*
|
||||
* If HPageRestoreReserve was set on page, page allocation consumed a
|
||||
|
|
@ -1953,15 +1954,15 @@ void free_huge_page(struct page *page)
|
|||
}
|
||||
|
||||
spin_lock_irqsave(&hugetlb_lock, flags);
|
||||
ClearHPageMigratable(page);
|
||||
hugetlb_cgroup_uncharge_page(hstate_index(h),
|
||||
pages_per_huge_page(h), page);
|
||||
hugetlb_cgroup_uncharge_page_rsvd(hstate_index(h),
|
||||
pages_per_huge_page(h), page);
|
||||
folio_clear_hugetlb_migratable(folio);
|
||||
hugetlb_cgroup_uncharge_folio(hstate_index(h),
|
||||
pages_per_huge_page(h), folio);
|
||||
hugetlb_cgroup_uncharge_folio_rsvd(hstate_index(h),
|
||||
pages_per_huge_page(h), folio);
|
||||
if (restore_reserve)
|
||||
h->resv_huge_pages++;
|
||||
|
||||
if (HPageTemporary(page)) {
|
||||
if (folio_test_hugetlb_temporary(folio)) {
|
||||
remove_hugetlb_page(h, page, false);
|
||||
spin_unlock_irqrestore(&hugetlb_lock, flags);
|
||||
update_and_free_page(h, page, true);
|
||||
|
|
@ -3080,6 +3081,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
|
|||
struct hugepage_subpool *spool = subpool_vma(vma);
|
||||
struct hstate *h = hstate_vma(vma);
|
||||
struct page *page;
|
||||
struct folio *folio;
|
||||
long map_chg, map_commit;
|
||||
long gbl_chg;
|
||||
int ret, idx;
|
||||
|
|
@ -3143,6 +3145,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
|
|||
* a reservation exists for the allocation.
|
||||
*/
|
||||
page = dequeue_huge_page_vma(h, vma, addr, avoid_reserve, gbl_chg);
|
||||
|
||||
if (!page) {
|
||||
spin_unlock_irq(&hugetlb_lock);
|
||||
page = alloc_buddy_huge_page_with_mpol(h, vma, addr);
|
||||
|
|
@ -3157,6 +3160,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
|
|||
set_page_refcounted(page);
|
||||
/* Fall through */
|
||||
}
|
||||
folio = page_folio(page);
|
||||
hugetlb_cgroup_commit_charge(idx, pages_per_huge_page(h), h_cg, page);
|
||||
/* If allocation is not consuming a reservation, also store the
|
||||
* hugetlb_cgroup pointer on the page.
|
||||
|
|
@ -3185,9 +3189,12 @@ struct page *alloc_huge_page(struct vm_area_struct *vma,
|
|||
|
||||
rsv_adjust = hugepage_subpool_put_pages(spool, 1);
|
||||
hugetlb_acct_memory(h, -rsv_adjust);
|
||||
if (deferred_reserve)
|
||||
hugetlb_cgroup_uncharge_page_rsvd(hstate_index(h),
|
||||
pages_per_huge_page(h), page);
|
||||
if (deferred_reserve) {
|
||||
spin_lock_irq(&hugetlb_lock);
|
||||
hugetlb_cgroup_uncharge_folio_rsvd(hstate_index(h),
|
||||
pages_per_huge_page(h), folio);
|
||||
spin_unlock_irq(&hugetlb_lock);
|
||||
}
|
||||
}
|
||||
return page;
|
||||
|
||||
|
|
@ -7662,9 +7669,9 @@ void __init hugetlb_cma_reserve(int order)
|
|||
* huge page demotion.
|
||||
*/
|
||||
res = cma_declare_contiguous_nid(0, size, 0,
|
||||
PAGE_SIZE << HUGETLB_PAGE_ORDER,
|
||||
0, false, name,
|
||||
&hugetlb_cma[nid], nid);
|
||||
PAGE_SIZE << HUGETLB_PAGE_ORDER,
|
||||
HUGETLB_PAGE_ORDER, false, name,
|
||||
&hugetlb_cma[nid], nid);
|
||||
if (res) {
|
||||
pr_warn("hugetlb_cma: reservation failed: err %d, node %d",
|
||||
res, nid);
|
||||
|
|
|
|||
|
|
@ -191,8 +191,9 @@ static void hugetlb_cgroup_move_parent(int idx, struct hugetlb_cgroup *h_cg,
|
|||
struct page_counter *counter;
|
||||
struct hugetlb_cgroup *page_hcg;
|
||||
struct hugetlb_cgroup *parent = parent_hugetlb_cgroup(h_cg);
|
||||
struct folio *folio = page_folio(page);
|
||||
|
||||
page_hcg = hugetlb_cgroup_from_page(page);
|
||||
page_hcg = hugetlb_cgroup_from_folio(folio);
|
||||
/*
|
||||
* We can have pages in active list without any cgroup
|
||||
* ie, hugepage with less than 3 pages. We can safely
|
||||
|
|
@ -314,7 +315,7 @@ static void __hugetlb_cgroup_commit_charge(int idx, unsigned long nr_pages,
|
|||
if (hugetlb_cgroup_disabled() || !h_cg)
|
||||
return;
|
||||
|
||||
__set_hugetlb_cgroup(page, h_cg, rsvd);
|
||||
__set_hugetlb_cgroup(page_folio(page), h_cg, rsvd);
|
||||
if (!rsvd) {
|
||||
unsigned long usage =
|
||||
h_cg->nodeinfo[page_to_nid(page)]->usage[idx];
|
||||
|
|
@ -345,18 +346,18 @@ void hugetlb_cgroup_commit_charge_rsvd(int idx, unsigned long nr_pages,
|
|||
/*
|
||||
* Should be called with hugetlb_lock held
|
||||
*/
|
||||
static void __hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
|
||||
struct page *page, bool rsvd)
|
||||
static void __hugetlb_cgroup_uncharge_folio(int idx, unsigned long nr_pages,
|
||||
struct folio *folio, bool rsvd)
|
||||
{
|
||||
struct hugetlb_cgroup *h_cg;
|
||||
|
||||
if (hugetlb_cgroup_disabled())
|
||||
return;
|
||||
lockdep_assert_held(&hugetlb_lock);
|
||||
h_cg = __hugetlb_cgroup_from_page(page, rsvd);
|
||||
h_cg = __hugetlb_cgroup_from_folio(folio, rsvd);
|
||||
if (unlikely(!h_cg))
|
||||
return;
|
||||
__set_hugetlb_cgroup(page, NULL, rsvd);
|
||||
__set_hugetlb_cgroup(folio, NULL, rsvd);
|
||||
|
||||
page_counter_uncharge(__hugetlb_cgroup_counter_from_cgroup(h_cg, idx,
|
||||
rsvd),
|
||||
|
|
@ -366,27 +367,27 @@ static void __hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
|
|||
css_put(&h_cg->css);
|
||||
else {
|
||||
unsigned long usage =
|
||||
h_cg->nodeinfo[page_to_nid(page)]->usage[idx];
|
||||
h_cg->nodeinfo[folio_nid(folio)]->usage[idx];
|
||||
/*
|
||||
* This write is not atomic due to fetching usage and writing
|
||||
* to it, but that's fine because we call this with
|
||||
* hugetlb_lock held anyway.
|
||||
*/
|
||||
WRITE_ONCE(h_cg->nodeinfo[page_to_nid(page)]->usage[idx],
|
||||
WRITE_ONCE(h_cg->nodeinfo[folio_nid(folio)]->usage[idx],
|
||||
usage - nr_pages);
|
||||
}
|
||||
}
|
||||
|
||||
void hugetlb_cgroup_uncharge_page(int idx, unsigned long nr_pages,
|
||||
struct page *page)
|
||||
void hugetlb_cgroup_uncharge_folio(int idx, unsigned long nr_pages,
|
||||
struct folio *folio)
|
||||
{
|
||||
__hugetlb_cgroup_uncharge_page(idx, nr_pages, page, false);
|
||||
__hugetlb_cgroup_uncharge_folio(idx, nr_pages, folio, false);
|
||||
}
|
||||
|
||||
void hugetlb_cgroup_uncharge_page_rsvd(int idx, unsigned long nr_pages,
|
||||
struct page *page)
|
||||
void hugetlb_cgroup_uncharge_folio_rsvd(int idx, unsigned long nr_pages,
|
||||
struct folio *folio)
|
||||
{
|
||||
__hugetlb_cgroup_uncharge_page(idx, nr_pages, page, true);
|
||||
__hugetlb_cgroup_uncharge_folio(idx, nr_pages, folio, true);
|
||||
}
|
||||
|
||||
static void __hugetlb_cgroup_uncharge_cgroup(int idx, unsigned long nr_pages,
|
||||
|
|
@ -888,13 +889,14 @@ void hugetlb_cgroup_migrate(struct page *oldhpage, struct page *newhpage)
|
|||
struct hugetlb_cgroup *h_cg;
|
||||
struct hugetlb_cgroup *h_cg_rsvd;
|
||||
struct hstate *h = page_hstate(oldhpage);
|
||||
struct folio *old_folio = page_folio(oldhpage);
|
||||
|
||||
if (hugetlb_cgroup_disabled())
|
||||
return;
|
||||
|
||||
spin_lock_irq(&hugetlb_lock);
|
||||
h_cg = hugetlb_cgroup_from_page(oldhpage);
|
||||
h_cg_rsvd = hugetlb_cgroup_from_page_rsvd(oldhpage);
|
||||
h_cg = hugetlb_cgroup_from_folio(old_folio);
|
||||
h_cg_rsvd = hugetlb_cgroup_from_folio_rsvd(old_folio);
|
||||
set_hugetlb_cgroup(oldhpage, NULL);
|
||||
set_hugetlb_cgroup_rsvd(oldhpage, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -258,8 +258,7 @@ void kmsan_internal_set_shadow_origin(void *addr, size_t size, int b,
|
|||
u32 origin, bool checked)
|
||||
{
|
||||
u64 address = (u64)addr;
|
||||
void *shadow_start;
|
||||
u32 *origin_start;
|
||||
u32 *shadow_start, *origin_start;
|
||||
size_t pad = 0;
|
||||
|
||||
KMSAN_WARN_ON(!kmsan_metadata_is_contiguous(addr, size));
|
||||
|
|
@ -287,8 +286,16 @@ void kmsan_internal_set_shadow_origin(void *addr, size_t size, int b,
|
|||
origin_start =
|
||||
(u32 *)kmsan_get_metadata((void *)address, KMSAN_META_ORIGIN);
|
||||
|
||||
for (int i = 0; i < size / KMSAN_ORIGIN_SIZE; i++)
|
||||
origin_start[i] = origin;
|
||||
/*
|
||||
* If the new origin is non-zero, assume that the shadow byte is also non-zero,
|
||||
* and unconditionally overwrite the old origin slot.
|
||||
* If the new origin is zero, overwrite the old origin slot iff the
|
||||
* corresponding shadow slot is zero.
|
||||
*/
|
||||
for (int i = 0; i < size / KMSAN_ORIGIN_SIZE; i++) {
|
||||
if (origin || !shadow_start[i])
|
||||
origin_start[i] = origin;
|
||||
}
|
||||
}
|
||||
|
||||
struct page *kmsan_vmalloc_to_page_or_null(void *vaddr)
|
||||
|
|
|
|||
|
|
@ -84,11 +84,23 @@ static int __page_handle_poison(struct page *page)
|
|||
{
|
||||
int ret;
|
||||
|
||||
zone_pcp_disable(page_zone(page));
|
||||
/*
|
||||
* zone_pcp_disable() can't be used here. It will
|
||||
* hold pcp_batch_high_lock and dissolve_free_huge_page() might hold
|
||||
* cpu_hotplug_lock via static_key_slow_dec() when hugetlb vmemmap
|
||||
* optimization is enabled. This will break current lock dependency
|
||||
* chain and leads to deadlock.
|
||||
* Disabling pcp before dissolving the page was a deterministic
|
||||
* approach because we made sure that those pages cannot end up in any
|
||||
* PCP list. Draining PCP lists expels those pages to the buddy system,
|
||||
* but nothing guarantees that those pages do not get back to a PCP
|
||||
* queue if we need to refill those.
|
||||
*/
|
||||
ret = dissolve_free_huge_page(page);
|
||||
if (!ret)
|
||||
if (!ret) {
|
||||
drain_all_pages(page_zone(page));
|
||||
ret = take_page_off_buddy(page);
|
||||
zone_pcp_enable(page_zone(page));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1098,7 +1110,7 @@ static int me_huge_page(struct page_state *ps, struct page *p)
|
|||
* subpages.
|
||||
*/
|
||||
put_page(hpage);
|
||||
if (__page_handle_poison(p) >= 0) {
|
||||
if (__page_handle_poison(p) > 0) {
|
||||
page_ref_inc(p);
|
||||
res = MF_RECOVERED;
|
||||
} else {
|
||||
|
|
@ -1876,7 +1888,7 @@ retry:
|
|||
*/
|
||||
if (res == 0) {
|
||||
unlock_page(head);
|
||||
if (__page_handle_poison(p) >= 0) {
|
||||
if (__page_handle_poison(p) > 0) {
|
||||
page_ref_inc(p);
|
||||
res = MF_RECOVERED;
|
||||
} else {
|
||||
|
|
@ -2334,6 +2346,13 @@ int unpoison_memory(unsigned long pfn)
|
|||
goto unlock_mutex;
|
||||
}
|
||||
|
||||
if (is_huge_zero_page(page)) {
|
||||
unpoison_pr_info("Unpoison: huge zero page is not supported %#lx\n",
|
||||
pfn, &unpoison_rs);
|
||||
ret = -EOPNOTSUPP;
|
||||
goto unlock_mutex;
|
||||
}
|
||||
|
||||
if (!PageHWPoison(p)) {
|
||||
unpoison_pr_info("Unpoison: Page was already unpoisoned %#lx\n",
|
||||
pfn, &unpoison_rs);
|
||||
|
|
|
|||
|
|
@ -5593,6 +5593,10 @@ int follow_phys(struct vm_area_struct *vma,
|
|||
goto out;
|
||||
pte = *ptep;
|
||||
|
||||
/* Never return PFNs of anon folios in COW mappings. */
|
||||
if (vm_normal_folio(vma, address, pte))
|
||||
goto unlock;
|
||||
|
||||
if ((flags & FOLL_WRITE) && !pte_write(pte))
|
||||
goto unlock;
|
||||
|
||||
|
|
|
|||
|
|
@ -1632,7 +1632,7 @@ struct page *alloc_migration_target(struct page *page, unsigned long private)
|
|||
nid = folio_nid(folio);
|
||||
|
||||
if (folio_test_hugetlb(folio)) {
|
||||
struct hstate *h = page_hstate(&folio->page);
|
||||
struct hstate *h = folio_hstate(folio);
|
||||
|
||||
gfp_mask = htlb_modify_alloc_mask(h, gfp_mask);
|
||||
return alloc_huge_page_nodemask(h, nid, mtc->nmask, gfp_mask);
|
||||
|
|
|
|||
|
|
@ -414,13 +414,20 @@ static void domain_dirty_limits(struct dirty_throttle_control *dtc)
|
|||
else
|
||||
bg_thresh = (bg_ratio * available_memory) / PAGE_SIZE;
|
||||
|
||||
if (bg_thresh >= thresh)
|
||||
bg_thresh = thresh / 2;
|
||||
tsk = current;
|
||||
if (rt_task(tsk)) {
|
||||
bg_thresh += bg_thresh / 4 + global_wb_domain.dirty_limit / 32;
|
||||
thresh += thresh / 4 + global_wb_domain.dirty_limit / 32;
|
||||
}
|
||||
/*
|
||||
* Dirty throttling logic assumes the limits in page units fit into
|
||||
* 32-bits. This gives 16TB dirty limits max which is hopefully enough.
|
||||
*/
|
||||
if (thresh > UINT_MAX)
|
||||
thresh = UINT_MAX;
|
||||
/* This makes sure bg_thresh is within 32-bits as well */
|
||||
if (bg_thresh >= thresh)
|
||||
bg_thresh = thresh / 2;
|
||||
dtc->thresh = thresh;
|
||||
dtc->bg_thresh = bg_thresh;
|
||||
|
||||
|
|
@ -470,7 +477,11 @@ static unsigned long node_dirty_limit(struct pglist_data *pgdat)
|
|||
if (rt_task(tsk))
|
||||
dirty += dirty / 4;
|
||||
|
||||
return dirty;
|
||||
/*
|
||||
* Dirty throttling logic assumes the limits in page units fit into
|
||||
* 32-bits. This gives 16TB dirty limits max which is hopefully enough.
|
||||
*/
|
||||
return min_t(unsigned long, dirty, UINT_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -507,10 +518,17 @@ static int dirty_background_bytes_handler(struct ctl_table *table, int write,
|
|||
void *buffer, size_t *lenp, loff_t *ppos)
|
||||
{
|
||||
int ret;
|
||||
unsigned long old_bytes = dirty_background_bytes;
|
||||
|
||||
ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
|
||||
if (ret == 0 && write)
|
||||
if (ret == 0 && write) {
|
||||
if (DIV_ROUND_UP(dirty_background_bytes, PAGE_SIZE) >
|
||||
UINT_MAX) {
|
||||
dirty_background_bytes = old_bytes;
|
||||
return -ERANGE;
|
||||
}
|
||||
dirty_background_ratio = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -536,6 +554,10 @@ static int dirty_bytes_handler(struct ctl_table *table, int write,
|
|||
|
||||
ret = proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
|
||||
if (ret == 0 && write && vm_dirty_bytes != old_bytes) {
|
||||
if (DIV_ROUND_UP(vm_dirty_bytes, PAGE_SIZE) > UINT_MAX) {
|
||||
vm_dirty_bytes = old_bytes;
|
||||
return -ERANGE;
|
||||
}
|
||||
writeback_set_ratelimit();
|
||||
vm_dirty_ratio = 0;
|
||||
}
|
||||
|
|
@ -1526,7 +1548,7 @@ static inline void wb_dirty_limits(struct dirty_throttle_control *dtc)
|
|||
*/
|
||||
dtc->wb_thresh = __wb_calc_thresh(dtc);
|
||||
dtc->wb_bg_thresh = dtc->thresh ?
|
||||
div64_u64(dtc->wb_thresh * dtc->bg_thresh, dtc->thresh) : 0;
|
||||
div_u64((u64)dtc->wb_thresh * dtc->bg_thresh, dtc->thresh) : 0;
|
||||
|
||||
/*
|
||||
* In order to avoid the stacked BDI deadlock we need
|
||||
|
|
|
|||
|
|
@ -705,12 +705,16 @@ out:
|
|||
|
||||
static inline unsigned int order_to_pindex(int migratetype, int order)
|
||||
{
|
||||
bool __maybe_unused movable;
|
||||
int base = order;
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
if (order > PAGE_ALLOC_COSTLY_ORDER) {
|
||||
VM_BUG_ON(order != pageblock_order);
|
||||
return NR_LOWORDER_PCP_LISTS;
|
||||
|
||||
movable = migratetype == MIGRATE_MOVABLE;
|
||||
|
||||
return NR_LOWORDER_PCP_LISTS + movable;
|
||||
}
|
||||
#else
|
||||
VM_BUG_ON(order > PAGE_ALLOC_COSTLY_ORDER);
|
||||
|
|
@ -724,7 +728,7 @@ static inline int pindex_to_order(unsigned int pindex)
|
|||
int order = pindex / MIGRATE_PCPTYPES;
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
if (pindex == NR_LOWORDER_PCP_LISTS)
|
||||
if (pindex >= NR_LOWORDER_PCP_LISTS)
|
||||
order = pageblock_order;
|
||||
#else
|
||||
VM_BUG_ON(order > PAGE_ALLOC_COSTLY_ORDER);
|
||||
|
|
|
|||
|
|
@ -70,6 +70,9 @@ static void page_table_check_clear(struct mm_struct *mm, unsigned long addr,
|
|||
page = pfn_to_page(pfn);
|
||||
page_ext = page_ext_get(page);
|
||||
|
||||
if (!page_ext)
|
||||
return;
|
||||
|
||||
BUG_ON(PageSlab(page));
|
||||
anon = PageAnon(page);
|
||||
|
||||
|
|
@ -108,6 +111,9 @@ static void page_table_check_set(struct mm_struct *mm, unsigned long addr,
|
|||
page = pfn_to_page(pfn);
|
||||
page_ext = page_ext_get(page);
|
||||
|
||||
if (!page_ext)
|
||||
return;
|
||||
|
||||
BUG_ON(PageSlab(page));
|
||||
anon = PageAnon(page);
|
||||
|
||||
|
|
@ -138,7 +144,10 @@ void __page_table_check_zero(struct page *page, unsigned int order)
|
|||
BUG_ON(PageSlab(page));
|
||||
|
||||
page_ext = page_ext_get(page);
|
||||
BUG_ON(!page_ext);
|
||||
|
||||
if (!page_ext)
|
||||
return;
|
||||
|
||||
for (i = 0; i < (1ul << order); i++) {
|
||||
struct page_table_check *ptc = get_page_table_check(page_ext);
|
||||
|
||||
|
|
|
|||
|
|
@ -195,6 +195,7 @@ pgtable_t pgtable_trans_huge_withdraw(struct mm_struct *mm, pmd_t *pmdp)
|
|||
pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
|
||||
pmd_t *pmdp)
|
||||
{
|
||||
VM_WARN_ON_ONCE(!pmd_present(*pmdp));
|
||||
pmd_t old = pmdp_establish(vma, address, pmdp, pmd_mkinvalid(*pmdp));
|
||||
flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
|
||||
return old;
|
||||
|
|
@ -205,6 +206,7 @@ pmd_t pmdp_invalidate(struct vm_area_struct *vma, unsigned long address,
|
|||
pmd_t pmdp_invalidate_ad(struct vm_area_struct *vma, unsigned long address,
|
||||
pmd_t *pmdp)
|
||||
{
|
||||
VM_WARN_ON_ONCE(!pmd_present(*pmdp));
|
||||
return pmdp_invalidate(vma, address, pmdp);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -525,6 +525,7 @@ void page_cache_ra_order(struct readahead_control *ractl,
|
|||
pgoff_t index = readahead_index(ractl);
|
||||
pgoff_t limit = (i_size_read(mapping->host) - 1) >> PAGE_SHIFT;
|
||||
pgoff_t mark = index + ra->size - ra->async_size;
|
||||
unsigned int nofs;
|
||||
int err = 0;
|
||||
gfp_t gfp = readahead_gfp_mask(mapping);
|
||||
|
||||
|
|
@ -541,6 +542,8 @@ void page_cache_ra_order(struct readahead_control *ractl,
|
|||
new_order--;
|
||||
}
|
||||
|
||||
/* See comment in page_cache_ra_unbounded() */
|
||||
nofs = memalloc_nofs_save();
|
||||
filemap_invalidate_lock_shared(mapping);
|
||||
while (index <= limit) {
|
||||
unsigned int order = new_order;
|
||||
|
|
@ -569,6 +572,7 @@ void page_cache_ra_order(struct readahead_control *ractl,
|
|||
|
||||
read_pages(ractl);
|
||||
filemap_invalidate_unlock_shared(mapping);
|
||||
memalloc_nofs_restore(nofs);
|
||||
|
||||
/*
|
||||
* If there were already pages in the page cache, then we may have
|
||||
|
|
|
|||
29
mm/vmalloc.c
29
mm/vmalloc.c
|
|
@ -2923,6 +2923,8 @@ vm_area_alloc_pages(gfp_t gfp, int nid,
|
|||
unsigned int order, unsigned int nr_pages, struct page **pages)
|
||||
{
|
||||
unsigned int nr_allocated = 0;
|
||||
gfp_t alloc_gfp = gfp;
|
||||
bool nofail = gfp & __GFP_NOFAIL;
|
||||
struct page *page;
|
||||
int i;
|
||||
|
||||
|
|
@ -2933,6 +2935,7 @@ vm_area_alloc_pages(gfp_t gfp, int nid,
|
|||
* more permissive.
|
||||
*/
|
||||
if (!order) {
|
||||
/* bulk allocator doesn't support nofail req. officially */
|
||||
gfp_t bulk_gfp = gfp & ~__GFP_NOFAIL;
|
||||
|
||||
while (nr_allocated < nr_pages) {
|
||||
|
|
@ -2971,20 +2974,34 @@ vm_area_alloc_pages(gfp_t gfp, int nid,
|
|||
if (nr != nr_pages_request)
|
||||
break;
|
||||
}
|
||||
} else if (gfp & __GFP_NOFAIL) {
|
||||
/*
|
||||
* Higher order nofail allocations are really expensive and
|
||||
* potentially dangerous (pre-mature OOM, disruptive reclaim
|
||||
* and compaction etc.
|
||||
*/
|
||||
alloc_gfp &= ~__GFP_NOFAIL;
|
||||
}
|
||||
|
||||
/* High-order pages or fallback path if "bulk" fails. */
|
||||
|
||||
while (nr_allocated < nr_pages) {
|
||||
if (fatal_signal_pending(current))
|
||||
if (!nofail && fatal_signal_pending(current))
|
||||
break;
|
||||
|
||||
if (nid == NUMA_NO_NODE)
|
||||
page = alloc_pages(gfp, order);
|
||||
page = alloc_pages(alloc_gfp, order);
|
||||
else
|
||||
page = alloc_pages_node(nid, gfp, order);
|
||||
if (unlikely(!page))
|
||||
break;
|
||||
page = alloc_pages_node(nid, alloc_gfp, order);
|
||||
if (unlikely(!page)) {
|
||||
if (!nofail)
|
||||
break;
|
||||
|
||||
/* fall back to the zero order allocations */
|
||||
alloc_gfp |= __GFP_NOFAIL;
|
||||
order = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Higher order allocations must be able to be treated as
|
||||
* indepdenent small pages by callers (as they can with
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue