From patchwork Sat Jul 11 10:45:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uladzislau Rezki X-Patchwork-Id: 11657847 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 62589618 for ; Sat, 11 Jul 2020 10:45:43 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 2DDF92065D for ; Sat, 11 Jul 2020 10:45:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gdMH0hkL" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2DDF92065D Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 21A576B0003; Sat, 11 Jul 2020 06:45:42 -0400 (EDT) Delivered-To: linux-mm-outgoing@kvack.org Received: by kanga.kvack.org (Postfix, from userid 40) id 1A4FF6B0005; Sat, 11 Jul 2020 06:45:42 -0400 (EDT) X-Original-To: int-list-linux-mm@kvack.org X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 06C2F6B0006; Sat, 11 Jul 2020 06:45:42 -0400 (EDT) X-Original-To: linux-mm@kvack.org X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0023.hostedemail.com [216.40.44.23]) by kanga.kvack.org (Postfix) with ESMTP id DD7D96B0003 for ; Sat, 11 Jul 2020 06:45:41 -0400 (EDT) Received: from smtpin07.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id 7F3C6181AC9CC for ; Sat, 11 Jul 2020 10:45:41 +0000 (UTC) X-FDA: 77025464082.07.slave77_2a1003e26ed6 Received: from filter.hostedemail.com (10.5.16.251.rfc1918.com [10.5.16.251]) by smtpin07.hostedemail.com (Postfix) with ESMTP id 59E5F1803F9AC for ; Sat, 11 Jul 2020 10:45:41 +0000 (UTC) X-Spam-Summary: 1,0,0,fb739597ebc51f32,d41d8cd98f00b204,urezki@gmail.com,,RULES_HIT:41:355:379:541:800:960:966:968:973:988:989:1260:1311:1314:1345:1437:1515:1535:1544:1605:1711:1730:1747:1777:1792:2196:2199:2393:2559:2562:2892:2898:2902:3138:3139:3140:3141:3142:3865:3866:3867:3868:3870:3871:3872:3874:4118:4250:4321:4385:4605:5007:6261:6653:7514:7875:7903:9413:10004:11026:11232:11658:11914:12043:12291:12296:12297:12438:12517:12519:12555:12683:12895:13095:13191:13192:13229:13894:14181:14394:14687:14721:21080:21324:21433:21444:21451:21627:21666:21939:21987:21990:30054:30070:30075,0,RBL:209.85.208.194:@gmail.com:.lbl8.mailshell.net-66.100.201.100 62.18.0.100;04yfdju6n6rr4gcrfiabkn7nxparkypnpkrn11zk6qxics5xq3sc6pnjnjz4qd8.u7tzwcrncx9ddbhdrs6gpyy51t8rns54txjqsdd4puippgxzskfy9eghkpjboeh.r-lbl8.mailshell.net-223.238.255.100,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fp,MSBL:0,DNSBL:neutral,Custom_rules:0:0:0,LFtime:25,LUA_SUMMARY:none X-HE-Tag: slave77_2a1003e26ed6 X-Filterd-Recvd-Size: 7880 Received: from mail-lj1-f194.google.com (mail-lj1-f194.google.com [209.85.208.194]) by imf37.hostedemail.com (Postfix) with ESMTP for ; Sat, 11 Jul 2020 10:45:40 +0000 (UTC) Received: by mail-lj1-f194.google.com with SMTP id e4so9206578ljn.4 for ; Sat, 11 Jul 2020 03:45:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=emwwLZ+sCVD9pQmKI5z9zIDSKav8YuxNbGB01XFmDw0=; b=gdMH0hkLsBg0LeQOOg3ir0y6Tfe16Uu5JTXMt0cZx6rK441QuK8rcV44Is/IGa5Qma PeMixu1wonnYnNZjV7772dnDf/rhXDYpVQxVA+H/mCezZvxOLJMN/5Wew3O/78zdPOVE bNXS6zlh2v0FYRMNbwhqj4LMVCZRXPG4ktGtV9jLHab4q+2kybrkHXjqjU9xHJm4FEhB 3qi6hUOik5HAxXB77C9VCK8Epv05znRjLrERi5AlYmva3T9LksPwiaW9JqI7T0K2Y8GL Ms+UlPLKakDDkjeTYEQ0dBuD6SBo1nZ12wp0vS9V2hkZN4afx2OaIS0hBz26OilFFcc0 RzCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=emwwLZ+sCVD9pQmKI5z9zIDSKav8YuxNbGB01XFmDw0=; b=rGZJ2nh09nTnbdv0x7oudJ8wPgImhqPxDH8p6LbX/GT1GsGBY+T//jsP4TGAc2HkRy DBHBVJ8OJDCIKJJngSARuWbUcSG2YHc4C1TeObhVoHWkl+0+NE43xQZDPEXNuNJeheuN 3HFSvFoQOhvT2NARH5PhVd0PRHVy+zzUT3ibo/KFDiMMoGwhWEY6zLbrLeq5fjFtDL1q sbTArtxXkfj7L5oAbBmuQapJTBQ/qD7qEQz/2i0JUqWcs3mh1E8yIPH6ZMWRFEdCdjQl SF9XmWRkXG+Ogrjqze4s7Ztg04xKSMLPRyfS3IccWxLy576u9Fq9SZXCbjBt/avZ5T9T sLEA== X-Gm-Message-State: AOAM532jbsM4AakIaEHSn4QhVE82TEqfTapS89YQwpFaLV7xTQSx6JYo u/Cwv3mzgXNtTdRcH0KbaWI= X-Google-Smtp-Source: ABdhPJys3VA5gh+UJ5rF9Pab2KKItVlJCxPddT9fMYWk524rqNVig7B+s52+EA2DA8nYPnO08vMTYQ== X-Received: by 2002:a2e:888d:: with SMTP id k13mr13080218lji.15.1594464339354; Sat, 11 Jul 2020 03:45:39 -0700 (PDT) Received: from pc638.lan (h5ef52e31.seluork.dyn.perspektivbredband.net. [94.245.46.49]) by smtp.gmail.com with ESMTPSA id m25sm2689233ljj.128.2020.07.11.03.45.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 11 Jul 2020 03:45:38 -0700 (PDT) From: "Uladzislau Rezki (Sony)" To: Andrew Morton Cc: linux-mm@kvack.org, LKML , Uladzislau Rezki , Hillf Danton , Michal Hocko , Matthew Wilcox , Oleksiy Avramchenko , Steven Rostedt Subject: [PATCH v3 1/1] mm/vmalloc.c: Remove BUG() from the find_va_links() Date: Sat, 11 Jul 2020 12:45:31 +0200 Message-Id: <20200711104531.12242-1-urezki@gmail.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 X-Rspamd-Queue-Id: 59E5F1803F9AC X-Spamd-Result: default: False [0.00 / 100.00] X-Rspamd-Server: rspam04 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: Get rid of BUG() macro, that should be used only when a critical situation happens and a system is not able to function anymore. Replace it with WARN() macro instead, dump some extra information about start/end addresses of both VAs which overlap. Such overlap data can help to figure out what happened making further analysis easier. For example if both areas are identical it could mean a double free. A recovery process consists of declining all further steps regarding inserting of conflicting overlap range. In that sense find_va_links() now can return NULL, so its return value has to be checked by callers. Side effect of such process is it can leak memory, but it is better than just killing a machine for no good reason. Apart of that a debugging process can be done on alive system. v2 -> v3 - rename the patch's title; - remove information about pointers; - convert BUG() to WARN() macros; - add "vmalloc bug:" prefix to the message; - add recovery process if an overlap occurs; - add more comments. Signed-off-by: Uladzislau Rezki (Sony) --- mm/vmalloc.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 3d7b94eb0ac0..b482d240f9a2 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -512,6 +512,10 @@ static struct vmap_area *__find_vmap_area(unsigned long addr) /* * This function returns back addresses of parent node * and its left or right link for further processing. + * + * Otherwise NULL is returned. In that case all further + * steps regarding inserting of conflicting overlap range + * have to be declined and actually considered as a bug. */ static __always_inline struct rb_node ** find_va_links(struct vmap_area *va, @@ -550,8 +554,12 @@ find_va_links(struct vmap_area *va, else if (va->va_end > tmp_va->va_start && va->va_start >= tmp_va->va_end) link = &(*link)->rb_right; - else - BUG(); + else { + WARN(1, "vmalloc bug: 0x%lx-0x%lx overlaps with 0x%lx-0x%lx\n", + va->va_start, va->va_end, tmp_va->va_start, tmp_va->va_end); + + return NULL; + } } while (*link); *parent = &tmp_va->rb_node; @@ -697,7 +705,8 @@ insert_vmap_area(struct vmap_area *va, struct rb_node *parent; link = find_va_links(va, root, NULL, &parent); - link_va(va, root, parent, link, head); + if (link) + link_va(va, root, parent, link, head); } static void @@ -713,8 +722,10 @@ insert_vmap_area_augment(struct vmap_area *va, else link = find_va_links(va, root, NULL, &parent); - link_va(va, root, parent, link, head); - augment_tree_propagate_from(va); + if (link) { + link_va(va, root, parent, link, head); + augment_tree_propagate_from(va); + } } /* @@ -722,6 +733,11 @@ insert_vmap_area_augment(struct vmap_area *va, * and next free blocks. If coalesce is not done a new * free area is inserted. If VA has been merged, it is * freed. + * + * Please note, it can return NULL in case of overlap + * ranges, followed by WARN() report. Despite it is a + * buggy behaviour, a system can be alive and keep + * ongoing. */ static __always_inline struct vmap_area * merge_or_add_vmap_area(struct vmap_area *va, @@ -738,6 +754,8 @@ merge_or_add_vmap_area(struct vmap_area *va, * inserted, unless it is merged with its sibling/siblings. */ link = find_va_links(va, root, NULL, &parent); + if (!link) + return NULL; /* * Get next node of VA to check if merging can be done. @@ -1346,6 +1364,9 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) va = merge_or_add_vmap_area(va, &free_vmap_area_root, &free_vmap_area_list); + if (!va) + continue; + if (is_vmalloc_or_module_addr((void *)orig_start)) kasan_release_vmalloc(orig_start, orig_end, va->va_start, va->va_end); @@ -3330,8 +3351,9 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, orig_end = vas[area]->va_end; va = merge_or_add_vmap_area(vas[area], &free_vmap_area_root, &free_vmap_area_list); - kasan_release_vmalloc(orig_start, orig_end, - va->va_start, va->va_end); + if (va) + kasan_release_vmalloc(orig_start, orig_end, + va->va_start, va->va_end); vas[area] = NULL; } @@ -3379,8 +3401,9 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, orig_end = vas[area]->va_end; va = merge_or_add_vmap_area(vas[area], &free_vmap_area_root, &free_vmap_area_list); - kasan_release_vmalloc(orig_start, orig_end, - va->va_start, va->va_end); + if (va) + kasan_release_vmalloc(orig_start, orig_end, + va->va_start, va->va_end); vas[area] = NULL; kfree(vms[area]); }