diff options
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r-- | mm/page_alloc.c | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e00f545c2398..634806f55120 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -3156,6 +3156,54 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, | |||
3156 | return NULL; | 3156 | return NULL; |
3157 | } | 3157 | } |
3158 | 3158 | ||
3159 | static inline bool | ||
3160 | should_compact_retry(struct alloc_context *ac, int order, int alloc_flags, | ||
3161 | enum compact_result compact_result, | ||
3162 | enum compact_priority *compact_priority, | ||
3163 | int compaction_retries) | ||
3164 | { | ||
3165 | int max_retries = MAX_COMPACT_RETRIES; | ||
3166 | |||
3167 | if (!order) | ||
3168 | return false; | ||
3169 | |||
3170 | /* | ||
3171 | * compaction considers all the zone as desperately out of memory | ||
3172 | * so it doesn't really make much sense to retry except when the | ||
3173 | * failure could be caused by insufficient priority | ||
3174 | */ | ||
3175 | if (compaction_failed(compact_result)) { | ||
3176 | if (*compact_priority > MIN_COMPACT_PRIORITY) { | ||
3177 | (*compact_priority)--; | ||
3178 | return true; | ||
3179 | } | ||
3180 | return false; | ||
3181 | } | ||
3182 | |||
3183 | /* | ||
3184 | * make sure the compaction wasn't deferred or didn't bail out early | ||
3185 | * due to locks contention before we declare that we should give up. | ||
3186 | * But do not retry if the given zonelist is not suitable for | ||
3187 | * compaction. | ||
3188 | */ | ||
3189 | if (compaction_withdrawn(compact_result)) | ||
3190 | return compaction_zonelist_suitable(ac, order, alloc_flags); | ||
3191 | |||
3192 | /* | ||
3193 | * !costly requests are much more important than __GFP_REPEAT | ||
3194 | * costly ones because they are de facto nofail and invoke OOM | ||
3195 | * killer to move on while costly can fail and users are ready | ||
3196 | * to cope with that. 1/4 retries is rather arbitrary but we | ||
3197 | * would need much more detailed feedback from compaction to | ||
3198 | * make a better decision. | ||
3199 | */ | ||
3200 | if (order > PAGE_ALLOC_COSTLY_ORDER) | ||
3201 | max_retries /= 4; | ||
3202 | if (compaction_retries <= max_retries) | ||
3203 | return true; | ||
3204 | |||
3205 | return false; | ||
3206 | } | ||
3159 | #else | 3207 | #else |
3160 | static inline struct page * | 3208 | static inline struct page * |
3161 | __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, | 3209 | __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, |
@@ -3166,8 +3214,6 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, | |||
3166 | return NULL; | 3214 | return NULL; |
3167 | } | 3215 | } |
3168 | 3216 | ||
3169 | #endif /* CONFIG_COMPACTION */ | ||
3170 | |||
3171 | static inline bool | 3217 | static inline bool |
3172 | should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_flags, | 3218 | should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_flags, |
3173 | enum compact_result compact_result, | 3219 | enum compact_result compact_result, |
@@ -3194,6 +3240,7 @@ should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_fla | |||
3194 | } | 3240 | } |
3195 | return false; | 3241 | return false; |
3196 | } | 3242 | } |
3243 | #endif /* CONFIG_COMPACTION */ | ||
3197 | 3244 | ||
3198 | /* Perform direct synchronous page reclaim */ | 3245 | /* Perform direct synchronous page reclaim */ |
3199 | static int | 3246 | static int |