diff options
Diffstat (limited to 'mm/page_alloc.c')
| -rw-r--r-- | mm/page_alloc.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6d00f746c2fd..6acf612fdd99 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -66,6 +66,7 @@ | |||
| 66 | #include <linux/kthread.h> | 66 | #include <linux/kthread.h> |
| 67 | #include <linux/memcontrol.h> | 67 | #include <linux/memcontrol.h> |
| 68 | #include <linux/ftrace.h> | 68 | #include <linux/ftrace.h> |
| 69 | #include <linux/lockdep.h> | ||
| 69 | 70 | ||
| 70 | #include <asm/sections.h> | 71 | #include <asm/sections.h> |
| 71 | #include <asm/tlbflush.h> | 72 | #include <asm/tlbflush.h> |
| @@ -3490,6 +3491,47 @@ should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_fla | |||
| 3490 | } | 3491 | } |
| 3491 | #endif /* CONFIG_COMPACTION */ | 3492 | #endif /* CONFIG_COMPACTION */ |
| 3492 | 3493 | ||
| 3494 | #ifdef CONFIG_LOCKDEP | ||
| 3495 | struct lockdep_map __fs_reclaim_map = | ||
| 3496 | STATIC_LOCKDEP_MAP_INIT("fs_reclaim", &__fs_reclaim_map); | ||
| 3497 | |||
| 3498 | static bool __need_fs_reclaim(gfp_t gfp_mask) | ||
| 3499 | { | ||
| 3500 | gfp_mask = current_gfp_context(gfp_mask); | ||
| 3501 | |||
| 3502 | /* no reclaim without waiting on it */ | ||
| 3503 | if (!(gfp_mask & __GFP_DIRECT_RECLAIM)) | ||
| 3504 | return false; | ||
| 3505 | |||
| 3506 | /* this guy won't enter reclaim */ | ||
| 3507 | if ((current->flags & PF_MEMALLOC) && !(gfp_mask & __GFP_NOMEMALLOC)) | ||
| 3508 | return false; | ||
| 3509 | |||
| 3510 | /* We're only interested __GFP_FS allocations for now */ | ||
| 3511 | if (!(gfp_mask & __GFP_FS)) | ||
| 3512 | return false; | ||
| 3513 | |||
| 3514 | if (gfp_mask & __GFP_NOLOCKDEP) | ||
| 3515 | return false; | ||
| 3516 | |||
| 3517 | return true; | ||
| 3518 | } | ||
| 3519 | |||
| 3520 | void fs_reclaim_acquire(gfp_t gfp_mask) | ||
| 3521 | { | ||
| 3522 | if (__need_fs_reclaim(gfp_mask)) | ||
| 3523 | lock_map_acquire(&__fs_reclaim_map); | ||
| 3524 | } | ||
| 3525 | EXPORT_SYMBOL_GPL(fs_reclaim_acquire); | ||
| 3526 | |||
| 3527 | void fs_reclaim_release(gfp_t gfp_mask) | ||
| 3528 | { | ||
| 3529 | if (__need_fs_reclaim(gfp_mask)) | ||
| 3530 | lock_map_release(&__fs_reclaim_map); | ||
| 3531 | } | ||
| 3532 | EXPORT_SYMBOL_GPL(fs_reclaim_release); | ||
| 3533 | #endif | ||
| 3534 | |||
| 3493 | /* Perform direct synchronous page reclaim */ | 3535 | /* Perform direct synchronous page reclaim */ |
| 3494 | static int | 3536 | static int |
| 3495 | __perform_reclaim(gfp_t gfp_mask, unsigned int order, | 3537 | __perform_reclaim(gfp_t gfp_mask, unsigned int order, |
| @@ -3504,7 +3546,7 @@ __perform_reclaim(gfp_t gfp_mask, unsigned int order, | |||
| 3504 | /* We now go into synchronous reclaim */ | 3546 | /* We now go into synchronous reclaim */ |
| 3505 | cpuset_memory_pressure_bump(); | 3547 | cpuset_memory_pressure_bump(); |
| 3506 | noreclaim_flag = memalloc_noreclaim_save(); | 3548 | noreclaim_flag = memalloc_noreclaim_save(); |
| 3507 | lockdep_set_current_reclaim_state(gfp_mask); | 3549 | fs_reclaim_acquire(gfp_mask); |
| 3508 | reclaim_state.reclaimed_slab = 0; | 3550 | reclaim_state.reclaimed_slab = 0; |
| 3509 | current->reclaim_state = &reclaim_state; | 3551 | current->reclaim_state = &reclaim_state; |
| 3510 | 3552 | ||
| @@ -3512,7 +3554,7 @@ __perform_reclaim(gfp_t gfp_mask, unsigned int order, | |||
| 3512 | ac->nodemask); | 3554 | ac->nodemask); |
| 3513 | 3555 | ||
| 3514 | current->reclaim_state = NULL; | 3556 | current->reclaim_state = NULL; |
| 3515 | lockdep_clear_current_reclaim_state(); | 3557 | fs_reclaim_release(gfp_mask); |
| 3516 | memalloc_noreclaim_restore(noreclaim_flag); | 3558 | memalloc_noreclaim_restore(noreclaim_flag); |
| 3517 | 3559 | ||
| 3518 | cond_resched(); | 3560 | cond_resched(); |
| @@ -4041,7 +4083,8 @@ static inline bool prepare_alloc_pages(gfp_t gfp_mask, unsigned int order, | |||
| 4041 | *alloc_flags |= ALLOC_CPUSET; | 4083 | *alloc_flags |= ALLOC_CPUSET; |
| 4042 | } | 4084 | } |
| 4043 | 4085 | ||
| 4044 | lockdep_trace_alloc(gfp_mask); | 4086 | fs_reclaim_acquire(gfp_mask); |
| 4087 | fs_reclaim_release(gfp_mask); | ||
| 4045 | 4088 | ||
| 4046 | might_sleep_if(gfp_mask & __GFP_DIRECT_RECLAIM); | 4089 | might_sleep_if(gfp_mask & __GFP_DIRECT_RECLAIM); |
| 4047 | 4090 | ||
