From: Hugh Dickins <hughd@google.com>
To: Jiri Slaby <jslaby@suse.cz>
Cc: stable@vger.kernel.org,
"Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>,
linux-kernel@vger.kernel.org, Hugh Dickins <hughd@google.com>,
Konstantin Khlebnikov <koct9i@gmail.com>,
Mel Gorman <mgorman@suse.de>, Bob Liu <bob.liu@oracle.com>,
Christoph Lameter <cl@gentwo.org>, Dave Jones <davej@redhat.com>,
David Rientjes <rientjes@google.com>,
Andrew Morton <akpm@linux-foundation.org>,
Linus Torvalds <torvalds@linux-foundation.org>
Subject: Re: [PATCH 3.12 78/78] mm: let mm_find_pmd fix buggy race with THP fault
Date: Fri, 9 Jan 2015 21:01:16 -0800 (PST) [thread overview]
Message-ID: <alpine.LSU.2.11.1501092048090.2283@eggly.anvils> (raw)
In-Reply-To: <e1c34dac913e87ee8d03c06d7a328a7c2137cafb.1420799385.git.jslaby@suse.cz>
On Fri, 9 Jan 2015, Jiri Slaby wrote:
> From: Hugh Dickins <hughd@google.com>
>
> 3.12-stable review patch. If anyone has any objections, please let me know.
>
> ===============
>
> commit f72e7dcdd25229446b102e587ef2f826f76bff28 upstream.
>
> Trinity has reported:
>
> BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
> IP: __lock_acquire (kernel/locking/lockdep.c:3070 (discriminator 1))
> CPU: 6 PID: 16173 Comm: trinity-c364 Tainted: G W
> 3.15.0-rc1-next-20140415-sasha-00020-gaa90d09 #398
> lock_acquire (arch/x86/include/asm/current.h:14
> kernel/locking/lockdep.c:3602)
> _raw_spin_lock (include/linux/spinlock_api_smp.h:143
> kernel/locking/spinlock.c:151)
> remove_migration_pte (mm/migrate.c:137)
> rmap_walk (mm/rmap.c:1628 mm/rmap.c:1699)
> remove_migration_ptes (mm/migrate.c:224)
> migrate_pages (mm/migrate.c:922 mm/migrate.c:960 mm/migrate.c:1126)
> migrate_misplaced_page (mm/migrate.c:1733)
> __handle_mm_fault (mm/memory.c:3762 mm/memory.c:3812 mm/memory.c:3925)
> handle_mm_fault (mm/memory.c:3948)
> __get_user_pages (mm/memory.c:1851)
> __mlock_vma_pages_range (mm/mlock.c:255)
> __mm_populate (mm/mlock.c:711)
> SyS_mlockall (include/linux/mm.h:1799 mm/mlock.c:817 mm/mlock.c:791)
>
> I believe this comes about because, whereas collapsing and splitting THP
> functions take anon_vma lock in write mode (which excludes concurrent
> rmap walks), faulting THP functions (write protection and misplaced
> NUMA) do not - and mostly they do not need to.
>
> But they do use a pmdp_clear_flush(), set_pmd_at() sequence which, for
> an instant (indeed, for a long instant, given the inter-CPU TLB flush in
> there), leaves *pmd neither present not trans_huge.
>
> Which can confuse a concurrent rmap walk, as when removing migration
> ptes, seen in the dumped trace. Although that rmap walk has a 4k page
> to insert, anon_vmas containing THPs are in no way segregated from
> 4k-page anon_vmas, so the 4k-intent mm_find_pmd() does need to cope with
> that instant when a trans_huge pmd is temporarily absent.
>
> I don't think we need strengthen the locking at the THP end: it's easily
> handled with an ACCESS_ONCE() before testing both conditions.
>
> And since mm_find_pmd() had only one caller who wanted a THP rather than
> a pmd, let's slightly repurpose it to fail when it hits a THP or
> non-present pmd, and open code split_huge_page_address() again.
>
> Signed-off-by: Hugh Dickins <hughd@google.com>
> Reported-by: Sasha Levin <sasha.levin@oracle.com>
> Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Cc: Konstantin Khlebnikov <koct9i@gmail.com>
> Cc: Mel Gorman <mgorman@suse.de>
> Cc: Bob Liu <bob.liu@oracle.com>
> Cc: Christoph Lameter <cl@gentwo.org>
> Cc: Dave Jones <davej@redhat.com>
> Cc: David Rientjes <rientjes@google.com>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> ---
> mm/huge_memory.c | 18 ++++++++++++------
> mm/ksm.c | 1 -
> mm/migrate.c | 2 --
> mm/rmap.c | 12 ++++++++----
> 4 files changed, 20 insertions(+), 13 deletions(-)
>
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index e497843f5f65..04d17ba00893 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -2408,8 +2408,6 @@ static void collapse_huge_page(struct mm_struct *mm,
> pmd = mm_find_pmd(mm, address);
> if (!pmd)
> goto out;
> - if (pmd_trans_huge(*pmd))
> - goto out;
>
> anon_vma_lock_write(vma->anon_vma);
>
> @@ -2508,8 +2506,6 @@ static int khugepaged_scan_pmd(struct mm_struct *mm,
> pmd = mm_find_pmd(mm, address);
> if (!pmd)
> goto out;
> - if (pmd_trans_huge(*pmd))
> - goto out;
>
> memset(khugepaged_node_load, 0, sizeof(khugepaged_node_load));
> pte = pte_offset_map_lock(mm, pmd, address, &ptl);
> @@ -2863,12 +2859,22 @@ void split_huge_page_pmd_mm(struct mm_struct *mm, unsigned long address,
> static void split_huge_page_address(struct mm_struct *mm,
> unsigned long address)
> {
> + pgd_t *pgd;
> + pud_t *pud;
> pmd_t *pmd;
>
> VM_BUG_ON(!(address & ~HPAGE_PMD_MASK));
>
> - pmd = mm_find_pmd(mm, address);
> - if (!pmd)
> + pgd = pgd_offset(mm, address);
> + if (!pgd_present(*pgd))
> + return;
> +
> + pud = pud_offset(pgd, address);
> + if (!pud_present(*pud))
> + return;
> +
> + pmd = pmd_offset(pud, address);
> + if (!pmd_present(*pmd))
> return;
> /*
> * Caller holds the mmap_sem write mode, so a huge pmd cannot
> diff --git a/mm/ksm.c b/mm/ksm.c
> index c78fff1e9eae..29cbd06c4884 100644
> --- a/mm/ksm.c
> +++ b/mm/ksm.c
> @@ -945,7 +945,6 @@ static int replace_page(struct vm_area_struct *vma, struct page *page,
> pmd = mm_find_pmd(mm, addr);
> if (!pmd)
> goto out;
> - BUG_ON(pmd_trans_huge(*pmd));
>
> mmun_start = addr;
> mmun_end = addr + PAGE_SIZE;
> diff --git a/mm/migrate.c b/mm/migrate.c
> index d5c84b0a5243..fac5fa0813c4 100644
> --- a/mm/migrate.c
> +++ b/mm/migrate.c
> @@ -136,8 +136,6 @@ static int remove_migration_pte(struct page *new, struct vm_area_struct *vma,
> pmd = mm_find_pmd(mm, addr);
> if (!pmd)
> goto out;
> - if (pmd_trans_huge(*pmd))
> - goto out;
>
> ptep = pte_offset_map(pmd, addr);
>
> diff --git a/mm/rmap.c b/mm/rmap.c
> index 5b8675ccc1ef..440c71c43b8d 100644
> --- a/mm/rmap.c
> +++ b/mm/rmap.c
> @@ -571,6 +571,7 @@ pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address)
> pgd_t *pgd;
> pud_t *pud;
> pmd_t *pmd = NULL;
> + pmd_t pmde;
>
> pgd = pgd_offset(mm, address);
> if (!pgd_present(*pgd))
> @@ -581,7 +582,13 @@ pmd_t *mm_find_pmd(struct mm_struct *mm, unsigned long address)
> goto out;
>
> pmd = pmd_offset(pud, address);
> - if (!pmd_present(*pmd))
> + /*
> + * Some THP functions use the sequence pmdp_clear_flush(), set_pmd_at()
> + * without holding anon_vma lock for write. So when looking for a
> + * genuine pmde (in which to find pte), test present and !THP together.
> + */
> + pmde = ACCESS_ONCE(*pmd);
> + if (!pmd_present(pmde) || pmd_trans_huge(pmde))
> pmd = NULL;
> out:
> return pmd;
> @@ -617,9 +624,6 @@ pte_t *__page_check_address(struct page *page, struct mm_struct *mm,
> if (!pmd)
> return NULL;
>
> - if (pmd_trans_huge(*pmd))
> - return NULL;
> -
> pte = pte_offset_map(pmd, address);
> /* Make a quick check before getting the lock */
> if (!sync && !pte_present(*pte)) {
> --
> 2.2.1
Fine for this to go in, but there is one catch, which I discovered when
backporting to v3.11: it needed one more hunk. I haven't checked your
base tree, but if this applies then I believe you need it - most of the
time no problem, but it can case page migration to fail to find a
migration entry it inserted earlier, then BUG_ON(!PageLocked(p)) in
migration_entry_to_page() soon after. Here's what I wrote back then:
Note on rebase to v3.11: added a hunk to replace the use of mm_find_pmd()
in page_check_address_pmd(). This call had been similarly replaced by
the time of my v3.16 commit, in Kirill Shutemov's v3.15 b5a8cad376ee
("thp: close race between split and zap huge pages"): which we do not
need as such, since it's fixing v3.13 117b0791ac42 ("mm, thp: move ptl
taking inside page_check_address_pmd()"), from a split page-table-lock
series we are not backporting. But without this additional hunk, rmap
sometimes broke when the new semantic for mm_find_pmd() was used here.
(Adding Kirill to Cc: shouldn't he have been Cc'ed already?)
Hugh
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1584,12 +1584,20 @@ pmd_t *page_check_address_pmd(struct page *page,
unsigned long address,
enum page_check_address_pmd_flag flag)
{
+ pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd, *ret = NULL;
if (address & ~HPAGE_PMD_MASK)
goto out;
- pmd = mm_find_pmd(mm, address);
+ pgd = pgd_offset(mm, address);
+ if (!pgd_present(*pgd))
+ goto out;
+ pud = pud_offset(pgd, address);
+ if (!pud_present(*pud))
+ goto out;
+ pmd = pmd_offset(pud, address);
if (!pmd)
goto out;
if (pmd_none(*pmd))
next prev parent reply other threads:[~2015-01-10 5:01 UTC|newest]
Thread overview: 89+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-09 10:30 [PATCH 3.12 00/78] 3.12.36-stable review Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 01/78] ipv6: gre: fix wrong skb->protocol in WCCP Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 02/78] Fix race condition between vxlan_sock_add and vxlan_sock_release Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 03/78] tg3: fix ring init when there are more TX than RX channels Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 04/78] net/mlx4_core: Limit count field to 24 bits in qp_alloc_res Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 05/78] rtnetlink: release net refcnt on error in do_setlink() Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 06/78] xen-netfront: Remove BUGs on paged skb data which crosses a page boundary Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 07/78] net: mvneta: fix Tx interrupt delay Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 08/78] net: mvneta: fix race condition in mvneta_tx() Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 09/78] net: sctp: use MAX_HEADER for headroom reserve in output path Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 10/78] ceph: fix null pointer dereference in discard_cap_releases() Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 11/78] perf/x86/intel: Protect LBR and extra_regs against KVM lying Jiri Slaby
2015-01-10 11:24 ` Dongsu Park
2015-01-10 11:42 ` Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 12/78] s390/3215: fix hanging console issue Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 13/78] s390/3215: fix tty output containing tabs Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 14/78] usb: gadget: at91_udc: move prepare clk into process context Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 15/78] tty: Fix pty master poll() after slave closes v2 Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 16/78] mm: frontswap: invalidate expired data on a dup-store failure Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 17/78] mm/vmpressure.c: fix race in vmpressure_work_fn() Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 18/78] mm: fix swapoff hang after page migration and fork Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 19/78] mm: fix anon_vma_clone() error treatment Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 20/78] i2c: omap: fix NACK and Arbitration Lost irq handling Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 21/78] i2c: omap: fix i207 errata handling Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 22/78] i2c: davinci: generate STP always when NACK is received Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 23/78] drm/radeon: kernel panic in drm_calc_vbltimestamp_from_scanoutpos with 3.18.0-rc6 Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 24/78] drm/i915: More cautious with pch fifo underruns Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 25/78] drm/i915: Unlock panel even when LVDS is disabled Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 26/78] media: smiapp: Only some selection targets are settable Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 27/78] USB: xhci: Reset a halted endpoint immediately when we encounter a stall Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 28/78] AHCI: Add DeviceIDs for Sunrise Point-LP SATA controller Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 29/78] ahci: disable MSI on SAMSUNG 0xa800 SSD Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 30/78] sata_fsl: fix error handling of irq_of_parse_and_map Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 31/78] igb: bring link up when PHY is powered up Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 32/78] powerpc: 32 bit getcpu VDSO function uses 64 bit instructions Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 33/78] ALSA: hda - Add EAPD fixup for ASUS Z99He laptop Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 34/78] ALSA: hda - Fix built-in mic at resume on Lenovo Ideapad S210 Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 35/78] ALSA: usb-audio: Don't resubmit pending URBs at MIDI error recovery Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 36/78] isofs: Fix infinite looping over CE entries Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 37/78] x86/tls: Validate TLS entries to protect espfix Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 38/78] x86/tls: Disallow unusual TLS segments Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 39/78] x86, kvm: Clear paravirt_enabled on KVM guests for espfix32's benefit Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 40/78] mfd: tc6393xb: Fail ohci suspend if full state restore is required Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 41/78] mmc: block: add newline to sysfs display of force_ro Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 42/78] megaraid_sas: corrected return of wait_event from abort frame path Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 43/78] scsi: correct return values for .eh_abort_handler implementations Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 44/78] nfs41: fix nfs4_proc_layoutget error handling Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 45/78] dm bufio: fix memleak when using a dm_buffer's inline bio Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 46/78] dm space map metadata: fix sm_bootstrap_get_nr_blocks() Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 47/78] x86/tls: Don't validate lm in set_thread_area() after all Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 48/78] audit: change decimal constant to macro for invalid uid Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 49/78] isofs: Fix unchecked printing of ER records Jiri Slaby
2015-01-09 10:31 ` [PATCH 3.12 50/78] KEYS: Fix stale key registration at error path Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 51/78] mac80211: fix multicast LED blinking and counter Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 52/78] mac80211: free management frame keys when removing station Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 53/78] thermal: Fix error path in thermal_init() Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 54/78] mnt: Implicitly add MNT_NODEV on remount when it was implicitly added by mount Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 55/78] mnt: Update unprivileged remount test Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 56/78] umount: Disallow unprivileged mount force Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 57/78] groups: Consolidate the setgroups permission checks Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 58/78] userns: Document what the invariant required for safe unprivileged mappings Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 59/78] userns: Don't allow setgroups until a gid mapping has been setablished Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 60/78] userns: Don't allow unprivileged creation of gid mappings Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 61/78] userns: Check euid no fsuid when establishing an unprivileged uid mapping Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 62/78] userns: Only allow the creator of the userns unprivileged mappings Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 63/78] userns: Rename id_map_mutex to userns_state_mutex Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 64/78] userns: Add a knob to disable setgroups on a per user namespace basis Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 65/78] userns: Allow setting gid_maps without privilege when setgroups is disabled Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 66/78] userns: Unbreak the unprivileged remount tests Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 67/78] audit: restore AUDIT_LOGINUID unset ABI Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 68/78] crypto: af_alg - fix backlog handling Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 69/78] ncpfs: return proper error from NCP_IOC_SETROOT ioctl Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 70/78] exit: pidns: alloc_pid() leaks pid_namespace if child_reaper is exiting Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 71/78] udf: Verify symlink size before loading it Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 72/78] eCryptfs: Force RO mount when encrypted view is enabled Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 73/78] eCryptfs: Remove buggy and unnecessary write in file name decode routine Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 74/78] Btrfs: do not move em to modified list when unpinning Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 75/78] Btrfs: fix fs corruption on transaction abort if device supports discard Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 76/78] mfd: stmpe: Fix STMPE24xx GPMR LSB Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 77/78] mfd: viperboard: Fix platform-device id collision Jiri Slaby
2015-01-09 10:32 ` [PATCH 3.12 78/78] mm: let mm_find_pmd fix buggy race with THP fault Jiri Slaby
2015-01-10 5:01 ` Hugh Dickins [this message]
2015-01-12 10:01 ` Jiri Slaby
2015-01-12 11:13 ` Kirill A. Shutemov
2015-01-12 23:13 ` Hugh Dickins
2015-01-09 17:59 ` [PATCH 3.12 00/78] 3.12.36-stable review Guenter Roeck
2015-01-11 3:40 ` Satoru Takeuchi
2015-01-12 10:35 ` Jiri Slaby
2015-01-12 18:00 ` Shuah Khan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=alpine.LSU.2.11.1501092048090.2283@eggly.anvils \
--to=hughd@google.com \
--cc=akpm@linux-foundation.org \
--cc=bob.liu@oracle.com \
--cc=cl@gentwo.org \
--cc=davej@redhat.com \
--cc=jslaby@suse.cz \
--cc=kirill.shutemov@linux.intel.com \
--cc=koct9i@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=rientjes@google.com \
--cc=stable@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®