Skip to content

Commit b33b6fd

Browse files
author
Mike Snitzer
committed
dm bufio: simplify DM_BUFIO_CLIENT_NO_SLEEP locking
Historically none of the bufio code runs in interrupt context but with the use of DM_BUFIO_CLIENT_NO_SLEEP a bufio client can, see: commit 5721d4e ("dm verity: Add optional "try_verify_in_tasklet" feature") That said, the new tasklet usecase still doesn't require interrupts be disabled by bufio (let alone conditionally restore them). Yet with PREEMPT_RT, and falling back from tasklet to workqueue, care must be taken to properly synchronize between softirq and process context, otherwise ABBA deadlock may occur. While it is unnecessary to disable bottom-half preemption within a tasklet, we must consistently do so in process context to ensure locking is in the proper order. Fix these issues by switching from spin_lock_irq{save,restore} to using spin_{lock,unlock}_bh instead. Also remove the 'spinlock_flags' member in dm_bufio_client struct (that can be used unsafely if bufio must recurse on behalf of some caller, e.g. block layer's submit_bio). Fixes: 5721d4e ("dm verity: Add optional "try_verify_in_tasklet" feature") Reported-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
1 parent 12907ef commit b33b6fd

1 file changed

Lines changed: 4 additions & 6 deletions

File tree

drivers/md/dm-bufio.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
struct dm_bufio_client {
8484
struct mutex lock;
8585
spinlock_t spinlock;
86-
unsigned long spinlock_flags;
86+
bool no_sleep;
8787

8888
struct list_head lru[LIST_SIZE];
8989
unsigned long n_buffers[LIST_SIZE];
@@ -93,8 +93,6 @@ struct dm_bufio_client {
9393
s8 sectors_per_block_bits;
9494
void (*alloc_callback)(struct dm_buffer *);
9595
void (*write_callback)(struct dm_buffer *);
96-
bool no_sleep;
97-
9896
struct kmem_cache *slab_buffer;
9997
struct kmem_cache *slab_cache;
10098
struct dm_io_client *dm_io;
@@ -174,23 +172,23 @@ static DEFINE_STATIC_KEY_FALSE(no_sleep_enabled);
174172
static void dm_bufio_lock(struct dm_bufio_client *c)
175173
{
176174
if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep)
177-
spin_lock_irqsave_nested(&c->spinlock, c->spinlock_flags, dm_bufio_in_request());
175+
spin_lock_bh(&c->spinlock);
178176
else
179177
mutex_lock_nested(&c->lock, dm_bufio_in_request());
180178
}
181179

182180
static int dm_bufio_trylock(struct dm_bufio_client *c)
183181
{
184182
if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep)
185-
return spin_trylock_irqsave(&c->spinlock, c->spinlock_flags);
183+
return spin_trylock_bh(&c->spinlock);
186184
else
187185
return mutex_trylock(&c->lock);
188186
}
189187

190188
static void dm_bufio_unlock(struct dm_bufio_client *c)
191189
{
192190
if (static_branch_unlikely(&no_sleep_enabled) && c->no_sleep)
193-
spin_unlock_irqrestore(&c->spinlock, c->spinlock_flags);
191+
spin_unlock_bh(&c->spinlock);
194192
else
195193
mutex_unlock(&c->lock);
196194
}

0 commit comments

Comments
 (0)