From patchwork Tue Jul 18 17:25:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 9849221 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 4D24A60392 for ; Tue, 18 Jul 2017 17:25:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 30D26285BD for ; Tue, 18 Jul 2017 17:25:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 25D30285CB; Tue, 18 Jul 2017 17:25:55 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 571DA285BD for ; Tue, 18 Jul 2017 17:25:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751715AbdGRRZw (ORCPT ); Tue, 18 Jul 2017 13:25:52 -0400 Received: from bombadil.infradead.org ([65.50.211.133]:39977 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751787AbdGRRZu (ORCPT ); Tue, 18 Jul 2017 13:25:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=Message-Id:Date:Subject:To:From: Sender:Reply-To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=AcsOahHDYPFrfh3MrPUtciNTRHJT/pteYJCLh3bJ1IE=; b=DmNAortOxUb/HgcKAztamURfr mz1RneWb12KLM1SgoFQbQq6OWlH9C2108ucGCNs/YiJDhDL0I/LD185fcu0BnteXgiEwMq11alx2U GynNfYkwNoJI5PJIa9E3N0EhbwZWNP6B2YqJSjwwhZbpbRkymHOUa9v8TuBliWeoypTonx3giMpGK NYY7gwBKmXoOhRKBlz4qmedqwO0+i0tHELO1wRCRdSJd6zzsP69A7PJbjwB0X7qrzfUsG+Br8y2ot 47/umlrarqfJzf90LIwi5wu09Y9Rkl/+HJ3U/O5iCir/m+9RjRkdf9x1fwO3kuTZa+BfL6Ji21+GK OCmsigZ1w==; Received: from clnet-p099-196.ikbnet.co.at ([83.175.99.196] helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.87 #1 (Red Hat Linux)) id 1dXWFp-0008Fb-5I; Tue, 18 Jul 2017 17:25:49 +0000 From: Christoph Hellwig To: n.borisov.lkml@gmail.com, linux-xfs@vger.kernel.org Subject: [PATCH, RFC] xfs: fix multi-AG deadlock in xfs_bunmapi Date: Tue, 18 Jul 2017 19:25:45 +0200 Message-Id: <20170718172545.18065-1-hch@lst.de> X-Mailer: git-send-email 2.11.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Just like in the allocator we must avoid touching multiple AGs out of order when freeing blocks, as freeing still locks the AGF and can cause the same AB-BA deadlocks as in the allocation path. Signed-off-by: Christoph Hellwig Reported-by: Nikolay Borisov Reviewed-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 0a9880777c9c..935adde72a8b 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -5435,6 +5435,7 @@ __xfs_bunmapi( xfs_fsblock_t sum; xfs_filblks_t len = *rlen; /* length to unmap in file */ xfs_fileoff_t max_len; + xfs_agnumber_t prev_agno = NULLAGNUMBER, agno; trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); @@ -5534,6 +5535,17 @@ __xfs_bunmapi( */ del = got; wasdel = isnullstartblock(del.br_startblock); + + /* + * Make sure we don't touch multiple AGF headers out of order + * in a single transaction, as that could cause AB-BA deadlocks. + */ + if (!wasdel) { + agno = XFS_FSB_TO_AGNO(mp, del.br_startblock); + if (prev_agno != NULLAGNUMBER && prev_agno > agno) + break; + prev_agno = agno; + } if (got.br_startoff < start) { del.br_startoff = start; del.br_blockcount -= start - got.br_startoff;