| From 45fef5b88d1f2f47ecdefae6354372d440ca5c84 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no> |
| Date: Thu, 22 May 2014 12:47:47 +0200 |
| Subject: ACPI: add dynamic_debug support |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no> |
| |
| commit 45fef5b88d1f2f47ecdefae6354372d440ca5c84 upstream. |
| |
| Commit 1a699476e258 ("ACPI / hotplug / PCI: Hotplug notifications |
| from acpi_bus_notify()") added debug messages for a few common |
| events. These debug messages are unconditionally enabled if |
| CONFIG_DYNAMIC_DEBUG is defined, contrary to the documented |
| meaning, making the ACPI system spew lots of unwanted noise on |
| any kernel with dynamic debugging. |
| |
| The bug was introduced by commit fbfddae69657 ("ACPI: Add |
| acpi_handle_<level>() interfaces"), which added the |
| CONFIG_DYNAMIC_DEBUG dependency without respecting its meaning. |
| |
| Fix by adding real support for dynamic_debug. |
| |
| Fixes: fbfddae69657 ("ACPI: Add acpi_handle_<level>() interfaces") |
| Signed-off-by: BjΓΈrn Mork <bjorn@mork.no> |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/acpi/utils.c | 64 +++++++++++++++++++++++++++++++++++++++++---------- |
| include/linux/acpi.h | 22 +++++++++++++++-- |
| 2 files changed, 72 insertions(+), 14 deletions(-) |
| |
| --- a/drivers/acpi/utils.c |
| +++ b/drivers/acpi/utils.c |
| @@ -30,6 +30,7 @@ |
| #include <linux/types.h> |
| #include <linux/hardirq.h> |
| #include <linux/acpi.h> |
| +#include <linux/dynamic_debug.h> |
| |
| #include "internal.h" |
| |
| @@ -464,6 +465,24 @@ acpi_evaluate_hotplug_ost(acpi_handle ha |
| EXPORT_SYMBOL(acpi_evaluate_hotplug_ost); |
| |
| /** |
| + * acpi_handle_path: Return the object path of handle |
| + * |
| + * Caller must free the returned buffer |
| + */ |
| +static char *acpi_handle_path(acpi_handle handle) |
| +{ |
| + struct acpi_buffer buffer = { |
| + .length = ACPI_ALLOCATE_BUFFER, |
| + .pointer = NULL |
| + }; |
| + |
| + if (in_interrupt() || |
| + acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK) |
| + return NULL; |
| + return buffer.pointer; |
| +} |
| + |
| +/** |
| * acpi_handle_printk: Print message with ACPI prefix and object path |
| * |
| * This function is called through acpi_handle_<level> macros and prints |
| @@ -476,29 +495,50 @@ acpi_handle_printk(const char *level, ac |
| { |
| struct va_format vaf; |
| va_list args; |
| - struct acpi_buffer buffer = { |
| - .length = ACPI_ALLOCATE_BUFFER, |
| - .pointer = NULL |
| - }; |
| const char *path; |
| |
| va_start(args, fmt); |
| vaf.fmt = fmt; |
| vaf.va = &args; |
| |
| - if (in_interrupt() || |
| - acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK) |
| - path = "<n/a>"; |
| - else |
| - path = buffer.pointer; |
| - |
| - printk("%sACPI: %s: %pV", level, path, &vaf); |
| + path = acpi_handle_path(handle); |
| + printk("%sACPI: %s: %pV", level, path ? path : "<n/a>" , &vaf); |
| |
| va_end(args); |
| - kfree(buffer.pointer); |
| + kfree(path); |
| } |
| EXPORT_SYMBOL(acpi_handle_printk); |
| |
| +#if defined(CONFIG_DYNAMIC_DEBUG) |
| +/** |
| + * __acpi_handle_debug: pr_debug with ACPI prefix and object path |
| + * |
| + * This function is called through acpi_handle_debug macro and debug |
| + * prints a message with ACPI prefix and object path. This function |
| + * acquires the global namespace mutex to obtain an object path. In |
| + * interrupt context, it shows the object path as <n/a>. |
| + */ |
| +void |
| +__acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, |
| + const char *fmt, ...) |
| +{ |
| + struct va_format vaf; |
| + va_list args; |
| + const char *path; |
| + |
| + va_start(args, fmt); |
| + vaf.fmt = fmt; |
| + vaf.va = &args; |
| + |
| + path = acpi_handle_path(handle); |
| + __dynamic_pr_debug(descriptor, "ACPI: %s: %pV", path ? path : "<n/a>", &vaf); |
| + |
| + va_end(args); |
| + kfree(path); |
| +} |
| +EXPORT_SYMBOL(__acpi_handle_debug); |
| +#endif |
| + |
| /** |
| * acpi_has_method: Check whether @handle has a method named @name |
| * @handle: ACPI device handle |
| --- a/include/linux/acpi.h |
| +++ b/include/linux/acpi.h |
| @@ -37,6 +37,7 @@ |
| |
| #include <linux/list.h> |
| #include <linux/mod_devicetable.h> |
| +#include <linux/dynamic_debug.h> |
| |
| #include <acpi/acpi.h> |
| #include <acpi/acpi_bus.h> |
| @@ -590,6 +591,14 @@ static inline __printf(3, 4) void |
| acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {} |
| #endif /* !CONFIG_ACPI */ |
| |
| +#if defined(CONFIG_ACPI) && defined(CONFIG_DYNAMIC_DEBUG) |
| +__printf(3, 4) |
| +void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const char *fmt, ...); |
| +#else |
| +#define __acpi_handle_debug(descriptor, handle, fmt, ...) \ |
| + acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__); |
| +#endif |
| + |
| /* |
| * acpi_handle_<level>: Print message with ACPI prefix and object path |
| * |
| @@ -611,11 +620,19 @@ acpi_handle_printk(const char *level, vo |
| #define acpi_handle_info(handle, fmt, ...) \ |
| acpi_handle_printk(KERN_INFO, handle, fmt, ##__VA_ARGS__) |
| |
| -/* REVISIT: Support CONFIG_DYNAMIC_DEBUG when necessary */ |
| -#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) |
| +#if defined(DEBUG) |
| #define acpi_handle_debug(handle, fmt, ...) \ |
| acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__) |
| #else |
| +#if defined(CONFIG_DYNAMIC_DEBUG) |
| +#define acpi_handle_debug(handle, fmt, ...) \ |
| +do { \ |
| + DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt); \ |
| + if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT)) \ |
| + __acpi_handle_debug(&descriptor, handle, pr_fmt(fmt), \ |
| + ##__VA_ARGS__); \ |
| +} while (0) |
| +#else |
| #define acpi_handle_debug(handle, fmt, ...) \ |
| ({ \ |
| if (0) \ |
| @@ -623,5 +640,6 @@ acpi_handle_printk(const char *level, vo |
| 0; \ |
| }) |
| #endif |
| +#endif |
| |
| #endif /*_LINUX_ACPI_H*/ |