diff options
| author | Jianpeng Ma <majianpeng@gmail.com> | 2013-07-03 13:25:24 +0200 | 
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2013-07-03 13:25:24 +0200 | 
| commit | d50235b7bc3ee0a0427984d763ea7534149531b4 (patch) | |
| tree | acf1916e7926c1a0dddbe08db11ca2426a3816cc /fs/btrfs/compression.c | |
| parent | a6b3f7614ca690e49e934c291f707b0c19312194 (diff) | |
elevator: Fix a race in elevator switching
There's a race between elevator switching and normal io operation.
    Because the allocation of struct elevator_queue and struct elevator_data
    don't in a atomic operation.So there are have chance to use NULL
    ->elevator_data.
    For example:
        Thread A:                               Thread B
        blk_queu_bio                            elevator_switch
        spin_lock_irq(q->queue_block)           elevator_alloc
        elv_merge                               elevator_init_fn
    Because call elevator_alloc, it can't hold queue_lock and the
    ->elevator_data is NULL.So at the same time, threadA call elv_merge and
    nedd some info of elevator_data.So the crash happened.
    Move the elevator_alloc into func elevator_init_fn, it make the
    operations in a atomic operation.
    Using the follow method can easy reproduce this bug
    1:dd if=/dev/sdb of=/dev/null
    2:while true;do echo noop > scheduler;echo deadline > scheduler;done
    The test method also use this method.
Signed-off-by: Jianpeng Ma <majianpeng@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/btrfs/compression.c')
0 files changed, 0 insertions, 0 deletions
