map_release() are not atomic, because it calls atomic_read and atomic_dec_and_test. Looks like it was designed to be called under plo->lock.
https://jira.sw.ru/browse/PSBM-23905 Signed-off-by: Andrey Vagin <ava...@openvz.org> Acked-by: Maxim Patlasov <mpatla...@parallels.com> --- drivers/block/ploop/dev.c | 6 ++++++ drivers/block/ploop/map.c | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/drivers/block/ploop/dev.c b/drivers/block/ploop/dev.c index 353fb35..e3422d8 100644 --- a/drivers/block/ploop/dev.c +++ b/drivers/block/ploop/dev.c @@ -1471,12 +1471,14 @@ static int prepare_merge_req(struct ploop_request * preq) return res; drop_map: + spin_lock_irq(&plo->lock); map_release(preq->trans_map); preq->trans_map = NULL; if (preq->map) { map_release(preq->map); preq->map = NULL; } + spin_unlock_irq(&plo->lock); return 1; } @@ -1688,8 +1690,10 @@ ploop_entry_reloc_a_req(struct ploop_request *preq, iblock_t *iblk) if (*clu <= MAP_MAX_IND(preq)) break; + spin_lock_irq(&plo->lock); map_release(preq->map); preq->map = NULL; + spin_unlock_irq(&plo->lock); } if (*clu >= plo->map.max_index) { @@ -1814,8 +1818,10 @@ static int discard_get_index(struct ploop_request *preq) preq->iblock = 0; if (preq->map) { + spin_lock_irq(&plo->lock); map_release(preq->map); preq->map = NULL; + spin_unlock_irq(&plo->lock); } return 0; diff --git a/drivers/block/ploop/map.c b/drivers/block/ploop/map.c index 5f50f81..2e971cd 100644 --- a/drivers/block/ploop/map.c +++ b/drivers/block/ploop/map.c @@ -145,6 +145,10 @@ static void flush_lru_buffer(struct ploop_map * map) map->lru_buffer_ptr = 0; } +/* + * map_release() must be called under plo-lock, because + * The pair atomic_read & atomic_dec_and_test is not atomic. + */ void map_release(struct map_node * m) { struct ploop_map * map = m->parent; @@ -1026,9 +1030,11 @@ static void map_wb_complete_post_process(struct ploop_map *map, } if (test_bit(PLOOP_REQ_RELOC_S, &preq->state)) { + spin_lock_irq(&plo->lock); del_lockout(preq); map_release(preq->map); preq->map = NULL; + spin_unlock_irq(&plo->lock); requeue_req(preq, PLOOP_E_RELOC_COMPLETE); return; -- 1.9.3 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel