mm, page_alloc: fix core hung in free_pcppages_bulk()
The following race is observable when onlining the first memory block of
a zone. Consider 2 processes, P1 and P2, where P1 is onlining the first
memory block of a zone(say movable) and P2 is trying to allocate the
pages from the same.
P1 P2
Online the first memory block in
the movable zone. Zone lists are
built but the pcp struct are yet
to update thus the values are
pcp's ->high = 0, ->count = 1.
Allocate the pages from the
movable zone. Since the pages
are available in buddy, it gets
from movable zone.
This process is entered into
the exit path thus it tries
to release the order-0 pages
to pcp lists through
free_unref_page_commit().
As pcp->high = 0, pcp->count = 1
proceed calling the function
free_pcppages_bulk().
Call zone_pcp_update().
Update the pcp values thus the new
pcp values are like, say, pcp's
->high = 378, ->batch = 63.
Read the pcp's batch value using
READ_ONCE() and pass the same to
free_pcppages_bulk(), pcp values
passed here are, batch = 63,
count = 1.
Since num of pages in the pcp
lists are less than ->batch,
then it will stuck in
while(list_empty(list)) loop
with interrupts disabled thus
a core hung.
Avoid this by skipping free_pcppages_bulk() when pcp struct is not
initialized.
Change-Id: I8407b8e91e13ac699233f61f8c2e893061825b4b
Signed-off-by:
Charan Teja Reddy <charante@codeaurora.org>
Loading
Please register or sign in to comment