Loading mm/zbud.c +16 −13 Original line number Diff line number Diff line Loading @@ -342,6 +342,7 @@ int zbud_alloc(struct zbud_pool *pool, size_t size, gfp_t gfp, struct zbud_header *zhdr = NULL; enum buddy bud; struct page *page; unsigned long flags; int found = 0; if (!size || (gfp & __GFP_HIGHMEM)) Loading @@ -349,7 +350,7 @@ int zbud_alloc(struct zbud_pool *pool, size_t size, gfp_t gfp, if (size > PAGE_SIZE - ZHDR_SIZE_ALIGNED - CHUNK_SIZE) return -ENOSPC; chunks = size_to_chunks(size); spin_lock_bh(&pool->lock); spin_lock_irqsave(&pool->lock, flags); /* First, try to find an unbuddied zbud page. */ zhdr = NULL; Loading @@ -368,11 +369,11 @@ int zbud_alloc(struct zbud_pool *pool, size_t size, gfp_t gfp, } /* Couldn't find unbuddied zbud page, create new one */ spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); page = alloc_page(gfp); if (!page) return -ENOMEM; spin_lock_bh(&pool->lock); spin_lock_irqsave(&pool->lock, flags); pool->pages_nr++; zhdr = init_zbud_page(page); bud = FIRST; Loading Loading @@ -400,7 +401,7 @@ found: *handle = encode_handle(zhdr, bud); if ((gfp & __GFP_ZERO) && found) memset((void *)*handle, 0, size); spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); return 0; } Loading @@ -419,8 +420,9 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle) { struct zbud_header *zhdr; int freechunks; unsigned long flags; spin_lock_bh(&pool->lock); spin_lock_irqsave(&pool->lock, flags); zhdr = handle_to_zbud_header(handle); /* If first buddy, handle will be page aligned */ Loading @@ -431,7 +433,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle) if (zhdr->under_reclaim) { /* zbud page is under reclaim, reclaim will free */ spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); return; } Loading @@ -449,7 +451,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle) list_add(&zhdr->buddy, &pool->unbuddied[freechunks]); } spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); } #define list_tail_entry(ptr, type, member) \ Loading Loading @@ -494,12 +496,13 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries) { int i, ret, freechunks; struct zbud_header *zhdr; unsigned long flags; unsigned long first_handle = 0, last_handle = 0; spin_lock_bh(&pool->lock); spin_lock_irqsave(&pool->lock, flags); if (!pool->ops || !pool->ops->evict || list_empty(&pool->lru) || retries == 0) { spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); return -EINVAL; } for (i = 0; i < retries; i++) { Loading @@ -518,7 +521,7 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries) first_handle = encode_handle(zhdr, FIRST); if (zhdr->last_chunks) last_handle = encode_handle(zhdr, LAST); spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); /* Issue the eviction callback(s) */ if (first_handle) { Loading @@ -532,7 +535,7 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries) goto next; } next: spin_lock_bh(&pool->lock); spin_lock_irqsave(&pool->lock, flags); zhdr->under_reclaim = false; if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) { /* Loading @@ -541,7 +544,7 @@ next: */ free_zbud_page(zhdr); pool->pages_nr--; spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); return 0; } else if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0) { Loading @@ -556,7 +559,7 @@ next: /* add to beginning of LRU */ list_add(&zhdr->lru, &pool->lru); } spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); return -EAGAIN; } Loading Loading
mm/zbud.c +16 −13 Original line number Diff line number Diff line Loading @@ -342,6 +342,7 @@ int zbud_alloc(struct zbud_pool *pool, size_t size, gfp_t gfp, struct zbud_header *zhdr = NULL; enum buddy bud; struct page *page; unsigned long flags; int found = 0; if (!size || (gfp & __GFP_HIGHMEM)) Loading @@ -349,7 +350,7 @@ int zbud_alloc(struct zbud_pool *pool, size_t size, gfp_t gfp, if (size > PAGE_SIZE - ZHDR_SIZE_ALIGNED - CHUNK_SIZE) return -ENOSPC; chunks = size_to_chunks(size); spin_lock_bh(&pool->lock); spin_lock_irqsave(&pool->lock, flags); /* First, try to find an unbuddied zbud page. */ zhdr = NULL; Loading @@ -368,11 +369,11 @@ int zbud_alloc(struct zbud_pool *pool, size_t size, gfp_t gfp, } /* Couldn't find unbuddied zbud page, create new one */ spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); page = alloc_page(gfp); if (!page) return -ENOMEM; spin_lock_bh(&pool->lock); spin_lock_irqsave(&pool->lock, flags); pool->pages_nr++; zhdr = init_zbud_page(page); bud = FIRST; Loading Loading @@ -400,7 +401,7 @@ found: *handle = encode_handle(zhdr, bud); if ((gfp & __GFP_ZERO) && found) memset((void *)*handle, 0, size); spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); return 0; } Loading @@ -419,8 +420,9 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle) { struct zbud_header *zhdr; int freechunks; unsigned long flags; spin_lock_bh(&pool->lock); spin_lock_irqsave(&pool->lock, flags); zhdr = handle_to_zbud_header(handle); /* If first buddy, handle will be page aligned */ Loading @@ -431,7 +433,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle) if (zhdr->under_reclaim) { /* zbud page is under reclaim, reclaim will free */ spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); return; } Loading @@ -449,7 +451,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle) list_add(&zhdr->buddy, &pool->unbuddied[freechunks]); } spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); } #define list_tail_entry(ptr, type, member) \ Loading Loading @@ -494,12 +496,13 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries) { int i, ret, freechunks; struct zbud_header *zhdr; unsigned long flags; unsigned long first_handle = 0, last_handle = 0; spin_lock_bh(&pool->lock); spin_lock_irqsave(&pool->lock, flags); if (!pool->ops || !pool->ops->evict || list_empty(&pool->lru) || retries == 0) { spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); return -EINVAL; } for (i = 0; i < retries; i++) { Loading @@ -518,7 +521,7 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries) first_handle = encode_handle(zhdr, FIRST); if (zhdr->last_chunks) last_handle = encode_handle(zhdr, LAST); spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); /* Issue the eviction callback(s) */ if (first_handle) { Loading @@ -532,7 +535,7 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries) goto next; } next: spin_lock_bh(&pool->lock); spin_lock_irqsave(&pool->lock, flags); zhdr->under_reclaim = false; if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) { /* Loading @@ -541,7 +544,7 @@ next: */ free_zbud_page(zhdr); pool->pages_nr--; spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); return 0; } else if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0) { Loading @@ -556,7 +559,7 @@ next: /* add to beginning of LRU */ list_add(&zhdr->lru, &pool->lru); } spin_unlock_bh(&pool->lock); spin_unlock_irqrestore(&pool->lock, flags); return -EAGAIN; } Loading