Patch "riscv: Disable preemption while handling PR_RISCV_CTX_SW_FENCEI_OFF" has been added to the 6.10-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

    riscv: Disable preemption while handling PR_RISCV_CTX_SW_FENCEI_OFF

to the 6.10-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:
     riscv-disable-preemption-while-handling-pr_riscv_ctx.patch
and it can be found in the queue-6.10 subdirectory.

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



commit 3db126dcdd5dee7030c9cd2a9062cce5842a88ff
Author: Charlie Jenkins <charlie@xxxxxxxxxxxx>
Date:   Tue Sep 3 15:52:34 2024 -0700

    riscv: Disable preemption while handling PR_RISCV_CTX_SW_FENCEI_OFF
    
    [ Upstream commit 7c1e5b9690b0e14acead4ff98d8a6c40f2dff54b ]
    
    The icache will be flushed in switch_to() if force_icache_flush is true,
    or in flush_icache_deferred() if icache_stale_mask is set. Between
    setting force_icache_flush to false and calculating the new
    icache_stale_mask, preemption needs to be disabled. There are two
    reasons for this:
    
    1. If CPU migration happens between force_icache_flush = false, and the
       icache_stale_mask is set, an icache flush will not be emitted.
    2. smp_processor_id() is used in set_icache_stale_mask() to mark the
       current CPU as not needing another flush since a flush will have
       happened either by userspace or by the kernel when performing the
       migration. smp_processor_id() is currently called twice with preemption
       enabled which causes a race condition. It allows
       icache_stale_mask to be populated with inconsistent CPU ids.
    
    Resolve these two issues by setting the icache_stale_mask before setting
    force_icache_flush to false, and using get_cpu()/put_cpu() to obtain the
    smp_processor_id().
    
    Signed-off-by: Charlie Jenkins <charlie@xxxxxxxxxxxx>
    Fixes: 6b9391b581fd ("riscv: Include riscv_set_icache_flush_ctx prctl")
    Link: https://lore.kernel.org/r/20240903-fix_fencei_optimization-v2-1-8025f20171fc@xxxxxxxxxxxx
    Signed-off-by: Palmer Dabbelt <palmer@xxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c
index a03c994eed3b..b81672729887 100644
--- a/arch/riscv/mm/cacheflush.c
+++ b/arch/riscv/mm/cacheflush.c
@@ -158,6 +158,7 @@ void __init riscv_init_cbo_blocksizes(void)
 #ifdef CONFIG_SMP
 static void set_icache_stale_mask(void)
 {
+	int cpu = get_cpu();
 	cpumask_t *mask;
 	bool stale_cpu;
 
@@ -168,10 +169,11 @@ static void set_icache_stale_mask(void)
 	 * concurrently on different harts.
 	 */
 	mask = &current->mm->context.icache_stale_mask;
-	stale_cpu = cpumask_test_cpu(smp_processor_id(), mask);
+	stale_cpu = cpumask_test_cpu(cpu, mask);
 
 	cpumask_setall(mask);
-	cpumask_assign_cpu(smp_processor_id(), mask, stale_cpu);
+	cpumask_assign_cpu(cpu, mask, stale_cpu);
+	put_cpu();
 }
 #endif
 
@@ -239,14 +241,12 @@ int riscv_set_icache_flush_ctx(unsigned long ctx, unsigned long scope)
 	case PR_RISCV_CTX_SW_FENCEI_OFF:
 		switch (scope) {
 		case PR_RISCV_SCOPE_PER_PROCESS:
-			current->mm->context.force_icache_flush = false;
-
 			set_icache_stale_mask();
+			current->mm->context.force_icache_flush = false;
 			break;
 		case PR_RISCV_SCOPE_PER_THREAD:
-			current->thread.force_icache_flush = false;
-
 			set_icache_stale_mask();
+			current->thread.force_icache_flush = false;
 			break;
 		default:
 			return -EINVAL;




[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