mm: prioritize tasks holding CMA pages
There are cases reported where CMA allocation fails because of
failure to migrate pages. One of the common cases was because of
pages being pinned by the exit path. The exit path does't really
pin the page, but it appears to be pinned for CMA code. The CMA
code in isolate_mirgatepages_range takes one refcount on page.
Another one is taken by buddy allocator on allocating the page.
CMA can only migrate the page if it is mapped. If !page_mapped,
then only way for CMA to succeed for the page is when it is
freed i.e. page_count == 1 (the one taken by CMA isolate path
itself). The exit path failure happens when !page_mapped and
page_count==2. The reason for this is, on exit, exit_mmap calls
zap_pte_range, which unmaps the page. And after unmapping the
page it has to execute few more pieces of code, before freeing
the pages. But in the failure case, the task in exit path gets
scheduled out and does't get scheduled again for an indefinite
period (in some cases tens of seconds). This happens when the
exiting task has a very low priority (in most cases becasuse of
being in the lowest priority cgroup), and some high priority
tasks hogging the CPU.
When this scenario is detected, move the 'task holding the page'
to root cgroup so that there is more chance for the task
to run and free up the pages. There are rare cases where such
a movement can fail, for e.g. because of failure to acquire
cgroup_mutex. In such cases, as a fallback option, the task
priority is increased to MIN_NICE. It is made sure that all
these is performed 'only' on an exiting task.
CRs-Fixed: 983539
Change-Id: Ib58798a2146b91454b37770c8c1236e06ed35e94
Signed-off-by:
Vinayak Menon <vinmenon@codeaurora.org>
Loading
Please register or sign in to comment