From patchwork Thu Mar 28 14:03:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uladzislau Rezki X-Patchwork-Id: 13608607 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 86B71C54E67 for ; Thu, 28 Mar 2024 14:05:08 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id E16956B0085; Thu, 28 Mar 2024 10:05:07 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id DC6896B0087; Thu, 28 Mar 2024 10:05:07 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C8DF66B0088; Thu, 28 Mar 2024 10:05:07 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id A4B386B0085 for ; Thu, 28 Mar 2024 10:05:07 -0400 (EDT) Received: from smtpin30.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id 41F0C1406FF for ; Thu, 28 Mar 2024 14:05:07 +0000 (UTC) X-FDA: 81946619454.30.C12D108 Received: from mail-lf1-f47.google.com (mail-lf1-f47.google.com [209.85.167.47]) by imf26.hostedemail.com (Postfix) with ESMTP id 0553714020E for ; Thu, 28 Mar 2024 14:03:34 +0000 (UTC) Authentication-Results: imf26.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=cy0sfdQG; spf=pass (imf26.hostedemail.com: domain of urezki@gmail.com designates 209.85.167.47 as permitted sender) smtp.mailfrom=urezki@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1711634615; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:references:dkim-signature; bh=CT8V/kdc5WB0TlbNcLxd5k9ElfIfxe6B6M2YsC8jwN0=; b=SOSRV+gScFyjKD3t5p4ZnsiRuGiJcKVbZadS4zFynGg/sGqoqaoNWWLBrJY2K87RKMIT9n 8CotZMnHR3c0M3Ym58acTYhnMashmD0z9XCLgmLUUL3yynuqRfEfAxb5o+kxviMIltJWFn pcMA6cL3D9JOe2Vu0uRN6uHR8eBkYcw= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1711634615; a=rsa-sha256; cv=none; b=i/uOvSPm3QO7oxUzR4xpga/uGo0Kr1J35pXVsw1PXC46DFDy7A6fBTglo1qAerP+ajkrJa akAubZLZRbeiN8e+5HYhgVDHONj8mb4LYW4uLSCpnb1XuxSpSpJSfFTnyPbkob3rm20dDH ko4Fy2+qkzfElpQbGLx/b3328/srn78= ARC-Authentication-Results: i=1; imf26.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=cy0sfdQG; spf=pass (imf26.hostedemail.com: domain of urezki@gmail.com designates 209.85.167.47 as permitted sender) smtp.mailfrom=urezki@gmail.com; dmarc=pass (policy=none) header.from=gmail.com Received: by mail-lf1-f47.google.com with SMTP id 2adb3069b0e04-515b3077d09so1047534e87.1 for ; Thu, 28 Mar 2024 07:03:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1711634613; x=1712239413; darn=kvack.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=CT8V/kdc5WB0TlbNcLxd5k9ElfIfxe6B6M2YsC8jwN0=; b=cy0sfdQGSfRU5DOoUi8251vyX7SBym+6QRwaq68JR5Q/05UbIJXr7drCRgt4efnyAw f1/KWkhw5vZQxmdmmXxiPvGMOovSIBQUoOgHpX9sonLYDXgsl7xnHnPorcZXrsISh4eG 5yv1McQaTH0Ph9d+nDAUNJyeTAfxl0am1/pUkONOD/MFGsH95iKK8Hs8QQKkkHzAsQC0 SGZI3OKpkgy0PPJpOEIUNZtJVSq71H+AR6ArYFaqp/yT3enfqqkhQxBdk50moD4fpN6E 2YI8phx2X/bzYFRfaY/Gvv0t8onZZZamAOFTLk3KWtFz9TE4k6UyMuVPcz74rXq3Tmew I+YA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711634613; x=1712239413; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=CT8V/kdc5WB0TlbNcLxd5k9ElfIfxe6B6M2YsC8jwN0=; b=oTHp7HhfaMr+WfcmJL8KxoKmbWya87W/U/uiR/HdhQ2VEvtIEnqoH9PZtMLk9TuMNu 20UH/O75vvlBi1OyS9KgognOQOBuH60JpKLR9vbqgEanaxq0fw7GIE3BIuvK7Pz1x+Sq 85c8VSGlpzsP2lhabL+z0LcwglI7l+pzJBSauC+A58lyfdGUbVorfN0tl/3lWMBk4fLw LXR4y7IDNd8NaeoOEAb4Hj6v+SV8oCn2pikTJ0aA8e/ctRcE7tPR7pbEKNS2ESOyC9N9 fyeZz26RrdWIBRE7Ly2Sy/SLDvoMgoXRBmn6TrxTIUt7kHgOjMUR8WeOVfmKsPyJuLge uUoQ== X-Gm-Message-State: AOJu0YxZFTXpTgyMMLQsZ480+FeXZlNIqtjKEi8rYJU2hItwYbQ82dB2 /ytJo0hY2fxNY8AoK1aowbWwuES/6Mhi8TmmwUn6ypp12GFpj42jnf2yZ1IV X-Google-Smtp-Source: AGHT+IFyy/sTknXNnqXo3qvpynipBRIV+fdDh3Ha8NkvdICnl6zBVEGiRqQMVGRtOenfauY1oMWr8Q== X-Received: by 2002:a05:6512:478:b0:515:920e:eedb with SMTP id x24-20020a056512047800b00515920eeedbmr2349894lfd.39.1711634612800; Thu, 28 Mar 2024 07:03:32 -0700 (PDT) Received: from pc638.lan (host-185-121-47-193.sydskane.nu. [185.121.47.193]) by smtp.gmail.com with ESMTPSA id q26-20020ac25a1a000000b00513da68c536sm221607lfn.152.2024.03.28.07.03.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Mar 2024 07:03:32 -0700 (PDT) From: "Uladzislau Rezki (Sony)" To: linux-mm@kvack.org, Andrew Morton Cc: LKML , Baoquan He , Lorenzo Stoakes , Christoph Hellwig , Matthew Wilcox , Dave Chinner , Uladzislau Rezki , Oleksiy Avramchenko , Jens Axboe , Omar Sandoval Subject: [PATCH 1/1] mm: vmalloc: Fix lockdep warning Date: Thu, 28 Mar 2024 15:03:30 +0100 Message-Id: <20240328140330.4747-1-urezki@gmail.com> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 X-Stat-Signature: m3f1g6bkjaq7sqrg3nebmiteypxrhk5d X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: 0553714020E X-Rspam-User: X-HE-Tag: 1711634614-278643 X-HE-Meta: U2FsdGVkX1/BCwkPLDW8EXTJz/HESH1QKe7W8JXuc/DeVVGixJil6Bcg9apt4ZLpoxaLmC/DlgEfDImKykqXtT8w+zTAuGu1IprkBVVzPELn46HOojDA1eFqFoh2VsvQEXTFZYqgGmXXQqoT1OZ8qkr4QzOj2d44VwxoWPpxtcQXAsxKaW3kX8aarcdbF5Y9VQDil2lPyoQltdoWfRhIYuF1UBKLLXSI/lE11qF17+d7gc9cMaDPY5S8vQ76IPkE/IoEG/2dKcJUsXHoS9bO3GwuSRe+EgH4i26a73jWZ6KfdhMJi3dmB6FBMHmapRcgkb+VbVOwpUGEHyCAzJvzOMnYSJEFseF55dxUYWrm2iM5sn5qT5/8KU4jsKNq+FT7e20fiSMU4jcZjIHhn3XqJRIUGgQjR0SwwNpT6X8xATQ+eIz0YKVW+BO1sacADP0UNN0mKMY5GNZaosNPbK/wmfz8sYyswe9dmAgU9Jn4mncS3Ksbke2RTtOklM6cjDJ2OwA1rSfGIscVfZ9UzjxmHtMKP5gvfzlWF63mb9AreOk2cnBKygByyvnpyYFU44jg2rEaGIvPBXOeV8ESymCYfQ31+QfyEHi1G0tlMetkY6JO9xj3BPkRxMkoIuEr7OtPUNc1Kunf8WE2VUW5ZoyZ2ooOHTL+jZY/W9K3y0/i8n7lu1I2Pk9Hx7/0ryMET0ovNaJ3YB7TUXwAbv2Dn3o5jipkxhbvRNaC6/Vc7FWFhF8nvlBhStaheoXFgY5niAdV/M3dDLIavWdS/j3INTKZwrgc53iSxdsVPh5JjVIkTHfh9NwQXXgz8fKuplIOSe7Vy+tMD2bg+X6JEeao6kVy5xIx6990OJRMl1Xgjb8Mo+6ayi3kyp7pIiJzKI3CWajkHh84lqSIL/hprZaBj/iz+Mjot8Ebo/tbyhPAhDsegWyX43PPeDs+AaiI4CzV4ZJS1egEPsyx72LBKktJ6WF pJvDeeKu MYAwWWGMOL75ko1huJlmqQn5KbA0FFtvoXWHNRVq5JF3EJSVhXxE8nosb9krAqHptiK/eoRRoOLYUyoDfbCFib4keSCsoXzyngFznDEDEnBHIGOTWFOt5pK6hOPifybMiFkObZ/eNWheBkkn2XF5My9drMqF1GBv4nNdeJNSYxV7PFcCRIN3zG1UIubt4Bu6IFGaZt6e5/CnQhsUUvpeNkG/YYa5obQyrD+TUkmtiC+yN0NyW3nCnFGt3K3saMOhndPqh+yVEvelH49cb0WrjBzLEdPvisDxtBhri8uyN7qVamMBTtouUY70E8mN23rwDMxN2qM+XtYP93qgfsAECzGhXV5abQbNRNaEVCJXLKc5XyJUsABdwWrGeuksNcBiH9hPyUKI2zgpChYtnWRg1uwR/UhXIwdgWLuvqJnwyY/+KbsLOYAizsgnaV5ZTvpV9MNAkS9ptZclTNvzse/z+Uy+Kh7nZ3rxaMk9rTdnXYYQHmzvQpb2OOvR+BNWjaDQsnNGl X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: A lockdep reports a possible deadlock in the find_vmap_area_exceed_addr_lock() function: ============================================ WARNING: possible recursive locking detected 6.9.0-rc1-00060-ged3ccc57b108-dirty #6140 Not tainted -------------------------------------------- drgn/455 is trying to acquire lock: ffff0000c00131d0 (&vn->busy.lock/1){+.+.}-{2:2}, at: find_vmap_area_exceed_addr_lock+0x64/0x124 but task is already holding lock: ffff0000c0011878 (&vn->busy.lock/1){+.+.}-{2:2}, at: find_vmap_area_exceed_addr_lock+0x64/0x124 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&vn->busy.lock/1); lock(&vn->busy.lock/1); *** DEADLOCK *** indeed it can happen if the find_vmap_area_exceed_addr_lock() gets called concurrently because it tries to acquire two nodes locks. It was done to prevent removing a lowest VA found on a previous step. To address this a lowest VA is found first without holding a node lock where it resides. As a last step we check if a VA still there because it can go away, if removed, proceed with next lowest. Fixes: 53becf32aec1 ("mm: vmalloc: support multiple nodes in vread_iter") Tested-by: Jens Axboe Tested-by: Omar Sandoval Reported-by: Jens Axboe Signed-off-by: Uladzislau Rezki (Sony) Reviewed-by: Baoquan He --- mm/vmalloc.c | 74 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index e94ce4562805..a5a5dfc3843e 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -989,6 +989,27 @@ unsigned long vmalloc_nr_pages(void) return atomic_long_read(&nr_vmalloc_pages); } +static struct vmap_area *__find_vmap_area(unsigned long addr, struct rb_root *root) +{ + struct rb_node *n = root->rb_node; + + addr = (unsigned long)kasan_reset_tag((void *)addr); + + while (n) { + struct vmap_area *va; + + va = rb_entry(n, struct vmap_area, rb_node); + if (addr < va->va_start) + n = n->rb_left; + else if (addr >= va->va_end) + n = n->rb_right; + else + return va; + } + + return NULL; +} + /* Look up the first VA which satisfies addr < va_end, NULL if none. */ static struct vmap_area * __find_vmap_area_exceed_addr(unsigned long addr, struct rb_root *root) @@ -1025,47 +1046,40 @@ __find_vmap_area_exceed_addr(unsigned long addr, struct rb_root *root) static struct vmap_node * find_vmap_area_exceed_addr_lock(unsigned long addr, struct vmap_area **va) { - struct vmap_node *vn, *va_node = NULL; - struct vmap_area *va_lowest; + unsigned long va_start_lowest; + struct vmap_node *vn; int i; - for (i = 0; i < nr_vmap_nodes; i++) { +repeat: + for (i = 0, va_start_lowest = 0; i < nr_vmap_nodes; i++) { vn = &vmap_nodes[i]; spin_lock(&vn->busy.lock); - va_lowest = __find_vmap_area_exceed_addr(addr, &vn->busy.root); - if (va_lowest) { - if (!va_node || va_lowest->va_start < (*va)->va_start) { - if (va_node) - spin_unlock(&va_node->busy.lock); - - *va = va_lowest; - va_node = vn; - continue; - } - } + *va = __find_vmap_area_exceed_addr(addr, &vn->busy.root); + + if (*va) + if (!va_start_lowest || (*va)->va_start < va_start_lowest) + va_start_lowest = (*va)->va_start; spin_unlock(&vn->busy.lock); } - return va_node; -} - -static struct vmap_area *__find_vmap_area(unsigned long addr, struct rb_root *root) -{ - struct rb_node *n = root->rb_node; + /* + * Check if found VA exists, it might it is gone away. + * In this case we repeat the search because a VA has + * been removed concurrently thus we need to proceed + * with next one what is a rare case. + */ + if (va_start_lowest) { + vn = addr_to_node(va_start_lowest); - addr = (unsigned long)kasan_reset_tag((void *)addr); + spin_lock(&vn->busy.lock); + *va = __find_vmap_area(va_start_lowest, &vn->busy.root); - while (n) { - struct vmap_area *va; + if (*va) + return vn; - va = rb_entry(n, struct vmap_area, rb_node); - if (addr < va->va_start) - n = n->rb_left; - else if (addr >= va->va_end) - n = n->rb_right; - else - return va; + spin_unlock(&vn->busy.lock); + goto repeat; } return NULL;