Loading fs/buffer.c +45 −2 Original line number Diff line number Diff line Loading @@ -1451,12 +1451,48 @@ static bool has_bh_in_lru(int cpu, void *dummy) return 0; } static void __evict_bh_lru(void *arg) { struct bh_lru *b = &get_cpu_var(bh_lrus); struct buffer_head *bh = arg; int i; for (i = 0; i < BH_LRU_SIZE; i++) { if (b->bhs[i] == bh) { brelse(b->bhs[i]); b->bhs[i] = NULL; goto out; } } out: put_cpu_var(bh_lrus); } static bool bh_exists_in_lru(int cpu, void *arg) { struct bh_lru *b = per_cpu_ptr(&bh_lrus, cpu); struct buffer_head *bh = arg; int i; for (i = 0; i < BH_LRU_SIZE; i++) { if (b->bhs[i] == bh) return 1; } return 0; } void invalidate_bh_lrus(void) { on_each_cpu_cond(has_bh_in_lru, invalidate_bh_lru, NULL, 1, GFP_KERNEL); } EXPORT_SYMBOL_GPL(invalidate_bh_lrus); static void evict_bh_lrus(struct buffer_head *bh) { on_each_cpu_cond(bh_exists_in_lru, __evict_bh_lru, bh, 1, GFP_ATOMIC); } void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long offset) { Loading Loading @@ -3284,8 +3320,15 @@ drop_buffers(struct page *page, struct buffer_head **buffers_to_free) bh = head; do { if (buffer_busy(bh)) { /* * Check if the busy failure was due to an * outstanding LRU reference */ evict_bh_lrus(bh); if (buffer_busy(bh)) goto failed; } bh = bh->b_this_page; } while (bh != head); Loading mm/cma.c +12 −1 Original line number Diff line number Diff line Loading @@ -409,6 +409,8 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, struct page *page = NULL; int ret = -ENOMEM; int retry_after_sleep = 0; int max_retries = 2; int available_regions = 0; if (!cma || !cma->count) return NULL; Loading @@ -433,8 +435,15 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, bitmap_maxno, start, bitmap_count, mask, offset); if (bitmap_no >= bitmap_maxno) { if (retry_after_sleep < 2) { if (retry_after_sleep < max_retries) { start = 0; /* * update max retries if available free regions * are less. */ if (available_regions < 3) max_retries = 5; available_regions = 0; /* * Page may be momentarily pinned by some other * process which has been scheduled out, eg. Loading @@ -452,6 +461,8 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, break; } } available_regions++; bitmap_set(cma->bitmap, bitmap_no, bitmap_count); /* * It's safe to drop the lock here. We've marked this region for Loading Loading
fs/buffer.c +45 −2 Original line number Diff line number Diff line Loading @@ -1451,12 +1451,48 @@ static bool has_bh_in_lru(int cpu, void *dummy) return 0; } static void __evict_bh_lru(void *arg) { struct bh_lru *b = &get_cpu_var(bh_lrus); struct buffer_head *bh = arg; int i; for (i = 0; i < BH_LRU_SIZE; i++) { if (b->bhs[i] == bh) { brelse(b->bhs[i]); b->bhs[i] = NULL; goto out; } } out: put_cpu_var(bh_lrus); } static bool bh_exists_in_lru(int cpu, void *arg) { struct bh_lru *b = per_cpu_ptr(&bh_lrus, cpu); struct buffer_head *bh = arg; int i; for (i = 0; i < BH_LRU_SIZE; i++) { if (b->bhs[i] == bh) return 1; } return 0; } void invalidate_bh_lrus(void) { on_each_cpu_cond(has_bh_in_lru, invalidate_bh_lru, NULL, 1, GFP_KERNEL); } EXPORT_SYMBOL_GPL(invalidate_bh_lrus); static void evict_bh_lrus(struct buffer_head *bh) { on_each_cpu_cond(bh_exists_in_lru, __evict_bh_lru, bh, 1, GFP_ATOMIC); } void set_bh_page(struct buffer_head *bh, struct page *page, unsigned long offset) { Loading Loading @@ -3284,8 +3320,15 @@ drop_buffers(struct page *page, struct buffer_head **buffers_to_free) bh = head; do { if (buffer_busy(bh)) { /* * Check if the busy failure was due to an * outstanding LRU reference */ evict_bh_lrus(bh); if (buffer_busy(bh)) goto failed; } bh = bh->b_this_page; } while (bh != head); Loading
mm/cma.c +12 −1 Original line number Diff line number Diff line Loading @@ -409,6 +409,8 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, struct page *page = NULL; int ret = -ENOMEM; int retry_after_sleep = 0; int max_retries = 2; int available_regions = 0; if (!cma || !cma->count) return NULL; Loading @@ -433,8 +435,15 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, bitmap_maxno, start, bitmap_count, mask, offset); if (bitmap_no >= bitmap_maxno) { if (retry_after_sleep < 2) { if (retry_after_sleep < max_retries) { start = 0; /* * update max retries if available free regions * are less. */ if (available_regions < 3) max_retries = 5; available_regions = 0; /* * Page may be momentarily pinned by some other * process which has been scheduled out, eg. Loading @@ -452,6 +461,8 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align, break; } } available_regions++; bitmap_set(cma->bitmap, bitmap_no, bitmap_count); /* * It's safe to drop the lock here. We've marked this region for Loading