[Devel] [PATCH RHEL9 COMMIT] blk-cbt: Use irq{save, restore} version of the spinlock in blk_cbt_release()

Konstantin Khorenko khorenko at virtuozzo.com
Tue Mar 7 20:44:35 MSK 2023


The commit is pushed to "branch-rh9-5.14.0-162.6.1.vz9.18.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh9-5.14.0-162.6.1.vz9.18.12
------>
commit e0d8d87d0d5fe9d867901f0c68151b8b52ee5dfb
Author: Konstantin Khorenko <khorenko at virtuozzo.com>
Date:   Fri Mar 3 18:51:57 2023 +0300

    blk-cbt: Use irq{save,restore} version of the spinlock in blk_cbt_release()
    
    blk_cbt_release() can be called both from soft irq and from
    non-interrupt context, so spin_lock should be used with irqsave.
    
    Example of the call from softirq context (taken from google):
    
     blk_release_queue
      kobject_cleanup
       kobject_put
        blk_put_queue
         blkg_free
          __blkg_release
           rcu_do_batch
            rcu_core
             rcu_core_si
              __do_softirq
    
    blk_cbt_release() is called by the blk_release_queue()
    which is the .release() callback of struct kobj_type.
    
    Example of the call from non-irq context:
    
    blk_cbt_release
     cbt_ioc_stop (even mutex is taken there => non-irq context)
      blk_cbt_ioctl
       blkdev_ioctl
        block_ioctl
    
    Fixes: ea18c5e9d2ba ("cbt: introduce changed block tracking")
    
    Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
---
 block/blk-cbt.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/block/blk-cbt.c b/block/blk-cbt.c
index a7abf5b8c044..b78ea8fd4608 100644
--- a/block/blk-cbt.c
+++ b/block/blk-cbt.c
@@ -672,15 +672,16 @@ void blk_cbt_release(struct request_queue *q)
 {
 	struct cbt_info *cbt;
 	int in_use = 0;
+	unsigned long flags;
 
 	cbt = q->cbt;
 	if (!cbt)
 		return;
-	spin_lock(&cbt->lock);
+	spin_lock_irqsave(&cbt->lock, flags);
 	set_bit(CBT_DEAD, &cbt->flags);
 	rcu_assign_pointer(q->cbt, NULL);
 	in_use = cbt->count;
-	spin_unlock(&cbt->lock);
+	spin_unlock_irqrestore(&cbt->lock, flags);
 	if (!in_use)
 		call_rcu(&cbt->rcu, &cbt_release_callback);
 }


More information about the Devel mailing list