Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp2483305imm; Mon, 24 Sep 2018 05:16:17 -0700 (PDT) X-Google-Smtp-Source: ACcGV60n2P1aPxHD+n3WIwNNDmGZh2uKhe16/UD8z4Px1JKlnZYeZDkbwyuD5B7aesN6BdH1q5HO X-Received: by 2002:a65:5286:: with SMTP id y6-v6mr9117175pgp.65.1537791376900; Mon, 24 Sep 2018 05:16:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1537791376; cv=none; d=google.com; s=arc-20160816; b=ZBE57WhGBu2Xvg1GRts6A2c07pvIgm6u44qfE01dh6+kYto4VShFHlavLWXLi4jA0x jXwKIDJWJtj+Q2KFLrDsPGwAvr2vYsMq/CFG24IucrqXo6Zc2CVH4BtW8fiLPTPYFqlx 2rtEoxvDCz8iMsy55EEO5ZVDkMzVgK57rwAI9Zp8Tr8aUCTwd0FALoroakQs2imqnAru 5hjjVw400n3m7qOAZ46zI7A1mm3d+L86ZuwEGiXxU+gVyp60zwB6kMoGS5InBCK+5waN srxi9MqNfeKbMBAyZUZG5gD8Xgz5cUNvHvF8UYwsruxeApCxBNWcZP13YDHI7g922wnR uPmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from; bh=t+b1Vzx2dl1Uucd3NOe3PK0Gqri/AQ3wpjmkzrLtvnM=; b=zGXdM5Ipnfncpoponyi1W0AlF86eXRedw0ixXWg+jWdAmyAPz3h/k6WvrlxQdWrhik sz49nsWxqGufp7jL1o7cyyPi2zM1htgCE1cm9kXrYngNVD3u9VNBMPhVTIoetFKJBg8O 8Q5inPjDVE9ghbPdovZJSJU0jv4TWE8wF+koQAPXJuhBZW6r7ZXNhu+NsOz+R0JXi195 9YM71Yu32zb1gQMtrx5aUF3jM9qv+jzbyjxCun+PhEqeNZQlI4CgWdYN4KAsRp9v5C2+ e7GCU7hqXbLRheFtGBKtLsS4gx0f0m0oTAPiViDP3v56kwTfT78heJSD00qbQpi+dKfm y79A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 32-v6si10340362plh.374.2018.09.24.05.16.01; Mon, 24 Sep 2018 05:16:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731719AbeIXSPu (ORCPT + 99 others); Mon, 24 Sep 2018 14:15:50 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:55322 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729561AbeIXSPu (ORCPT ); Mon, 24 Sep 2018 14:15:50 -0400 Received: from localhost (ip-213-127-77-73.ip.prioritytelecom.net [213.127.77.73]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 60923109C; Mon, 24 Sep 2018 12:13:59 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Jiri Olsa , Namhyung Kim , Alexander Shishkin , Andi Kleen , David Ahern , Kan Liang , Lukasz Odzioba , Peter Zijlstra , Wang Nan , kernel-team@lge.com, Arnaldo Carvalho de Melo , Sasha Levin Subject: [PATCH 4.14 038/173] perf tools: Fix struct comm_str removal crash Date: Mon, 24 Sep 2018 13:51:12 +0200 Message-Id: <20180924113118.769034862@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180924113114.334025954@linuxfoundation.org> References: <20180924113114.334025954@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ From: Jiri Olsa [ Upstream commit 46b3722cc7765582354488da633aafffcb138458 ] We occasionaly hit following assert failure in 'perf top', when processing the /proc info in multiple threads. perf: ...include/linux/refcount.h:109: refcount_inc: Assertion `!(!refcount_inc_not_zero(r))' failed. The gdb backtrace looks like this: [Switching to Thread 0x7ffff11ba700 (LWP 13749)] 0x00007ffff50839fb in raise () from /lib64/libc.so.6 (gdb) #0 0x00007ffff50839fb in raise () from /lib64/libc.so.6 #1 0x00007ffff5085800 in abort () from /lib64/libc.so.6 #2 0x00007ffff507c0da in __assert_fail_base () from /lib64/libc.so.6 #3 0x00007ffff507c152 in __assert_fail () from /lib64/libc.so.6 #4 0x0000000000535373 in refcount_inc (r=0x7fffdc009be0) at ...include/linux/refcount.h:109 #5 0x00000000005354f1 in comm_str__get (cs=0x7fffdc009bc0) at util/comm.c:24 #6 0x00000000005356bd in __comm_str__findnew (str=0x7fffd000b260 ":2", root=0xbed5c0 ) at util/comm.c:72 #7 0x000000000053579e in comm_str__findnew (str=0x7fffd000b260 ":2", root=0xbed5c0 ) at util/comm.c:95 #8 0x000000000053582e in comm__new (str=0x7fffd000b260 ":2", timestamp=0, exec=false) at util/comm.c:111 #9 0x00000000005363bc in thread__new (pid=2, tid=2) at util/thread.c:57 #10 0x0000000000523da0 in ____machine__findnew_thread (machine=0xbfde38, threads=0xbfdf28, pid=2, tid=2, create=true) at util/machine.c:457 #11 0x0000000000523eb4 in __machine__findnew_thread (machine=0xbfde38, ... The failing assertion is this one: REFCOUNT_WARN(!refcount_inc_not_zero(r), ... The problem is that we keep global comm_str_root list, which is accessed by multiple threads during the 'perf top' startup and following 2 paths can race: thread 1: ... thread__new comm__new comm_str__findnew down_write(&comm_str_lock); __comm_str__findnew comm_str__get thread 2: ... comm__override or comm__free comm_str__put refcount_dec_and_test down_write(&comm_str_lock); rb_erase(&cs->rb_node, &comm_str_root); Because thread 2 first decrements the refcnt and only after then it removes the struct comm_str from the list, the thread 1 can find this object on the list with refcnt equls to 0 and hit the assert. This patch fixes the thread 1 __comm_str__findnew path, by ignoring objects that already dropped the refcnt to 0. For the rest of the objects we take the refcnt before comparing its name and release it afterwards with comm_str__put, which can also release the object completely. Signed-off-by: Jiri Olsa Acked-by: Namhyung Kim Cc: Alexander Shishkin Cc: Andi Kleen Cc: David Ahern Cc: Kan Liang Cc: Lukasz Odzioba Cc: Peter Zijlstra Cc: Wang Nan Cc: kernel-team@lge.com Link: http://lkml.kernel.org/r/20180720101740.GA27176@krava Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- tools/perf/util/comm.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) --- a/tools/perf/util/comm.c +++ b/tools/perf/util/comm.c @@ -18,9 +18,10 @@ static struct rb_root comm_str_root; static struct comm_str *comm_str__get(struct comm_str *cs) { - if (cs) - refcount_inc(&cs->refcnt); - return cs; + if (cs && refcount_inc_not_zero(&cs->refcnt)) + return cs; + + return NULL; } static void comm_str__put(struct comm_str *cs) @@ -62,9 +63,14 @@ static struct comm_str *comm_str__findne parent = *p; iter = rb_entry(parent, struct comm_str, rb_node); + /* + * If we race with comm_str__put, iter->refcnt is 0 + * and it will be removed within comm_str__put call + * shortly, ignore it in this search. + */ cmp = strcmp(str, iter->str); - if (!cmp) - return comm_str__get(iter); + if (!cmp && comm_str__get(iter)) + return iter; if (cmp < 0) p = &(*p)->rb_left;