Patch "dma-debug: fix a possible deadlock on radix_lock" has been added to the 6.1-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

    dma-debug: fix a possible deadlock on radix_lock

to the 6.1-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:
     dma-debug-fix-a-possible-deadlock-on-radix_lock.patch
and it can be found in the queue-6.1 subdirectory.

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



commit 4ac4b5d45f45d29397e1b19cbe244b13d8a5dd46
Author: Levi Yun <yeoreum.yun@xxxxxxx>
Date:   Fri Oct 25 11:06:00 2024 +0100

    dma-debug: fix a possible deadlock on radix_lock
    
    [ Upstream commit 7543c3e3b9b88212fcd0aaf5cab5588797bdc7de ]
    
    radix_lock() shouldn't be held while holding dma_hash_entry[idx].lock
    otherwise, there's a possible deadlock scenario when
    dma debug API is called holding rq_lock():
    
    CPU0                   CPU1                       CPU2
    dma_free_attrs()
    check_unmap()          add_dma_entry()            __schedule() //out
                                                      (A) rq_lock()
    get_hash_bucket()
    (A) dma_entry_hash
                                                      check_sync()
                           (A) radix_lock()           (W) dma_entry_hash
    dma_entry_free()
    (W) radix_lock()
                           // CPU2's one
                           (W) rq_lock()
    
    CPU1 situation can happen when it extending radix tree and
    it tries to wake up kswapd via wake_all_kswapd().
    
    CPU2 situation can happen while perf_event_task_sched_out()
    (i.e. dma sync operation is called while deleting perf_event using
     etm and etr tmc which are Arm Coresight hwtracing driver backends).
    
    To remove this possible situation, call dma_entry_free() after
    put_hash_bucket() in check_unmap().
    
    Reported-by: Denis Nikitin <denik@xxxxxxxxxxxx>
    Closes: https://lists.linaro.org/archives/list/coresight@xxxxxxxxxxxxxxxx/thread/2WMS7BBSF5OZYB63VT44U5YWLFP5HL6U/#RWM6MLQX5ANBTEQ2PRM7OXCBGCE6NPWU
    Signed-off-by: Levi Yun <yeoreum.yun@xxxxxxx>
    Signed-off-by: Christoph Hellwig <hch@xxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c
index de02c0808fb83..3e6f2a39beb3b 100644
--- a/kernel/dma/debug.c
+++ b/kernel/dma/debug.c
@@ -1044,9 +1044,13 @@ static void check_unmap(struct dma_debug_entry *ref)
 	}
 
 	hash_bucket_del(entry);
-	dma_entry_free(entry);
-
 	put_hash_bucket(bucket, flags);
+
+	/*
+	 * Free the entry outside of bucket_lock to avoid ABBA deadlocks
+	 * between that and radix_lock.
+	 */
+	dma_entry_free(entry);
 }
 
 static void check_for_stack(struct device *dev,




[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