Received: by 10.213.65.68 with SMTP id h4csp537347imn; Tue, 20 Mar 2018 09:06:01 -0700 (PDT) X-Google-Smtp-Source: AG47ELsaad2NNpU4fDIR5s2/daEFnUhUmFeSbsj1KdRq+MByJxY6maf1P69cXieWuFMk1VvUs9w3 X-Received: by 2002:a17:902:f44:: with SMTP id 62-v6mr17014242ply.27.1521561961293; Tue, 20 Mar 2018 09:06:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521561961; cv=none; d=google.com; s=arc-20160816; b=olj1Wn1lHZ7UcdE1eWfW9yZKEuELJD3PN9PSGccgXYH/wLW5JVJIgytw5h6dgMkG8t 3SaO6DjWBv0co7nxqBKoN7dde28GMeqF7kWUkEw9dgGUeouk0MmhXaDBee1JTf7jK/ZC Zzid6bq3SCchPYP8EQSM3Ue+lPeFHIbs1jRCxryn6dEUAPBw8EqCdQbT2Kr+eOoWJfiY SDqM9NP5sL8zT5wvMHDP5S7uAOO57NtS+EoGpSXm38zHtw+69yMii96rAicEzCLFEjVB 1ZX2TMT+P/KKU6163wqHaz7donlTCP16HpWfWggsGKuTLKJKHaSwKlndyzG0yc3h6/4V 1Zcw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=GFmYyDaRXNdyDXS+ka8h/XRlijrUjUYsYDQzfsLVzYo=; b=i5YG9rgDucgKViMyX3mF8nbQZT7COw6Im7Mb+XaPWjFEaufr/7L0MtH8LBu74TtfdT 1gzIILdC3Uj86N4V0wuE/qvrMFlr8sxK6GwhyIbBgqm+tQSWFhZ0Lxa1au856GqfFhL1 7ZEHljgWlDC7FJ/+xBo2qvZBFHKsSHpfjxwxixP0OHfRcyVCOjXdV3uFteMEQk3d8FeU d8JQ+JG6mzAfZXIJMtH2Yy9FJMvwDJu0TUbhIBx9rc1LTqXePqQ1HbfHEsMIpJPP/0W6 cKDNi/CE8Dm0D/bRoYlyFh7VU6PTIfxN6KsjR/bi72EJVBDwyfiEXsZGRd8t++4c+UcU scwg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ffwll.ch header.s=google header.b=VK93NXqh; 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 l1-v6si1901708pld.312.2018.03.20.09.05.37; Tue, 20 Mar 2018 09:06:01 -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; dkim=pass header.i=@ffwll.ch header.s=google header.b=VK93NXqh; 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 S1751824AbeCTQDH (ORCPT + 99 others); Tue, 20 Mar 2018 12:03:07 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:36729 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751583AbeCTQDF (ORCPT ); Tue, 20 Mar 2018 12:03:05 -0400 Received: by mail-wm0-f68.google.com with SMTP id x82so4526509wmg.1 for ; Tue, 20 Mar 2018 09:03:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=from:to:cc:subject:date:message-id; bh=GFmYyDaRXNdyDXS+ka8h/XRlijrUjUYsYDQzfsLVzYo=; b=VK93NXqhkd+wwKVBSyKrtX3r/2ncGAQvBEnzDNPyRVBNLVXI/5Iu3f1nlgEE+gUIvb QsXmne0iaAzXf1b4IptYs6G6AfiI1O82btVHyBdxkmAIFDp0bUud5g/nWRxx4nJapvg4 cjj6SS4ozj9M7o8o6/GhoCIiCQCh/1P8wDo+M= 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; bh=GFmYyDaRXNdyDXS+ka8h/XRlijrUjUYsYDQzfsLVzYo=; b=YdVpefsAvrYxK7BvIqJb7+9KhZ8fevxqx8sf2zTqnlGYAZ9FLK8zoUkmTsi5PpuEX8 d5Hwr4GlFejZmCZe3tnNrfMaEAoWPnS4dMdaFlKEhrTWcv6QKMOg6EfhfYO0fiodelBS ZE5BGRpubj8NPoKwBqHl/1rGejf8efdYtGSetXa1yOX0h3GtyxyNStQ+pPAPBdY0ecAK lzRkCM+WKfobkzCjM5Y6r93kWExUyPyHW8HbXmTBtW7rjXxhhNJuRAqmmFQ15LZ2NuMh tMa9VOxHo1D6dpnja1IqV8JrEk8xSgoGqvUH26EmgKLBHg4wIl+ZVNUXtA3xHaCLhYf4 EzMg== X-Gm-Message-State: AElRT7GHwbwCf/Vgg3Dw0OwK6cENc2g3/U8uR7SEkrQjEcXp9INc2ts9 luZppzMe216iC3L0/73uw7IJtA== X-Received: by 10.80.170.56 with SMTP id o53mr17896606edc.28.1521561784635; Tue, 20 Mar 2018 09:03:04 -0700 (PDT) Received: from phenom.ffwll.local (212-51-149-109.fiber7.init7.net. [212.51.149.109]) by smtp.gmail.com with ESMTPSA id b10sm1970404edj.73.2018.03.20.09.03.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 20 Mar 2018 09:03:03 -0700 (PDT) From: Daniel Vetter To: Intel Graphics Development Cc: LKML , Daniel Vetter , Philippe Ombredanne , Greg Kroah-Hartman , Thomas Gleixner , Kate Stewart , Waiman Long , Daniel Vetter Subject: [PATCH] RFC: debugobjects: capture stack traces at _init() time Date: Tue, 20 Mar 2018 17:02:58 +0100 Message-Id: <20180320160258.11381-1-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.16.2 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Sometimes it's really easy to know which object has gone boom and where the offending code is, and sometimes it's really hard. One case we're trying to hunt down is when module unload catches a live debug object, with a module with lots of them. Capture a full stack trace from debug_object_init() and dump it when there's a problem. FIXME: Should we have a separate Kconfig knob for the backtraces, they're quite expensive? Atm I'm just selecting it for the general debug object stuff. v2: Drop the locks for gathering&storing the backtrace. This is required because depot_save_stack can call free_pages (to drop it's preallocation), which can call debug_check_no_obj_freed, which will recurse into the db->lock spinlocks. Cc: Philippe Ombredanne Cc: Greg Kroah-Hartman Cc: Thomas Gleixner Cc: Kate Stewart Cc: Daniel Vetter Cc: Waiman Long Signed-off-by: Daniel Vetter --- include/linux/debugobjects.h | 2 ++ lib/Kconfig.debug | 1 + lib/debugobjects.c | 57 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/include/linux/debugobjects.h b/include/linux/debugobjects.h index afc416e5dcab..d3a6ca1a7756 100644 --- a/include/linux/debugobjects.h +++ b/include/linux/debugobjects.h @@ -4,6 +4,7 @@ #include #include +#include enum debug_obj_state { ODEBUG_STATE_NONE, @@ -31,6 +32,7 @@ struct debug_obj { unsigned int astate; void *object; struct debug_obj_descr *descr; + depot_stack_handle_t stack; }; /** diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 64155e310a9f..894dd792e771 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -442,6 +442,7 @@ source mm/Kconfig.debug config DEBUG_OBJECTS bool "Debug object operations" depends on DEBUG_KERNEL + select STACKDEPOT help If you say Y here, additional code will be inserted into the kernel to track the life time of various objects and validate diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 2f5349c6e81a..2acad7150bee 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -19,6 +19,7 @@ #include #include #include +#include #define ODEBUG_HASH_BITS 14 #define ODEBUG_HASH_SIZE (1 << ODEBUG_HASH_BITS) @@ -30,6 +31,8 @@ #define ODEBUG_CHUNK_SIZE (1 << ODEBUG_CHUNK_SHIFT) #define ODEBUG_CHUNK_MASK (~(ODEBUG_CHUNK_SIZE - 1)) +#define ODEBUG_STACKDEPTH 32 + struct debug_bucket { struct hlist_head list; raw_spinlock_t lock; @@ -280,15 +283,24 @@ static void debug_print_object(struct debug_obj *obj, char *msg) { struct debug_obj_descr *descr = obj->descr; static int limit; + unsigned long entries[ODEBUG_STACKDEPTH]; + struct stack_trace trace = { + .entries = entries, + .max_entries = ODEBUG_STACKDEPTH + }; + if (limit < 5 && descr != descr_test) { void *hint = descr->debug_hint ? descr->debug_hint(obj->object) : NULL; limit++; + depot_fetch_stack(obj->stack, &trace); WARN(1, KERN_ERR "ODEBUG: %s %s (active state %u) " "object type: %s hint: %pS\n", msg, obj_states[obj->state], obj->astate, descr->name, hint); + pr_err("ODEBUG: debug object originally initialized at:\n"); + print_stack_trace(&trace, 2); } debug_objects_warnings++; } @@ -328,6 +340,24 @@ static void debug_object_is_on_stack(void *addr, int onstack) WARN_ON(1); } +static noinline depot_stack_handle_t save_stack(struct debug_obj *obj) +{ + unsigned long entries[ODEBUG_STACKDEPTH]; + struct stack_trace trace = { + .entries = entries, + .max_entries = ODEBUG_STACKDEPTH, + .skip = 2 + }; + + save_stack_trace(&trace); + if (trace.nr_entries != 0 && + trace.entries[trace.nr_entries-1] == ULONG_MAX) + trace.nr_entries--; + + /* May be called under spinlock, so avoid sleeping */ + return depot_save_stack(&trace, GFP_NOWAIT); +} + static void __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) { @@ -344,14 +374,29 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack) obj = lookup_object(addr, db); if (!obj) { - obj = alloc_object(addr, db, descr); + depot_stack_handle_t stack; + + /* + * must drop locks while storing the stack trace to avoid + * recursive deadlock through depot_save_stack + * allocating/freeing memory. + */ + raw_spin_unlock_irqrestore(&db->lock, flags); + stack = save_stack(obj); + raw_spin_lock_irqsave(&db->lock, flags); + + obj = lookup_object(addr, db); if (!obj) { - debug_objects_enabled = 0; - raw_spin_unlock_irqrestore(&db->lock, flags); - debug_objects_oom(); - return; + obj = alloc_object(addr, db, descr); + if (!obj) { + debug_objects_enabled = 0; + raw_spin_unlock_irqrestore(&db->lock, flags); + debug_objects_oom(); + return; + } + debug_object_is_on_stack(addr, onstack); + obj->stack = stack; } - debug_object_is_on_stack(addr, onstack); } switch (obj->state) { -- 2.16.2