Patch "mm/zsmalloc.c: close race window between zs_pool_dec_isolated() and zs_unregister_migration()" has been added to the 4.14-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    mm/zsmalloc.c: close race window between zs_pool_dec_isolated() and zs_unregister_migration()

to the 4.14-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     mm-zsmalloc.c-close-race-window-between-zs_pool_dec_.patch
and it can be found in the queue-4.14 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 23eabaf9aa087caf41cb3f98ed2b864333dfea32
Author: Miaohe Lin <linmiaohe@xxxxxxxxxx>
Date:   Fri Nov 5 13:45:03 2021 -0700

    mm/zsmalloc.c: close race window between zs_pool_dec_isolated() and zs_unregister_migration()
    
    [ Upstream commit afe8605ca45424629fdddfd85984b442c763dc47 ]
    
    There is one possible race window between zs_pool_dec_isolated() and
    zs_unregister_migration() because wait_for_isolated_drain() checks the
    isolated count without holding class->lock and there is no order inside
    zs_pool_dec_isolated().  Thus the below race window could be possible:
    
      zs_pool_dec_isolated          zs_unregister_migration
        check pool->destroying != 0
                                      pool->destroying = true;
                                      smp_mb();
                                      wait_for_isolated_drain()
                                        wait for pool->isolated_pages == 0
        atomic_long_dec(&pool->isolated_pages);
        atomic_long_read(&pool->isolated_pages) == 0
    
    Since we observe the pool->destroying (false) before atomic_long_dec()
    for pool->isolated_pages, waking pool->migration_wait up is missed.
    
    Fix this by ensure checking pool->destroying happens after the
    atomic_long_dec(&pool->isolated_pages).
    
    Link: https://lkml.kernel.org/r/20210708115027.7557-1-linmiaohe@xxxxxxxxxx
    Fixes: 701d678599d0 ("mm/zsmalloc.c: fix race condition in zs_destroy_pool")
    Signed-off-by: Miaohe Lin <linmiaohe@xxxxxxxxxx>
    Cc: Minchan Kim <minchan@xxxxxxxxxx>
    Cc: Sergey Senozhatsky <senozhatsky@xxxxxxxxxxxx>
    Cc: Henry Burns <henryburns@xxxxxxxxxx>
    Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
index 633ebcac82f8d..6cdb49ae00010 100644
--- a/mm/zsmalloc.c
+++ b/mm/zsmalloc.c
@@ -1901,10 +1901,11 @@ static inline void zs_pool_dec_isolated(struct zs_pool *pool)
 	VM_BUG_ON(atomic_long_read(&pool->isolated_pages) <= 0);
 	atomic_long_dec(&pool->isolated_pages);
 	/*
-	 * There's no possibility of racing, since wait_for_isolated_drain()
-	 * checks the isolated count under &class->lock after enqueuing
-	 * on migration_wait.
+	 * Checking pool->destroying must happen after atomic_long_dec()
+	 * for pool->isolated_pages above. Paired with the smp_mb() in
+	 * zs_unregister_migration().
 	 */
+	smp_mb__after_atomic();
 	if (atomic_long_read(&pool->isolated_pages) == 0 && pool->destroying)
 		wake_up_all(&pool->migration_wait);
 }



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux