summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2014-04-08 11:29:01 +0100
committerMike Snitzer <snitzer@redhat.com>2014-04-08 10:18:35 -0400
commitb10ebd34cccae1b431caf1be54919aede2be7cbe (patch)
treef8f848169991555d7ea0719740da37645e405c99 /kernel
parent5e3283e2920a0bd8a806964d80274b8756e0dd7f (diff)
downloadlinux-b10ebd34cccae1b431caf1be54919aede2be7cbe.tar.bz2
dm thin: fix rcu_read_lock being held in code that can sleep
Commit c140e1c4e23 ("dm thin: use per thin device deferred bio lists") introduced the use of an rculist for all active thin devices. The use of rcu_read_lock() in process_deferred_bios() can result in a BUG if a dm_bio_prison_cell must be allocated as a side-effect of bio_detain(): BUG: sleeping function called from invalid context at mm/mempool.c:203 in_atomic(): 1, irqs_disabled(): 0, pid: 6, name: kworker/u8:0 3 locks held by kworker/u8:0/6: #0: ("dm-" "thin"){.+.+..}, at: [<ffffffff8106be42>] process_one_work+0x192/0x550 #1: ((&pool->worker)){+.+...}, at: [<ffffffff8106be42>] process_one_work+0x192/0x550 #2: (rcu_read_lock){.+.+..}, at: [<ffffffff816360b5>] do_worker+0x5/0x4d0 We can't process deferred bios with the rcu lock held, since dm_bio_prison_cell allocation may block if the bio-prison's cell mempool is exhausted. To fix: - Introduce a refcount and completion field to each thin_c - Add thin_get/put methods for adjusting the refcount. If the refcount hits zero then the completion is triggered. - Initialise refcount to 1 when creating thin_c - When iterating the active_thins list we thin_get() whilst the rcu lock is held. - After the rcu lock is dropped we process the deferred bios for that thin. - When destroying a thin_c we thin_put() and then wait for the completion -- to avoid a race between the worker thread iterating from that thin_c and destroying the thin_c. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'kernel')
0 files changed, 0 insertions, 0 deletions