summaryrefslogtreecommitdiff
path: root/scripts/objdiff
diff options
context:
space:
mode:
authorShaohua Li <shli@fb.com>2017-08-25 10:40:02 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-10-05 09:41:44 +0200
commitd03d1567866e8015db3b7cc706c3659deba500de (patch)
treef073eafbe26b6f4b16e8e1e9d4d75fa0cb2e3e79 /scripts/objdiff
parent68a4a52899187a8411374b861ae1fed78302fab8 (diff)
md/raid5: fix a race condition in stripe batch
commit 3664847d95e60a9a943858b7800f8484669740fc upstream. We have a race condition in below scenario, say have 3 continuous stripes, sh1, sh2 and sh3, sh1 is the stripe_head of sh2 and sh3: CPU1 CPU2 CPU3 handle_stripe(sh3) stripe_add_to_batch_list(sh3) -> lock(sh2, sh3) -> lock batch_lock(sh1) -> add sh3 to batch_list of sh1 -> unlock batch_lock(sh1) clear_batch_ready(sh1) -> lock(sh1) and batch_lock(sh1) -> clear STRIPE_BATCH_READY for all stripes in batch_list -> unlock(sh1) and batch_lock(sh1) ->clear_batch_ready(sh3) -->test_and_clear_bit(STRIPE_BATCH_READY, sh3) --->return 0 as sh->batch == NULL -> sh3->batch_head = sh1 -> unlock (sh2, sh3) In CPU1, handle_stripe will continue handle sh3 even it's in batch stripe list of sh1. By moving sh3->batch_head assignment in to batch_lock, we make it impossible to clear STRIPE_BATCH_READY before batch_head is set. Thanks Stephane for helping debug this tricky issue. Reported-and-tested-by: Stephane Thiell <sthiell@stanford.edu> Signed-off-by: Shaohua Li <shli@fb.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'scripts/objdiff')
0 files changed, 0 insertions, 0 deletions