Received: by 10.223.164.202 with SMTP id h10csp680253wrb; Thu, 9 Nov 2017 12:35:42 -0800 (PST) X-Google-Smtp-Source: ABhQp+REUy7E5nmvLe0JZINhR7psz1fygKr7tljxdeZ6ZFSXH7E7njS2Bj5Lb+GwRpYKZG4S+MQr X-Received: by 10.98.110.73 with SMTP id j70mr1720665pfc.146.1510259742359; Thu, 09 Nov 2017 12:35:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510259742; cv=none; d=google.com; s=arc-20160816; b=pWH2vP2WON7czHxCiyGjJ0YBF2+uzdW+P8KJAmhHRKSuYbYl+hst5G76KIckoO0pUD U98FmgFI694NqSbs2sFVjdBoZrg8th96XWp7EkMqgaCDWEzOaJ9c6acZjcLfYqQLUZXV pQK8qZ3ow/kZom0JTjSoud+JkXRnjvSle0KRB/4lXxC3iD/GsVWQ6kPC+wxeEnA2LP1i oNbv4dkGOGlYBl1Y5hinvknS9HI2gM6Qxc/e+01m9EQOsF4DilgzV245WFUJIytikc0j H5ovnF1nNj0qsMoGf4tFYMF8QiPkm3zRupfWe7Wti2BdcaSbTjaXqVSMnFmDC5GYTwNZ HGmA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=Al/ExRQH8IH/uk9G6KgwAtrxe4tDwGbxCXAtfH8DQrk=; b=XErYd7vjMgCQY5SLK4lP3OtPgDGhRIhaF3o2zgME97WfP4kafIHMcwuq3BDvt2/X0s 7jAIZu7uXrFGN8MMU63T/zRJbaeQ/uHXieGquYA/Zqtyx0MBD4fqzPCEEa3aO9+P5ztH m8ycA7QCLn/PvGTrcAIt9GcomQA/JqHO3yqMktqE5vzOI/vuWQM1JlXAdxirqxCeqd/s R6VXeSXIhzyQV0VDxbRl3fMzQDVe2ZlAxXUMGVbDjX42dG+V9W0fJqBnYw2Agw7s4844 4Mo4Q0XEPm/ZauvYPt1qhJPa5QJipKMmnNuwLzXwBz2PR+Dq4ZewaSUrEVT7RxSfgyFq eNLg== 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 j3si7161017pld.2.2017.11.09.12.35.30; Thu, 09 Nov 2017 12:35:42 -0800 (PST) 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 S1754259AbdKIUee (ORCPT + 83 others); Thu, 9 Nov 2017 15:34:34 -0500 Received: from mga01.intel.com ([192.55.52.88]:33892 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753751AbdKIUe1 (ORCPT ); Thu, 9 Nov 2017 15:34:27 -0500 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Nov 2017 12:34:27 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.44,370,1505804400"; d="scan'208";a="5891735" Received: from dkusalov-mobl4.amr.corp.intel.com (HELO localhost) ([10.254.117.34]) by orsmga002.jf.intel.com with ESMTP; 09 Nov 2017 12:34:25 -0800 From: Tom Zanussi To: rostedt@goodmis.org Cc: tglx@linutronix.de, mhiramat@kernel.org, namhyung@kernel.org, vedang.patel@intel.com, bigeasy@linutronix.de, joel.opensrc@gmail.com, joelaf@google.com, mathieu.desnoyers@efficios.com, baohong.liu@intel.com, rajvi.jingar@intel.com, julia@ni.com, linux-kernel@vger.kernel.org, linux-rt-users@vger.kernel.org, Tom Zanussi Subject: [PATCH v5 03/37] tracing: Add support to detect and avoid duplicates Date: Thu, 9 Nov 2017 14:33:34 -0600 Message-Id: <572118543e22b53466beae1121d5b5b4279ceb06.1510252666.git.tom.zanussi@linux.intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Vedang Patel A duplicate in the tracing_map hash table is when 2 different entries have the same key and, as a result, the key_hash. This is possible due to a race condition in the algorithm. This race condition is inherent to the algorithm and not a bug. This was fine because, until now, we were only interested in the sum of all the values related to a particular key (the duplicates are dealt with in tracing_map_sort_entries()). But, with the inclusion of variables[1], we are interested in individual values. So, it will not be clear what value to choose when there are duplicates. So, the duplicates need to be removed. The duplicates can occur in the code in the following scenarios: - A thread is in the process of adding a new element. It has successfully executed cmpxchg() and inserted the key. But, it is still not done acquiring the trace_map_elt struct, populating it and storing the pointer to the struct in the value field of tracing_map hash table. If another thread comes in at this time and wants to add an element with the same key, it will not see the current element and add a new one. - There are multiple threads trying to execute cmpxchg at the same time, one of the threads will succeed and the others will fail. The ones which fail will go ahead increment 'idx' and add a new element there creating a duplicate. This patch detects and avoids the first condition by asking the thread which detects the duplicate to loop one more time. There is also a possibility of infinite loop if the thread which is trying to insert goes to sleep indefinitely and the one which is trying to insert a new element detects a duplicate. Which is why, the thread loops for map_size iterations before returning NULL. The second scenario is avoided by preventing the threads which failed cmpxchg() from incrementing idx. This way, they will loop around and check if the thread which succeeded in executing cmpxchg() had the same key. [1] http://lkml.kernel.org/r/cover.1498510759.git.tom.zanussi@linux.intel.com Signed-off-by: Vedang Patel Signed-off-by: Tom Zanussi --- kernel/trace/tracing_map.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c index 07e7534..b30f343 100644 --- a/kernel/trace/tracing_map.c +++ b/kernel/trace/tracing_map.c @@ -414,7 +414,9 @@ static inline bool keys_match(void *key, void *test_key, unsigned key_size) __tracing_map_insert(struct tracing_map *map, void *key, bool lookup_only) { u32 idx, key_hash, test_key; + int dup_try = 0; struct tracing_map_entry *entry; + struct tracing_map_elt *val; key_hash = jhash(key, map->key_size, 0); if (key_hash == 0) @@ -426,11 +428,33 @@ static inline bool keys_match(void *key, void *test_key, unsigned key_size) entry = TRACING_MAP_ENTRY(map->map, idx); test_key = entry->key; - if (test_key && test_key == key_hash && entry->val && - keys_match(key, entry->val->key, map->key_size)) { - if (!lookup_only) - atomic64_inc(&map->hits); - return entry->val; + if (test_key && test_key == key_hash) { + val = READ_ONCE(entry->val); + if (val && + keys_match(key, val->key, map->key_size)) { + if (!lookup_only) + atomic64_inc(&map->hits); + return val; + } else if (unlikely(!val)) { + /* + * The key is present. But, val (pointer to elt + * struct) is still NULL. which means some other + * thread is in the process of inserting an + * element. + * + * On top of that, it's key_hash is same as the + * one being inserted right now. So, it's + * possible that the element has the same + * key as well. + */ + + dup_try++; + if (dup_try > map->map_size) { + atomic64_inc(&map->drops); + break; + } + continue; + } } if (!test_key) { @@ -452,6 +476,13 @@ static inline bool keys_match(void *key, void *test_key, unsigned key_size) atomic64_inc(&map->hits); return entry->val; + } else { + /* + * cmpxchg() failed. Loop around once + * more to check what key was inserted. + */ + dup_try++; + continue; } } -- 1.9.3 From 1583489987608404284@xxx Wed Nov 08 09:35:31 +0000 2017 X-GM-THRID: 1583489987608404284 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread