From patchwork Fri Aug 8 01:47:05 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Filipe Manana X-Patchwork-Id: 4693141 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.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 2E1F7C0338 for ; Fri, 8 Aug 2014 00:47:44 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2D24C2017A for ; Fri, 8 Aug 2014 00:47:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 30BF02010F for ; Fri, 8 Aug 2014 00:47:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755337AbaHHAri (ORCPT ); Thu, 7 Aug 2014 20:47:38 -0400 Received: from victor.provo.novell.com ([137.65.250.26]:40099 "EHLO victor.provo.novell.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755330AbaHHArh (ORCPT ); Thu, 7 Aug 2014 20:47:37 -0400 Received: from debian-vm3.lan (prv-ext-foundry1int.gns.novell.com [137.65.251.240]) by victor.provo.novell.com with ESMTP (NOT encrypted); Thu, 07 Aug 2014 18:47:28 -0600 From: Filipe Manana To: linux-btrfs@vger.kernel.org Cc: Filipe Manana Subject: [PATCH] Btrfs: don't monopolize a core when evicting inode Date: Fri, 8 Aug 2014 02:47:05 +0100 Message-Id: <1407462426-6420-1-git-send-email-fdmanana@suse.com> X-Mailer: git-send-email 1.9.1 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-7.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, 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 If an inode has a very large number of extent maps, we can spend a lot of time freeing them, which triggers a soft lockup warning. Therefore reschedule if we need to when freeing the extent maps while evicting the inode. I could trigger this all the time by running xfstests/generic/299 on a file system with the no-holes feature enabled. That test creates an inode with 11386677 extent maps. $ mkfs.btrfs -f -O no-holes $TEST_DEV $ MKFS_OPTIONS="-O no-holes" ./check generic/299 generic/299 382s ... Message from syslogd@debian-vm3 at Aug 7 10:44:29 ... kernel:[85304.208017] BUG: soft lockup - CPU#0 stuck for 22s! [umount:25330] 384s Ran: generic/299 Passed all 1 tests $ dmesg (...) [86304.300017] BUG: soft lockup - CPU#0 stuck for 23s! [umount:25330] (...) [86304.300036] Call Trace: [86304.300036] [] __slab_free+0x54/0x295 [86304.300036] [] ? free_extent_map+0x5c/0xb0 [btrfs] [86304.300036] [] kmem_cache_free+0x282/0x2a0 [86304.300036] [] free_extent_map+0x5c/0xb0 [btrfs] [86304.300036] [] btrfs_evict_inode+0xd5/0x660 [btrfs] [86304.300036] [] ? __inode_wait_for_writeback+0x6d/0xc0 [86304.300036] [] ? _raw_spin_unlock+0x2b/0x40 [86304.300036] [] evict+0xab/0x180 [86304.300036] [] dispose_list+0x3e/0x60 [86304.300036] [] evict_inodes+0xf4/0x110 [86304.300036] [] generic_shutdown_super+0x53/0x110 [86304.300036] [] kill_anon_super+0x16/0x30 [86304.300036] [] btrfs_kill_super+0x1a/0xa0 [btrfs] [86304.300036] [] deactivate_locked_super+0x59/0x80 [86304.300036] [] deactivate_super+0x4e/0x70 [86304.300036] [] mntput_no_expire+0x174/0x1f0 [86304.300036] [] ? mntput_no_expire+0x17/0x1f0 [86304.300036] [] SyS_umount+0x97/0x100 (...) Signed-off-by: Filipe Manana Reviewed-by: Satoru Takeuchi Tested-by: Satoru Takeuchi --- fs/btrfs/inode.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8ad3ea9..00b4bd3 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -4718,6 +4718,11 @@ static void evict_inode_truncate_pages(struct inode *inode) clear_bit(EXTENT_FLAG_LOGGING, &em->flags); remove_extent_mapping(map_tree, em); free_extent_map(em); + if (need_resched()) { + write_unlock(&map_tree->lock); + cond_resched(); + write_lock(&map_tree->lock); + } } write_unlock(&map_tree->lock); @@ -4740,6 +4745,7 @@ static void evict_inode_truncate_pages(struct inode *inode) &cached_state, GFP_NOFS); free_extent_state(state); + cond_resched(); spin_lock(&io_tree->lock); } spin_unlock(&io_tree->lock);