[Devel] [PATCH RHEL9 COMMIT] blk-cbt: disable interrupts before this_cpu_ptr() call

Konstantin Khorenko khorenko at virtuozzo.com
Thu Jul 28 14:35:22 MSK 2022


The commit is pushed to "branch-rh9-5.14.0-70.13.1.vz9.16.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh9-5.14.0-70.13.1.vz9.16.5
------>
commit 8eb5c2ab513e06f86e1c65f3cc87c2f1533e8825
Author: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Date:   Thu Jun 23 11:49:43 2022 +0300

    blk-cbt: disable interrupts before this_cpu_ptr() call
    
    We see a BUG on vz9 debug kernel:
    
      BUG: using smp_processor_id() in preemptible [00000000] code: ...
      caller is blk_cbt_add+0x16e/0x3c0
      CPU: 1 PID: 10076 Comm: systemd-journal ve:
        4e2fb160-9b05-4d4e-b7bd-a6bc7238c6da Kdump:
        loaded Not tainted 5.14.0-70.13.1.vz9.16.5+debug #1 16.5
      Hardware name: GIGABYTE H252-Z10-00/MZ12-HD0-00, BIOS F01 03/05/2020
      Call Trace:
       dump_stack_lvl+0x57/0x7d
       check_preemption_disabled+0xc8/0xd0
       blk_cbt_add+0x16e/0x3c0
       ...
    
    comming from blk_cbt_add->this_cpu_ptr->my_cpu_offset->smp_processor_id.
    
    According to Documentation/locking/preempt-locking.rst:
    "It is possible to prevent a preemption event using local_irq_disable..."
    so we just need to move this_cpu_ptr down under local_irq_disable
    to fix the BUG.
    
    Note: alternatively we could probably use get_cpu_var/put_cpu_var here.
    
    https://jira.sw.ru/browse/PSBM-140699
    Fixes: 777e2825461a ("cbt: introduce changed block tracking")
    
    Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 block/blk-cbt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block/blk-cbt.c b/block/blk-cbt.c
index e8eee11a87ba..43a51446eafa 100644
--- a/block/blk-cbt.c
+++ b/block/blk-cbt.c
@@ -236,8 +236,8 @@ static void blk_cbt_add(struct request_queue *q, blkcnt_t start, blkcnt_t len)
 		__blk_cbt_set(cbt, start, len, 1, 1, NULL, NULL);
 		goto out_rcu;
 	}
-	ex = this_cpu_ptr(cbt->cache);
 	local_irq_disable();
+	ex = this_cpu_ptr(cbt->cache);
 	if (ex->start + ex->len == start) {
 		ex->len += len;
 		local_irq_enable();


More information about the Devel mailing list