Revision 8a8683ad9ba48b4b52a57f013513d1635c1ca5c4 authored by Huang Ying on 06 March 2020, 06:28:29 UTC, committed by Linus Torvalds on 06 March 2020, 13:06:09 UTC
In set_pmd_migration_entry(), pmdp_invalidate() is used to change PMD
atomically.  But the PMD is read before that with an ordinary memory
reading.  If the THP (transparent huge page) is written between the PMD
reading and pmdp_invalidate(), the PMD dirty bit may be lost, and cause
data corruption.  The race window is quite small, but still possible in
theory, so need to be fixed.

The race is fixed via using the return value of pmdp_invalidate() to get
the original content of PMD, which is a read/modify/write atomic
operation.  So no THP writing can occur in between.

The race has been introduced when the THP migration support is added in
the commit 616b8371539a ("mm: thp: enable thp migration in generic path").
But this fix depends on the commit d52605d7cb30 ("mm: do not lose dirty
and accessed bits in pmdp_invalidate()").  So it's easy to be backported
after v4.16.  But the race window is really small, so it may be fine not
to backport the fix at all.

Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: "Huang, Ying" <ying.huang@intel.com>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: William Kucharski <william.kucharski@oracle.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: <stable@vger.kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Link: http://lkml.kernel.org/r/20200220075220.2327056-1-ying.huang@intel.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 8b272b3
Raw File
ca.h.rst.exceptions
# SPDX-License-Identifier: GPL-2.0

# Ignore header name
ignore define _DVBCA_H_

# struct ca_slot_info defines
replace define CA_CI :c:type:`ca_slot_info`
replace define CA_CI_LINK :c:type:`ca_slot_info`
replace define CA_CI_PHYS :c:type:`ca_slot_info`
replace define CA_DESCR :c:type:`ca_slot_info`
replace define CA_SC :c:type:`ca_slot_info`
replace define CA_CI_MODULE_PRESENT :c:type:`ca_slot_info`
replace define CA_CI_MODULE_READY :c:type:`ca_slot_info`

# struct ca_descr_info defines
replace define CA_ECD :c:type:`ca_descr_info`
replace define CA_NDS :c:type:`ca_descr_info`
replace define CA_DSS :c:type:`ca_descr_info`

# some typedefs should point to struct/enums
replace typedef ca_slot_info_t :c:type:`ca_slot_info`
replace typedef ca_descr_info_t :c:type:`ca_descr_info`
replace typedef ca_caps_t :c:type:`ca_caps`
replace typedef ca_msg_t :c:type:`ca_msg`
replace typedef ca_descr_t :c:type:`ca_descr`
back to top