From patchwork Tue Feb 24 16:51:32 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Sterba X-Patchwork-Id: 5874251 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 24491BF440 for ; Tue, 24 Feb 2015 16:51:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id AE24D201FE for ; Tue, 24 Feb 2015 16:51:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A2B4B20145 for ; Tue, 24 Feb 2015 16:51:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753378AbbBXQve (ORCPT ); Tue, 24 Feb 2015 11:51:34 -0500 Received: from cantor2.suse.de ([195.135.220.15]:44654 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753250AbbBXQve (ORCPT ); Tue, 24 Feb 2015 11:51:34 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 28BDFADBA for ; Tue, 24 Feb 2015 16:51:33 +0000 (UTC) Received: by ds.suse.cz (Postfix, from userid 10065) id D2169DA85C; Tue, 24 Feb 2015 17:51:32 +0100 (CET) From: David Sterba To: linux-btrfs@vger.kernel.org Cc: David Sterba Subject: [PATCH 1/4] btrfs: add missing barriers before waitqueue_active Date: Tue, 24 Feb 2015 17:51:32 +0100 Message-Id: <17483cf32d53059bb3e6aa1662fe2f35727829bc.1424795734.git.dsterba@suse.cz> X-Mailer: git-send-email 2.1.3 In-Reply-To: References: Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The waitqueue might miss a wakeup due to memory ordering issues, the explicit barrier is required unless there's an implicit one. Signed-off-by: David Sterba --- fs/btrfs/dev-replace.c | 9 ++++++++- fs/btrfs/raid56.c | 17 ++++++++++++----- fs/btrfs/transaction.c | 5 ++++- fs/btrfs/tree-log.c | 8 ++++++++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 5ec03d999c37..30b8668396e0 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -451,6 +451,10 @@ static void btrfs_rm_dev_replace_blocked(struct btrfs_fs_info *fs_info) static void btrfs_rm_dev_replace_unblocked(struct btrfs_fs_info *fs_info) { clear_bit(BTRFS_FS_STATE_DEV_REPLACING, &fs_info->fs_state); + /* + * Make sure counter is updated before we wake up waiters. + */ + smp_mb(); if (waitqueue_active(&fs_info->replace_wait)) wake_up(&fs_info->replace_wait); } @@ -916,7 +920,10 @@ void btrfs_bio_counter_inc_noblocked(struct btrfs_fs_info *fs_info) void btrfs_bio_counter_sub(struct btrfs_fs_info *fs_info, s64 amount) { percpu_counter_sub(&fs_info->bio_counter, amount); - + /* + * Make sure counter is updated before we wake up waiters. + */ + smp_mb(); if (waitqueue_active(&fs_info->replace_wait)) wake_up(&fs_info->replace_wait); } diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index 5264858ed768..b460e193f324 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c @@ -809,11 +809,18 @@ static noinline void unlock_stripe(struct btrfs_raid_bio *rbio) } goto done_nolock; - } else if (waitqueue_active(&h->wait)) { - spin_unlock(&rbio->bio_list_lock); - spin_unlock_irqrestore(&h->lock, flags); - wake_up(&h->wait); - goto done_nolock; + } else { + /* + * Make sure counter is updated before we wake up + * waiters. + */ + smp_mb(); + if (waitqueue_active(&h->wait)) { + spin_unlock(&rbio->bio_list_lock); + spin_unlock_irqrestore(&h->lock, flags); + wake_up(&h->wait); + goto done_nolock; + } } } done: diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 038fcf6051e0..90ba0c3c3d0d 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -90,8 +90,11 @@ static void clear_btree_io_tree(struct extent_io_tree *tree) /* * btree io trees aren't supposed to have tasks waiting for * changes in the flags of extent states ever. + * + * Barrier required to make sure counter is updated before we + * wake up waiters. */ - ASSERT(!waitqueue_active(&state->wq)); + ASSERT(({ smp_mb(); !waitqueue_active(&state->wq); })); free_extent_state(state); if (need_resched()) { spin_unlock(&tree->lock); diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index f96996a1b70c..121df0fe5128 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -2739,6 +2739,10 @@ out_wake_log_root: atomic_set(&log_root_tree->log_commit[index2], 0); mutex_unlock(&log_root_tree->log_mutex); + /* + * Make sure counter is updated before we wake up waiters. + */ + smp_mb(); if (waitqueue_active(&log_root_tree->log_commit_wait[index2])) wake_up(&log_root_tree->log_commit_wait[index2]); out: @@ -2750,6 +2754,10 @@ out: atomic_set(&root->log_commit[index1], 0); mutex_unlock(&root->log_mutex); + /* + * Make sure counter is updated before we wake up waiters. + */ + smp_mb(); if (waitqueue_active(&root->log_commit_wait[index1])) wake_up(&root->log_commit_wait[index1]); return ret;