selftests: pidfd: skip test if unshare fails with EPERM
[linux-2.6-microblaze.git] / mm / compaction.c
index fd988b7..8637560 100644 (file)
@@ -2316,15 +2316,26 @@ static enum compact_result compact_zone_order(struct zone *zone, int order,
                .page = NULL,
        };
 
-       current->capture_control = &capc;
+       /*
+        * Make sure the structs are really initialized before we expose the
+        * capture control, in case we are interrupted and the interrupt handler
+        * frees a page.
+        */
+       barrier();
+       WRITE_ONCE(current->capture_control, &capc);
 
        ret = compact_zone(&cc, &capc);
 
        VM_BUG_ON(!list_empty(&cc.freepages));
        VM_BUG_ON(!list_empty(&cc.migratepages));
 
-       *capture = capc.page;
-       current->capture_control = NULL;
+       /*
+        * Make sure we hide capture control first before we read the captured
+        * page pointer, otherwise an interrupt could free and capture a page
+        * and we would leak it.
+        */
+       WRITE_ONCE(current->capture_control, NULL);
+       *capture = READ_ONCE(capc.page);
 
        return ret;
 }