Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8d3d8eb2 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mm: zbud: prevent softirq during zbud alloc, free and reclaim"

parents 5999a957 6a1fdaa3
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -349,7 +349,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(&pool->lock);
	spin_lock_bh(&pool->lock);

	/* First, try to find an unbuddied zbud page. */
	zhdr = NULL;
@@ -368,11 +368,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(&pool->lock);
	spin_unlock_bh(&pool->lock);
	page = alloc_page(gfp);
	if (!page)
		return -ENOMEM;
	spin_lock(&pool->lock);
	spin_lock_bh(&pool->lock);
	pool->pages_nr++;
	zhdr = init_zbud_page(page);
	bud = FIRST;
@@ -400,7 +400,7 @@ found:
	*handle = encode_handle(zhdr, bud);
	if ((gfp & __GFP_ZERO) && found)
		memset((void *)*handle, 0, size);
	spin_unlock(&pool->lock);
	spin_unlock_bh(&pool->lock);

	return 0;
}
@@ -420,7 +420,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
	struct zbud_header *zhdr;
	int freechunks;

	spin_lock(&pool->lock);
	spin_lock_bh(&pool->lock);
	zhdr = handle_to_zbud_header(handle);

	/* If first buddy, handle will be page aligned */
@@ -431,7 +431,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(&pool->lock);
		spin_unlock_bh(&pool->lock);
		return;
	}

@@ -449,7 +449,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
		list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
	}

	spin_unlock(&pool->lock);
	spin_unlock_bh(&pool->lock);
}

#define list_tail_entry(ptr, type, member) \
@@ -496,10 +496,10 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries)
	struct zbud_header *zhdr;
	unsigned long first_handle = 0, last_handle = 0;

	spin_lock(&pool->lock);
	spin_lock_bh(&pool->lock);
	if (!pool->ops || !pool->ops->evict || list_empty(&pool->lru) ||
			retries == 0) {
		spin_unlock(&pool->lock);
		spin_unlock_bh(&pool->lock);
		return -EINVAL;
	}
	for (i = 0; i < retries; i++) {
@@ -518,7 +518,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(&pool->lock);
		spin_unlock_bh(&pool->lock);

		/* Issue the eviction callback(s) */
		if (first_handle) {
@@ -532,7 +532,7 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries)
				goto next;
		}
next:
		spin_lock(&pool->lock);
		spin_lock_bh(&pool->lock);
		zhdr->under_reclaim = false;
		if (zhdr->first_chunks == 0 && zhdr->last_chunks == 0) {
			/*
@@ -541,7 +541,7 @@ next:
			 */
			free_zbud_page(zhdr);
			pool->pages_nr--;
			spin_unlock(&pool->lock);
			spin_unlock_bh(&pool->lock);
			return 0;
		} else if (zhdr->first_chunks == 0 ||
				zhdr->last_chunks == 0) {
@@ -556,7 +556,7 @@ next:
		/* add to beginning of LRU */
		list_add(&zhdr->lru, &pool->lru);
	}
	spin_unlock(&pool->lock);
	spin_unlock_bh(&pool->lock);
	return -EAGAIN;
}