Re: [PATCH] loop: Fix NULL pointer dereference by synchronizing lo_release and loop_queue_rq

From: Tetsuo Handa

Date: Mon May 11 2026 - 13:44:00 EST


Thank you for responding.

Given it is protected by RCU, this might be yet another manifestation of
"is trying to release lock (rcu_read_lock) at:" + "but there are no more locks to release!"-type of
hidden RCU imbalance bugs recently introduced? Andrew, was any progress made for RCU imbalance bugs?

On 2026/04/21 20:05, Tetsuo Handa wrote:
> Since this problem started after the merge window opened, the culprit commit
> might be in between commit a028739a4330 ("Merge tag 'block-7.0-20260305' of
> git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux") and
> commit 7fe6ac157b7e ("Merge tag 'for-7.1/block-20260411' of
> git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux").
> Also, syzbot was not testing changes in linux-next since next-20260403,
> and found this problem in next-20260413.

On 2026/05/12 0:58, Bart Van Assche wrote:
> Why SRCU instead of RCU? The loop driver doesn't set BLK_MQ_F_BLOCKING
> and hence must not sleep inside loop_queue_rq(). Additionally, the block
> layer already holds an RCU lock around all loop_queue_rq() calls. From
> block/blk-mq.h:
>
> /* run the code block in @dispatch_ops with rcu/srcu read lock held */
> #define __blk_mq_run_dispatch_ops(q, check_sleep, dispatch_ops)    \
> do {                                \
>     if ((q)->tag_set->flags & BLK_MQ_F_BLOCKING) {        \
>         struct blk_mq_tag_set *__tag_set = (q)->tag_set; \
>         int srcu_idx;                    \
>                                 \
>         might_sleep_if(check_sleep);            \
>         srcu_idx = srcu_read_lock(__tag_set->srcu);    \
>         (dispatch_ops);                    \
>         srcu_read_unlock(__tag_set->srcu, srcu_idx);    \
>     } else {                        \
>         rcu_read_lock();                \
>         (dispatch_ops);                    \
>         rcu_read_unlock();                \
>     }                            \
> } while (0)