Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp954500ybl; Mon, 2 Dec 2019 22:08:43 -0800 (PST) X-Google-Smtp-Source: APXvYqwzkk6ruIbwFkv+BjOe5O91LC0n9S5FVvlgNhf5CLF6JmhYJ7JmF5Hyy8KjxeRl1z9MCW5S X-Received: by 2002:a05:6808:9ba:: with SMTP id e26mr2376146oig.81.1575353323703; Mon, 02 Dec 2019 22:08:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1575353323; cv=none; d=google.com; s=arc-20160816; b=hVp5hhZeCLtgi2MpIEFwxPkTskyoB6/rhW6/kQIwu+tDpaWg+Jti9DN24aXt3vbE1J KaV2EXJ/yFfo13iU9UYUDuk23yEZNY0BM0eHijdvq/2SUjJJMK1DpeChsarsHI4ZJxMB HTxoLUoMNy7i3nLVfJ5TtrXhkFcHpjnjpkg2M9mzIN+7cCbbStcCM5RsuSewXJ1ZnTCf T2451jZM+nODxwDDHlxAOqDUnfEUrNVsAjdJCEEsIBB9W7CW5YEMQgaDjzq7b0GVBKOJ Q5liayZvKRm+AxVRlOmD0dbsil7MJm+U2094TBKxPM9HgO7jpO+J9ySd4EcfG+0Vt+FY Z8Mw== 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:dkim-signature; bh=YA6VM+XsrW6mc+UiutETVq5gNDCU70SmXLoqrPp5wlA=; b=LDyg1UEN4qTY1jZit0G0WvCiohU9ZK2qOOW6EmRBJ+7v/t+VF7EoRW3Xu/OB1/w/Id wq60P8xXog9MYXp9KRaf+e6/jAShv0rPGBmg5pt4+mbQM+Uig3fQwGn1GEf2BMeg8ell xmNT9+zpwPQS92AH4W/PyKzIw4KOcgVlLG91/qrJfYwuqXwuzFEr4jU6+eyjpnUc5+Wh LuVdwoR0TQZwLb7P+5Bc9MNHPK8QHp4aH/zTcEdgWE48uSoh+fMIyF6X3N0AK+CWiyNf Ov330W04o3ygPs8NXtzblDnDmRxIDcelxz2bPvpcV0CULZs/WjT3XMcmiC07kaG0I+5Y q6fQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=gx0xrp3q; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id j2si802473oif.98.2019.12.02.22.08.31; Mon, 02 Dec 2019 22:08:43 -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; dkim=pass header.i=@kernel.org header.s=default header.b=gx0xrp3q; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727183AbfLCGGg (ORCPT + 99 others); Tue, 3 Dec 2019 01:06:36 -0500 Received: from mail.kernel.org ([198.145.29.99]:44142 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726521AbfLCGGg (ORCPT ); Tue, 3 Dec 2019 01:06:36 -0500 Received: from localhost.localdomain (unknown [180.22.253.92]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C31C02068E; Tue, 3 Dec 2019 06:06:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1575353195; bh=dIreLY83seUdqZu6R1y9BdVoKulh8Q54BvasWnDIcXQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gx0xrp3qzvwok1qlziS3AtgnxlYaKJ1UfSBycZ7LIHHbbE/qzXpMQs2GWf41Ydsqr hsLowHot4PIiY86PlmVjdzesbkkF057mpg+pk2PTmB8IIGYXFpyovkVTN+G9sweJl3 q6K8dIZZGkcJ9sJ2kOwQfDt0InDykbrfJCxWiWlw= From: Masami Hiramatsu To: Ingo Molnar Cc: Anders Roxell , paulmck@kernel.org, joel@joelfernandes.org, "Naveen N . Rao" , Anil S Keshavamurthy , David Miller , Masami Hiramatsu , Linux Kernel Mailing List Subject: [PATCH -tip V2 2/2] kprobes: Use non RCU traversal APIs on kprobe_tables if possible Date: Tue, 3 Dec 2019 15:06:28 +0900 Message-Id: <157535318870.16485.6366477974356032624.stgit@devnote2> X-Mailer: git-send-email 2.20.1 In-Reply-To: <157535316659.16485.11817291759382261088.stgit@devnote2> References: <157535316659.16485.11817291759382261088.stgit@devnote2> User-Agent: StGit/0.17.1-dirty 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 Current kprobes uses RCU traversal APIs on kprobe_tables even if it is safe because kprobe_mutex is locked. Make those traversals to non-RCU APIs where the kprobe_mutex is locked. Signed-off-by: Masami Hiramatsu --- kernel/kprobes.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/kernel/kprobes.c b/kernel/kprobes.c index f9ecb6d532fb..4caab01ace30 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -46,6 +46,11 @@ static int kprobes_initialized; +/* kprobe_table can be accessed by + * - Normal hlist traversal and RCU add/del under kprobe_mutex is held. + * Or + * - RCU hlist traversal under disabling preempt (breakpoint handlers) + */ static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE]; @@ -829,7 +834,7 @@ static void optimize_all_kprobes(void) kprobes_allow_optimization = true; for (i = 0; i < KPROBE_TABLE_SIZE; i++) { head = &kprobe_table[i]; - hlist_for_each_entry_rcu(p, head, hlist) + hlist_for_each_entry(p, head, hlist) if (!kprobe_disabled(p)) optimize_kprobe(p); } @@ -856,7 +861,7 @@ static void unoptimize_all_kprobes(void) kprobes_allow_optimization = false; for (i = 0; i < KPROBE_TABLE_SIZE; i++) { head = &kprobe_table[i]; - hlist_for_each_entry_rcu(p, head, hlist) { + hlist_for_each_entry(p, head, hlist) { if (!kprobe_disabled(p)) unoptimize_kprobe(p, false); } @@ -1479,12 +1484,14 @@ static struct kprobe *__get_valid_kprobe(struct kprobe *p) { struct kprobe *ap, *list_p; + lockdep_assert_held(&kprobe_mutex); + ap = get_kprobe(p->addr); if (unlikely(!ap)) return NULL; if (p != ap) { - list_for_each_entry_rcu(list_p, &ap->list, list) + list_for_each_entry(list_p, &ap->list, list) if (list_p == p) /* kprobe p is a valid probe */ goto valid; @@ -1649,7 +1656,9 @@ static int aggr_kprobe_disabled(struct kprobe *ap) { struct kprobe *kp; - list_for_each_entry_rcu(kp, &ap->list, list) + lockdep_assert_held(&kprobe_mutex); + + list_for_each_entry(kp, &ap->list, list) if (!kprobe_disabled(kp)) /* * There is an active probe on the list. @@ -1728,7 +1737,7 @@ static int __unregister_kprobe_top(struct kprobe *p) else { /* If disabling probe has special handlers, update aggrprobe */ if (p->post_handler && !kprobe_gone(p)) { - list_for_each_entry_rcu(list_p, &ap->list, list) { + list_for_each_entry(list_p, &ap->list, list) { if ((list_p != p) && (list_p->post_handler)) goto noclean; } @@ -2042,13 +2051,15 @@ static void kill_kprobe(struct kprobe *p) { struct kprobe *kp; + lockdep_assert_held(&kprobe_mutex); + p->flags |= KPROBE_FLAG_GONE; if (kprobe_aggrprobe(p)) { /* * If this is an aggr_kprobe, we have to list all the * chained probes and mark them GONE. */ - list_for_each_entry_rcu(kp, &p->list, list) + list_for_each_entry(kp, &p->list, list) kp->flags |= KPROBE_FLAG_GONE; p->post_handler = NULL; kill_optimized_kprobe(p); @@ -2217,7 +2228,7 @@ static int kprobes_module_callback(struct notifier_block *nb, mutex_lock(&kprobe_mutex); for (i = 0; i < KPROBE_TABLE_SIZE; i++) { head = &kprobe_table[i]; - hlist_for_each_entry_rcu(p, head, hlist) + hlist_for_each_entry(p, head, hlist) if (within_module_init((unsigned long)p->addr, mod) || (checkcore && within_module_core((unsigned long)p->addr, mod))) { @@ -2468,7 +2479,7 @@ static int arm_all_kprobes(void) for (i = 0; i < KPROBE_TABLE_SIZE; i++) { head = &kprobe_table[i]; /* Arm all kprobes on a best-effort basis */ - hlist_for_each_entry_rcu(p, head, hlist) { + hlist_for_each_entry(p, head, hlist) { if (!kprobe_disabled(p)) { err = arm_kprobe(p); if (err) { @@ -2511,7 +2522,7 @@ static int disarm_all_kprobes(void) for (i = 0; i < KPROBE_TABLE_SIZE; i++) { head = &kprobe_table[i]; /* Disarm all kprobes on a best-effort basis */ - hlist_for_each_entry_rcu(p, head, hlist) { + hlist_for_each_entry(p, head, hlist) { if (!arch_trampoline_kprobe(p) && !kprobe_disabled(p)) { err = disarm_kprobe(p, false); if (err) {