aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/zswap.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/mm/zswap.c b/mm/zswap.c
index de0f119b1780..275b22cc8df4 100644
--- a/mm/zswap.c
+++ b/mm/zswap.c
@@ -117,7 +117,7 @@ struct zswap_pool {
117 struct crypto_comp * __percpu *tfm; 117 struct crypto_comp * __percpu *tfm;
118 struct kref kref; 118 struct kref kref;
119 struct list_head list; 119 struct list_head list;
120 struct rcu_head rcu_head; 120 struct work_struct work;
121 struct notifier_block notifier; 121 struct notifier_block notifier;
122 char tfm_name[CRYPTO_MAX_ALG_NAME]; 122 char tfm_name[CRYPTO_MAX_ALG_NAME];
123}; 123};
@@ -658,9 +658,11 @@ static int __must_check zswap_pool_get(struct zswap_pool *pool)
658 return kref_get_unless_zero(&pool->kref); 658 return kref_get_unless_zero(&pool->kref);
659} 659}
660 660
661static void __zswap_pool_release(struct rcu_head *head) 661static void __zswap_pool_release(struct work_struct *work)
662{ 662{
663 struct zswap_pool *pool = container_of(head, typeof(*pool), rcu_head); 663 struct zswap_pool *pool = container_of(work, typeof(*pool), work);
664
665 synchronize_rcu();
664 666
665 /* nobody should have been able to get a kref... */ 667 /* nobody should have been able to get a kref... */
666 WARN_ON(kref_get_unless_zero(&pool->kref)); 668 WARN_ON(kref_get_unless_zero(&pool->kref));
@@ -680,7 +682,9 @@ static void __zswap_pool_empty(struct kref *kref)
680 WARN_ON(pool == zswap_pool_current()); 682 WARN_ON(pool == zswap_pool_current());
681 683
682 list_del_rcu(&pool->list); 684 list_del_rcu(&pool->list);
683 call_rcu(&pool->rcu_head, __zswap_pool_release); 685
686 INIT_WORK(&pool->work, __zswap_pool_release);
687 schedule_work(&pool->work);
684 688
685 spin_unlock(&zswap_pools_lock); 689 spin_unlock(&zswap_pools_lock);
686} 690}