mirror of
https://github.com/brain-hackers/linux-brain.git
synced 2024-06-09 23:36:23 +09:00
lightnvm: pblk: fix two sleep-in-atomic-context bugs
[ Upstream commit 7325b4bbe5
]
The driver may sleep with holding a spinlock.
The function call paths (from bottom to top) in Linux-4.16 are:
[FUNC] nvm_dev_dma_alloc(GFP_KERNEL)
drivers/lightnvm/pblk-core.c, 754:
nvm_dev_dma_alloc in pblk_line_submit_smeta_io
drivers/lightnvm/pblk-core.c, 1048:
pblk_line_submit_smeta_io in pblk_line_init_bb
drivers/lightnvm/pblk-core.c, 1434:
pblk_line_init_bb in pblk_line_replace_data
drivers/lightnvm/pblk-recovery.c, 980:
pblk_line_replace_data in pblk_recov_l2p
drivers/lightnvm/pblk-recovery.c, 976:
spin_lock in pblk_recov_l2p
[FUNC] bio_map_kern(GFP_KERNEL)
drivers/lightnvm/pblk-core.c, 762:
bio_map_kern in pblk_line_submit_smeta_io
drivers/lightnvm/pblk-core.c, 1048:
pblk_line_submit_smeta_io in pblk_line_init_bb
drivers/lightnvm/pblk-core.c, 1434:
pblk_line_init_bb in pblk_line_replace_data
drivers/lightnvm/pblk-recovery.c, 980:
pblk_line_replace_data in pblk_recov_l2p
drivers/lightnvm/pblk-recovery.c, 976:
spin_lock in pblk_recov_l2p
To fix these bugs, the call to pblk_line_replace_data()
is moved out of the spinlock protection.
These bugs are found by my static analysis tool DSAC.
Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com>
Reviewed-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <mb@lightnvm.io>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
d16cd14ea3
commit
47f2932860
|
@ -1001,12 +1001,14 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
|
|||
}
|
||||
}
|
||||
|
||||
spin_lock(&l_mg->free_lock);
|
||||
if (!open_lines) {
|
||||
spin_lock(&l_mg->free_lock);
|
||||
WARN_ON_ONCE(!test_and_clear_bit(meta_line,
|
||||
&l_mg->meta_bitmap));
|
||||
spin_unlock(&l_mg->free_lock);
|
||||
pblk_line_replace_data(pblk);
|
||||
} else {
|
||||
spin_lock(&l_mg->free_lock);
|
||||
/* Allocate next line for preparation */
|
||||
l_mg->data_next = pblk_line_get(pblk);
|
||||
if (l_mg->data_next) {
|
||||
|
@ -1014,8 +1016,8 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
|
|||
l_mg->data_next->type = PBLK_LINETYPE_DATA;
|
||||
is_next = 1;
|
||||
}
|
||||
spin_unlock(&l_mg->free_lock);
|
||||
}
|
||||
spin_unlock(&l_mg->free_lock);
|
||||
|
||||
if (is_next) {
|
||||
pblk_line_erase(pblk, l_mg->data_next);
|
||||
|
|
Loading…
Reference in New Issue
Block a user