From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA7D547CC71 for ; Tue, 30 Jun 2026 19:09:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.133 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782846550; cv=none; b=bqdYGlz18eNUDi4Epn2JrcD3k1v5zEp7k06Wg5KwoFACfkIOCt+YlSH77E2ShH+B/4+ROTXmsSuMKxI9bGz+2z8LBLeOTGEeWuajjm6ueswBGbvjfsHENwiUhGPEH2ryZgYfNKxRWddgAid427SkbzrMV2jAzin2Di2Vd2DTNFE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782846550; c=relaxed/simple; bh=DaAEV9D30ZscJVpm2M0Bsu8I96hecdUSjO3OO7CR6vM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KxVxR8VzNSS/YSgKwyw1h3bqlnPignAH0FHljN+k83v4IQyYB/1v/cUA3PcOECZIvhXSz4Tler1WaWq3IPLukHxu0/FspHW4W1BeO3ymI1LW++JoNbaeeoZd6Y+OMcF18h3zC294BxuGf+UjuLQeX0hmyfwMTfun3VxfYCUx5VA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=pass smtp.mailfrom=infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=RKh0kJj7; arc=none smtp.client-ip=198.137.202.133 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="RKh0kJj7" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=0kaHdhZZieDrrxJiHdXSNOC3F/Y8uD5iXdhmdi4dH0M=; b=RKh0kJj79M15Qw8NbUKDxSJoZc 9OMktzlqvb6Dcdxmyfu3/Yxy8VCu80gGyQZERYzhY/H2rHThtuK4epGjhp/KdYACYxcAICNRWu9/y XyxprKCX2jeFm72+DNLCVr4zwZV1NQekLdmU3BlLq76p8WKFrIMAk0Ui1NJzBbkwXSCgDbqUCXfrt vCtemZvPOaIon6POEZXySYA9hZgKsJ4DFLp4fn+/+5ip00N67L3kPsosjqvyX+4bH5SIRn6ctq2om /W97HebRJ2V/nEaag1+VGX+GFtxZVMKfcR1ICtlUac8bDyGe4SUmB3Hm6MElnmtZhet0hxHp0diLM Kd8bppuQ==; Received: from [38.23.173.23] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.99.1 #2 (Red Hat Linux)) id 1wedpT-000000005xp-1SMI; Tue, 30 Jun 2026 19:09:08 +0000 From: "Liam R. Howlett (Oracle)" To: Andrew Morton Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, maple-tree@lists.infradead.org, "Liam R. Howlett (Oracle)" , Chris Mason , Chuck Lever Subject: [PATCH v2 12/19] maple_tree: Catch race in mas_alloc_cyclic() Date: Tue, 30 Jun 2026 15:08:36 -0400 Message-ID: <20260630190843.3563858-13-liam@infradead.org> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260630190843.3563858-1-liam@infradead.org> References: <20260630190843.3563858-1-liam@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit If mas_alloc_cyclic() is called during a low memory situation, it is possible the lock may be dropped so reclaim can occur. There is a window where some other task may allocate the same id and cause the mas_insert() to fail with -EEXIST. In this scenario the function will return -EEXIST, which is not expected. Modifying the retry on mas_nomem() to re-search for a slot means that any race with other writes will not matter as the lock will be held between finding the index and writing the index. Moving the flag logic avoids cases where the flag is modified on drop lock/reacquire or when the write fails after clearing the flag. No existing users are exposed to this issue. Fixes: 9b6713cc75229 ("maple_tree: Add mtree_alloc_cyclic()") Reported-by: Chris Mason Cc: Chuck Lever Signed-off-by: Liam R. Howlett (Oracle) --- lib/maple_tree.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 768193406c3db..1bc177bf42f9f 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -3867,35 +3867,40 @@ int mas_alloc_cyclic(struct ma_state *mas, unsigned long *startp, void *entry, unsigned long range_lo, unsigned long range_hi, unsigned long *next, gfp_t gfp) { - unsigned long min = range_lo; - int ret = 0; - - range_lo = max(min, *next); - ret = mas_empty_area(mas, range_lo, range_hi, 1); - if ((mas->tree->ma_flags & MT_FLAGS_ALLOC_WRAPPED) && ret == 0) { - mas->tree->ma_flags &= ~MT_FLAGS_ALLOC_WRAPPED; - ret = 1; - } - if (ret < 0 && range_lo > min) { - mas_reset(mas); - ret = mas_empty_area(mas, min, range_hi, 1); - if (ret == 0) - ret = 1; - } - if (ret < 0) - return ret; + int ret; + unsigned long min; + min = range_lo; do { + range_lo = max(min, *next); + ret = mas_empty_area(mas, range_lo, range_hi, 1); + if (ret < 0 && range_lo > min) { + mas_reset(mas); + ret = mas_empty_area(mas, min, range_hi, 1); + if (ret == 0) + ret = 1; + } + if (ret < 0) + goto out; + mas_insert(mas, entry); } while (mas_nomem(mas, gfp)); - if (mas_is_err(mas)) - return xa_err(mas->node); + if (mas_is_err(mas)) { + ret = xa_err(mas->node); + goto out; + } + + if ((mas->tree->ma_flags & MT_FLAGS_ALLOC_WRAPPED) && ret == 0) { + mas->tree->ma_flags &= ~MT_FLAGS_ALLOC_WRAPPED; + ret = 1; + } *startp = mas->index; *next = *startp + 1; if (*next == 0) mas->tree->ma_flags |= MT_FLAGS_ALLOC_WRAPPED; +out: mas_destroy(mas); return ret; } -- 2.47.3