@@ -48,8 +48,9 @@
/* Encryption added and removed here! (L: */
-static unsigned int num_prealloc_crypto_pages = 32;
static unsigned int num_prealloc_crypto_ctxs = 128;
+static unsigned int num_prealloc_crypto_pages = BIO_MAX_PAGES;
+static unsigned int num_prealloc_emergent_pages = 32;
module_param(num_prealloc_crypto_pages, uint, 0444);
MODULE_PARM_DESC(num_prealloc_crypto_pages,
@@ -58,7 +59,7 @@ module_param(num_prealloc_crypto_ctxs, uint, 0444);
MODULE_PARM_DESC(num_prealloc_crypto_ctxs,
"Number of crypto contexts to preallocate");
-static mempool_t *f2fs_bounce_page_pool;
+static mempool_t *f2fs_bounce_page_pool, *f2fs_emergent_page_pool;
static LIST_HEAD(f2fs_free_crypto_ctxs);
static DEFINE_SPINLOCK(f2fs_crypto_ctx_lock);
@@ -83,10 +84,13 @@ void f2fs_release_crypto_ctx(struct f2fs_crypto_ctx *ctx)
unsigned long flags;
if (ctx->flags & F2FS_WRITE_PATH_FL && ctx->w.bounce_page) {
- if (ctx->flags & F2FS_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL)
- __free_page(ctx->w.bounce_page);
- else
+ if (ctx->flags & F2FS_BOUNCE_PAGE_POOL_FREE_ENCRYPT_FL)
mempool_free(ctx->w.bounce_page, f2fs_bounce_page_pool);
+ else if (ctx->flags & F2FS_EMERGENT_PAGE_POOL_FREE_ENCRYPT_FL)
+ mempool_free(ctx->w.bounce_page,
+ f2fs_emergent_page_pool);
+ else
+ __free_page(ctx->w.bounce_page);
ctx->w.bounce_page = NULL;
}
ctx->w.control_page = NULL;
@@ -189,6 +193,9 @@ static void f2fs_crypto_destroy(void)
if (f2fs_bounce_page_pool)
mempool_destroy(f2fs_bounce_page_pool);
f2fs_bounce_page_pool = NULL;
+ if (f2fs_emergent_page_pool)
+ mempool_destroy(f2fs_emergent_page_pool);
+ f2fs_emergent_page_pool = NULL;
}
/**
@@ -225,6 +232,11 @@ int f2fs_crypto_initialize(void)
if (!f2fs_bounce_page_pool)
goto fail;
+ f2fs_emergent_page_pool =
+ mempool_create_page_pool(num_prealloc_emergent_pages, 0);
+ if (!f2fs_emergent_page_pool)
+ goto fail;
+
already_initialized:
mutex_unlock(&crypto_init);
return 0;
@@ -408,21 +420,28 @@ struct page *f2fs_encrypt(struct inode *inode,
return (struct page *)ctx;
/* The encryption operation will require a bounce page. */
+ ctx->flags &= ~F2FS_MASK_PAGE_POOL_FREE_ENCRYPT_FL;
+
+ ciphertext_page = mempool_alloc(f2fs_bounce_page_pool, GFP_NOFS);
+ if (ciphertext_page) {
+ ctx->flags |= F2FS_BOUNCE_PAGE_POOL_FREE_ENCRYPT_FL;
+ goto got_it;
+ }
+
ciphertext_page = alloc_page(GFP_NOFS);
if (!ciphertext_page) {
/*
* This is a potential bottleneck, but at least we'll have
* forward progress.
*/
- ciphertext_page = mempool_alloc(f2fs_bounce_page_pool,
- GFP_NOFS);
+ ciphertext_page = mempool_alloc(f2fs_emergent_page_pool,
+ GFP_NOFS);
if (WARN_ON_ONCE(!ciphertext_page))
- ciphertext_page = mempool_alloc(f2fs_bounce_page_pool,
- GFP_NOFS | __GFP_WAIT);
- ctx->flags &= ~F2FS_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL;
- } else {
- ctx->flags |= F2FS_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL;
+ ciphertext_page = mempool_alloc(f2fs_emergent_page_pool,
+ GFP_NOFS | __GFP_NOFAIL);
+ ctx->flags |= F2FS_EMERGENT_PAGE_POOL_FREE_ENCRYPT_FL;
}
+got_it:
ctx->flags |= F2FS_WRITE_PATH_FL;
ctx->w.bounce_page = ciphertext_page;
ctx->w.control_page = plaintext_page;
@@ -83,9 +83,13 @@ struct f2fs_crypt_info {
char ci_master_key[F2FS_KEY_DESCRIPTOR_SIZE];
};
-#define F2FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
-#define F2FS_BOUNCE_PAGE_REQUIRES_FREE_ENCRYPT_FL 0x00000002
-#define F2FS_WRITE_PATH_FL 0x00000004
+#define F2FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001
+#define F2FS_WRITE_PATH_FL 0x00000002
+#define F2FS_BOUNCE_PAGE_POOL_FREE_ENCRYPT_FL 0x00000004
+#define F2FS_EMERGENT_PAGE_POOL_FREE_ENCRYPT_FL 0x00000008
+#define F2FS_MASK_PAGE_POOL_FREE_ENCRYPT_FL \
+ (F2FS_BOUNCE_PAGE_POOL_FREE_ENCRYPT_FL | \
+ F2FS_EMERGENT_PAGE_POOL_FREE_ENCRYPT_FL)
struct f2fs_crypto_ctx {
union {