Thread (14 messages) 14 messages, 3 authors, 2016-11-29
STALE3501d

[PATCH] mremap: move_ptes: check pte dirty after its removal

From: Aaron Lu <hidden>
Date: 2016-11-29 02:58:04
Also in: lkml
Subsystem: memory management, memory management - thp (transparent huge page), memory mapping, the rest · Maintainers: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Linus Torvalds

On 11/29/2016 01:15 AM, Linus Torvalds wrote:
However, I also independently think I found an actual bug while
looking at the code as part of looking at the patch.

This part looks racy:

                /*
                 * We are remapping a dirty PTE, make sure to
                 * flush TLB before we drop the PTL for the
                 * old PTE or we may race with page_mkclean().
                 */
                if (pte_present(*old_pte) && pte_dirty(*old_pte))
                        force_flush = true;
                pte = ptep_get_and_clear(mm, old_addr, old_pte);

where the issue is that another thread might make the pte be dirty (in
the hardware walker, so no locking of ours make any difference)
*after* we checked whether it was dirty, but *before* we removed it
from the page tables.
Ah, very right. Thanks for the catch!
So I think the "check for force-flush" needs to come *after*, and we should do

                pte = ptep_get_and_clear(mm, old_addr, old_pte);
                if (pte_present(pte) && pte_dirty(pte))
                        force_flush = true;

instead.

This happens for the pmd case too.
Here is a fix patch, sorry for the trouble.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help