ARM/ARM64: config: enable DM_INIT configuration
[platform/kernel/linux-rpi.git] / mm / zswap.c
index 2076326..4719af5 100644 (file)
@@ -648,8 +648,9 @@ error:
        return NULL;
 }
 
-static __init struct zswap_pool *__zswap_pool_create_fallback(void)
+static bool zswap_try_pool_create(void)
 {
+       struct zswap_pool *pool;
        bool has_comp, has_zpool;
 
        has_comp = crypto_has_acomp(zswap_compressor, 0, 0);
@@ -685,9 +686,21 @@ static __init struct zswap_pool *__zswap_pool_create_fallback(void)
        }
 
        if (!has_comp || !has_zpool)
-               return NULL;
+               return false;
+
+       pool = zswap_pool_create(zswap_zpool_type, zswap_compressor);
+
+       if (pool) {
+               pr_info("loaded using pool %s/%s\n", pool->tfm_name,
+                       zpool_get_type(pool->zpool));
+               list_add(&pool->list, &zswap_pools);
+               zswap_has_pool = true;
+       } else {
+               pr_err("pool creation failed\n");
+               zswap_enabled = false;
+       }
 
-       return zswap_pool_create(zswap_zpool_type, zswap_compressor);
+       return zswap_enabled;
 }
 
 static void zswap_pool_destroy(struct zswap_pool *pool)
@@ -860,16 +873,19 @@ static int zswap_zpool_param_set(const char *val,
 static int zswap_enabled_param_set(const char *val,
                                   const struct kernel_param *kp)
 {
+       int ret;
+
        if (zswap_init_failed) {
                pr_err("can't enable, initialization failed\n");
                return -ENODEV;
        }
-       if (!zswap_has_pool && zswap_init_started) {
-               pr_err("can't enable, no pool configured\n");
-               return -ENODEV;
-       }
 
-       return param_set_bool(val, kp);
+       ret = param_set_bool(val, kp);
+       if (!ret && zswap_enabled && zswap_init_started && !zswap_has_pool)
+               if (!zswap_try_pool_create())
+                       ret = -ENODEV;
+
+       return ret;
 }
 
 /*********************************
@@ -967,6 +983,13 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
        spin_unlock(&tree->lock);
        BUG_ON(offset != entry->offset);
 
+       src = (u8 *)zhdr + sizeof(struct zswap_header);
+       if (!zpool_can_sleep_mapped(pool)) {
+               memcpy(tmp, src, entry->length);
+               src = tmp;
+               zpool_unmap_handle(pool, handle);
+       }
+
        /* try to allocate swap cache page */
        switch (zswap_get_swap_cache_page(swpentry, &page)) {
        case ZSWAP_SWAPCACHE_FAIL: /* no memory or invalidate happened */
@@ -982,17 +1005,7 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
        case ZSWAP_SWAPCACHE_NEW: /* page is locked */
                /* decompress */
                acomp_ctx = raw_cpu_ptr(entry->pool->acomp_ctx);
-
                dlen = PAGE_SIZE;
-               src = (u8 *)zhdr + sizeof(struct zswap_header);
-
-               if (!zpool_can_sleep_mapped(pool)) {
-
-                       memcpy(tmp, src, entry->length);
-                       src = tmp;
-
-                       zpool_unmap_handle(pool, handle);
-               }
 
                mutex_lock(acomp_ctx->mutex);
                sg_init_one(&input, src, entry->length);
@@ -1203,7 +1216,7 @@ static int zswap_frontswap_store(unsigned type, pgoff_t offset,
                zswap_reject_alloc_fail++;
                goto put_dstmem;
        }
-       buf = zpool_map_handle(entry->pool->zpool, handle, ZPOOL_MM_RW);
+       buf = zpool_map_handle(entry->pool->zpool, handle, ZPOOL_MM_WO);
        memcpy(buf, &zhdr, hlen);
        memcpy(buf + hlen, dst, dlen);
        zpool_unmap_handle(entry->pool->zpool, handle);
@@ -1427,18 +1440,11 @@ static int __init zswap_debugfs_init(void)
 
        return 0;
 }
-
-static void __exit zswap_debugfs_exit(void)
-{
-       debugfs_remove_recursive(zswap_debugfs_root);
-}
 #else
 static int __init zswap_debugfs_init(void)
 {
        return 0;
 }
-
-static void __exit zswap_debugfs_exit(void) { }
 #endif
 
 /*********************************
@@ -1446,7 +1452,6 @@ static void __exit zswap_debugfs_exit(void) { }
 **********************************/
 static int __init init_zswap(void)
 {
-       struct zswap_pool *pool;
        int ret;
 
        zswap_init_started = true;
@@ -1470,29 +1475,19 @@ static int __init init_zswap(void)
        if (ret)
                goto hp_fail;
 
-       pool = __zswap_pool_create_fallback();
-       if (pool) {
-               pr_info("loaded using pool %s/%s\n", pool->tfm_name,
-                       zpool_get_type(pool->zpool));
-               list_add(&pool->list, &zswap_pools);
-               zswap_has_pool = true;
-       } else {
-               pr_err("pool creation failed\n");
-               zswap_enabled = false;
-       }
-
        shrink_wq = create_workqueue("zswap-shrink");
        if (!shrink_wq)
-               goto fallback_fail;
+               goto hp_fail;
 
        frontswap_register_ops(&zswap_frontswap_ops);
        if (zswap_debugfs_init())
                pr_warn("debugfs initialization failed\n");
+
+       if (zswap_enabled)
+               zswap_try_pool_create();
+
        return 0;
 
-fallback_fail:
-       if (pool)
-               zswap_pool_destroy(pool);
 hp_fail:
        cpuhp_remove_state(CPUHP_MM_ZSWP_MEM_PREPARE);
 dstmem_fail: