* [PATCH 0/3] Add Firmware Info, Warn, and Bug messages
@ 2013-12-02 15:19 Prarit Bhargava
2013-12-02 15:19 ` [PATCH 1/3] Introduce FW_INFO* functions and messages Prarit Bhargava
` (3 more replies)
0 siblings, 4 replies; 14+ messages in thread
From: Prarit Bhargava @ 2013-12-02 15:19 UTC (permalink / raw)
To: linux-kernel
Cc: Prarit Bhargava, Arnd Bergmann, Andrew Morton, Greg Kroah-Hartman
Logging and tracking firmware bugs in the kernel has long been an issue
for system administrators. The current kernel does not have a good
uniform method of reporting firmware bugs and the code in the kernel is a
mix of printk's and WARN_ONs. This causes problems for both system
administrators and QA engineers who attempt to diagnose problems within
the kernel.
Using printk's is somewhat effective but lacks information useful for
reporting a bug such as the system vendor or model, BIOS revision, etc.
Using WARN_ONs is also questionable because the data like the backtrace
and the list of modules is usually unnecessary for firmware issues as the
warning stems from one call path during system or driver initialization.
We have heard many complaints from users about the excess verbosity and
confusing stacktraces for these messages.
I'm proposing with this patch to do something similar to the WARN()
mechanism that is currently implemented in the kernel. This
patchset introduces FW_* functions which logs output like:
[ 230.661137] [Firmware Info]: pci_bus 0000:00: at
/home/prarit_modules/prarit.c:21 Your BIOS is broken because it is
-ENOWORKY.
[ 230.671076] [Firmware Info]: Intel Corporation SandyBridge Platform/To
be filled by O.E.M., BIOS RMLCRB.86I.R3.27.D685.1305151733 05/15/2013
instead of the verbose back traces we are currently seeing. These messages
can be easily gleaned from /var/log/messages, etc., by automatic bug
reporting tools and system administrators to properly report bugs to
hardware vendors.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Prarit Bhargava (3):
Introduce FW_INFO* functions and messages
Introduce FW_WARN* functions and messages
Introduce FW_BUG* functions and messages
arch/x86/kernel/apic/apic.c | 8 +--
arch/x86/kernel/cpu/amd.c | 9 ++--
arch/x86/kernel/cpu/mcheck/mce.c | 2 +-
arch/x86/kernel/cpu/mcheck/mce_amd.c | 12 ++---
arch/x86/kernel/cpu/mtrr/generic.c | 4 +-
arch/x86/kernel/cpu/perf_event.c | 8 ++-
arch/x86/kernel/cpu/perf_event_amd_ibs.c | 10 ++--
arch/x86/pci/mmconfig-shared.c | 18 ++-----
drivers/acpi/apei/apei-base.c | 40 +++++++--------
drivers/acpi/apei/einj.c | 9 ++--
drivers/acpi/apei/erst.c | 17 +++----
drivers/acpi/apei/ghes.c | 42 ++++++++--------
drivers/acpi/apei/hest.c | 15 +++---
drivers/acpi/battery.c | 12 +++--
drivers/acpi/osl.c | 6 +--
drivers/acpi/pci_root.c | 4 +-
drivers/acpi/processor_perflib.c | 16 +++---
drivers/acpi/thermal.c | 5 +-
drivers/acpi/video.c | 17 +++----
drivers/acpi/video_detect.c | 4 +-
drivers/cpufreq/acpi-cpufreq.c | 4 +-
drivers/cpufreq/powernow-k8.c | 56 +++++++++++----------
drivers/firmware/dmi_scan.c | 2 +-
drivers/firmware/efi/cper.c | 2 +-
drivers/iommu/amd_iommu_init.c | 24 +++++----
drivers/iommu/dmar.c | 3 +-
drivers/iommu/intel_irq_remapping.c | 4 +-
drivers/pci/quirks.c | 2 +-
drivers/pnp/quirks.c | 4 +-
include/asm-generic/bug.h | 78 ++++++++++++++++++++++++++++++
include/linux/printk.h | 30 +++---------
kernel/panic.c | 42 ++++++++++++++++
kernel/printk/printk.c | 12 +++++
33 files changed, 305 insertions(+), 216 deletions(-)
--
1.7.9.3
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 1/3] Introduce FW_INFO* functions and messages
2013-12-02 15:19 [PATCH 0/3] Add Firmware Info, Warn, and Bug messages Prarit Bhargava
@ 2013-12-02 15:19 ` Prarit Bhargava
2013-12-03 21:21 ` Andrew Morton
2013-12-02 15:19 ` [PATCH 2/3] Introduce FW_WARN* " Prarit Bhargava
` (2 subsequent siblings)
3 siblings, 1 reply; 14+ messages in thread
From: Prarit Bhargava @ 2013-12-02 15:19 UTC (permalink / raw)
To: linux-kernel
Cc: Prarit Bhargava, Arnd Bergmann, Andrew Morton, Greg Kroah-Hartman
Logging and tracking firmware bugs in the kernel has long been an issue
for system administrators. The current kernel does not have a good
uniform method of reporting firmware bugs and the code in the kernel is a
mix of printk's and WARN_ONs. This causes problems for both system
administrators and QA engineers who attempt to diagnose problems within
the kernel.
Using printk's is somewhat effective but lacks information useful for
reporting a bug such as the system vendor or model, BIOS revision, etc.
Using WARN_ONs is also questionable because the data like the backtrace
and the list of modules is usually unnecessary for firmware issues as the
warning stems from one call path during system or driver initialization.
We have heard many complaints from users about the excess verbosity and
confusing stacktraces for these messages.
I'm proposing with this patch to do something similar to the WARN()
mechanism that is currently implemented in the kernel. This
patchset introduces FW_INFO() and FW_INFO_DEV() which logs output like:
[ 230.661137] [Firmware Info]: pci_bus 0000:00: at
/home/prarit_modules/prarit.c:21 Your BIOS is broken because it is
-ENOWORKY.
[ 230.671076] [Firmware Info]: Intel Corporation SandyBridge Platform/To
be filled by O.E.M., BIOS RMLCRB.86I.R3.27.D685.1305151733 05/15/2013
instead of the verbose back traces we are currently seeing. These messages
can be easily gleaned from /var/log/messages, etc., by automatic bug
reporting tools and system administrators to properly report bugs to
hardware vendors.
I found an improperly classified FW_INFO in arch/x86/kernel/cpu/amd.c
which that should be a FW_BUG.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/pci/mmconfig-shared.c | 15 +++-----------
include/asm-generic/bug.h | 35 +++++++++++++++++++++++++++++++++
include/linux/printk.h | 13 ++++++-------
kernel/panic.c | 42 ++++++++++++++++++++++++++++++++++++++++
kernel/printk/printk.c | 12 ++++++++++++
5 files changed, 98 insertions(+), 19 deletions(-)
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 082e881..3cb0eff 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -498,15 +498,9 @@ static int __ref pci_mmcfg_check_reserved(struct device *dev,
if (is_mmconf_reserved(is_acpi_reserved, cfg, dev, 0))
return 1;
- if (dev)
- dev_info(dev, FW_INFO
- "MMCONFIG at %pR not reserved in "
- "ACPI motherboard resources\n",
+ FW_INFO_DEV(dev, dev, "MMCONFIG at %pR not reserved in ACPI motherboard resources\n",
&cfg->res);
- else
- pr_info(FW_INFO PREFIX
- "MMCONFIG at %pR not reserved in "
- "ACPI motherboard resources\n",
+ FW_INFO(!dev, PREFIX "MMCONFIG at %pR not reserved in ACPI motherboard resources\n",
&cfg->res);
}
@@ -707,10 +701,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
cfg = pci_mmconfig_lookup(seg, start);
if (cfg) {
if (cfg->end_bus < end)
- dev_info(dev, FW_INFO
- "MMCONFIG for "
- "domain %04x [bus %02x-%02x] "
- "only partially covers this bridge\n",
+ FW_INFO_DEV(1, dev, "MMCONFIG for domain %04x [bus %02x-%02x] only partially covers this bridge\n",
cfg->segment, cfg->start_bus, cfg->end_bus);
mutex_unlock(&pci_mmcfg_lock);
return -EEXIST;
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 7d10f96..b3cb4ed 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -68,12 +68,17 @@ void warn_slowpath_fmt(const char *file, const int line,
extern __printf(4, 5)
void warn_slowpath_fmt_taint(const char *file, const int line, unsigned taint,
const char *fmt, ...);
+extern __printf(5, 6)
+void warn_slowpath_fmt_dev(const char *file, const int line,
+ struct device *dev, int level, const char *fmt, ...);
extern void warn_slowpath_null(const char *file, const int line);
#define WANT_WARN_ON_SLOWPATH
#define __WARN() warn_slowpath_null(__FILE__, __LINE__)
#define __WARN_printf(arg...) warn_slowpath_fmt(__FILE__, __LINE__, arg)
#define __WARN_printf_taint(taint, arg...) \
warn_slowpath_fmt_taint(__FILE__, __LINE__, taint, arg)
+#define __WARN_printf_dev(dev, level, arg...) \
+ warn_slowpath_fmt_dev(__FILE__, __LINE__, dev, level, arg)
#else
#define __WARN() __WARN_TAINT(TAINT_WARN)
#define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0)
@@ -106,6 +111,25 @@ extern void warn_slowpath_null(const char *file, const int line);
unlikely(__ret_warn_on); \
})
+/*
+ * FW_INFO & FW_INFO_DEV are used to indicate that a firmware bug has
+ * been found, but no action has been taken in the kernel.
+ *
+ * FW_WARN & FW_WARN_DEV are used to indicate that a firmware bug has
+ * been found, and an error action has been taken in the kernel.
+ *
+ * FW_BUG & FW_BUG_DEV are used to indicate that a firmware bug has been
+ * found, and a corrective action has been taken in the kernel. FW_BUG
+ * sets the TAINT_FIRMWARE_WORKAROUND flag.
+ */
+#define FW_INFO_DEV(condition, dev, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ if (unlikely(__ret_warn_on)) \
+ __WARN_printf_dev(dev, 1, format); \
+ unlikely(__ret_warn_on); \
+})
+#define FW_INFO(condition, format...) FW_INFO_DEV(condition, NULL, format)
+
#else /* !CONFIG_BUG */
#ifndef HAVE_ARCH_BUG
#define BUG() do {} while(0)
@@ -131,6 +155,17 @@ extern void warn_slowpath_null(const char *file, const int line);
#define WARN_TAINT(condition, taint, format...) WARN_ON(condition)
+#define FW_INFO_DEV(condition, dev, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ dev_info(format); \
+ unlikely(__ret_warn_on); \
+})
+
+#define FW_INFO(condition, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ pr_info(format); \
+ unlikely(__ret_warn_on); \
+})
#endif
#define WARN_ON_ONCE(condition) ({ \
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 6949258..db540cc 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -69,16 +69,9 @@ struct va_format {
* FW_WARN
* Use it for not that clear (e.g. could the kernel messed up things already?)
* and medium priority BIOS bugs.
- *
- * FW_INFO
- * Use this one if you want to tell the user or vendor about something
- * suspicious, but generally harmless related to the firmware.
- *
- * Use it for information or very low priority BIOS bugs.
*/
#define FW_BUG "[Firmware Bug]: "
#define FW_WARN "[Firmware Warn]: "
-#define FW_INFO "[Firmware Info]: "
/*
* HW_ERR
@@ -147,6 +140,7 @@ extern void wake_up_klogd(void);
void log_buf_kexec_setup(void);
void __init setup_log_buf(int early);
void dump_stack_set_arch_desc(const char *fmt, ...);
+char *dump_hardware_arch_desc(void);
void dump_stack_print_info(const char *log_lvl);
void show_regs_print_info(const char *log_lvl);
#else
@@ -187,6 +181,11 @@ static inline void setup_log_buf(int early)
{
}
+static inline char *dump_hadware_arch_desc(void)
+{
+ return NULL;
+}
+
static inline void dump_stack_set_arch_desc(const char *fmt, ...)
{
}
diff --git a/kernel/panic.c b/kernel/panic.c
index c00b4ce..ed24b3e 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -23,6 +23,7 @@
#include <linux/sysrq.h>
#include <linux/init.h>
#include <linux/nmi.h>
+#include <linux/device.h>
#define PANIC_TIMER_STEP 100
#define PANIC_BLINK_SPD 18
@@ -445,6 +446,47 @@ void warn_slowpath_fmt_taint(const char *file, int line,
}
EXPORT_SYMBOL(warn_slowpath_fmt_taint);
+void warn_slowpath_fmt_dev(const char *file, int line,
+ struct device *dev, int level, const char *fmt, ...)
+{
+ struct slowpath_args args;
+ static char fw_str[16] = "\0";
+
+ switch (level) {
+ case 1:
+ strcpy(fw_str, "[Firmware Info]");
+ break;
+ case 2:
+ strcpy(fw_str, "[Firmware Warn]");
+ break;
+ case 3:
+ strcpy(fw_str, "[Firmware Bug]");
+ add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
+ break;
+ default:
+ strcpy(fw_str, "[Firmware Bug]");
+ break;
+ }
+
+ if (dev)
+ pr_info("%s: %s %s ", fw_str,
+ dev_driver_string(dev), dev_name(dev));
+ pr_info("%s: at %s:%d\n", fw_str, file, line);
+
+ args.fmt = fmt;
+ va_start(args.args, fmt);
+ printk(KERN_WARNING "%s: %pV", fw_str, &args);
+ va_end(args.args);
+
+ if (dump_hardware_arch_desc())
+ pr_info("%s: System Info: %s\n", fw_str,
+ dump_hardware_arch_desc());
+ else
+ pr_info("%s: System Info: Hardware Unidentified\n", fw_str);
+}
+EXPORT_SYMBOL(warn_slowpath_fmt_dev);
+
+
void warn_slowpath_null(const char *file, int line)
{
warn_slowpath_common(file, line, __builtin_return_address(0),
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index be7c86b..3e4c634 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -2869,6 +2869,18 @@ void __init dump_stack_set_arch_desc(const char *fmt, ...)
}
/**
+ * dump_hardware_arch_desc -- return generic hardware and firmware information
+ *
+ * Return a string with the hardware name and firmware version for this system
+ */
+char *dump_hardware_arch_desc(void)
+{
+ if (dump_stack_arch_desc_str[0] != '\0')
+ return dump_stack_arch_desc_str;
+ return NULL;
+}
+
+/**
* dump_stack_print_info - print generic debug info for dump_stack()
* @log_lvl: log level
*
--
1.7.9.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/3] Introduce FW_WARN* functions and messages
2013-12-02 15:19 [PATCH 0/3] Add Firmware Info, Warn, and Bug messages Prarit Bhargava
2013-12-02 15:19 ` [PATCH 1/3] Introduce FW_INFO* functions and messages Prarit Bhargava
@ 2013-12-02 15:19 ` Prarit Bhargava
2013-12-02 15:19 ` [PATCH 3/3] Introduce FW_BUG* " Prarit Bhargava
2013-12-02 17:34 ` [PATCH 0/3] Add Firmware Info, Warn, and Bug messages Joe Perches
3 siblings, 0 replies; 14+ messages in thread
From: Prarit Bhargava @ 2013-12-02 15:19 UTC (permalink / raw)
To: linux-kernel
Cc: Prarit Bhargava, Arnd Bergmann, Andrew Morton, Greg Kroah-Hartman
Logging and tracking firmware bugs in the kernel has long been an issue
for system administrators. The current kernel does not have a good
uniform method of reporting firmware bugs and the code in the kernel is a
mix of printk's and WARN_ONs. This causes problems for both system
administrators and QA engineers who attempt to diagnose problems within
the kernel.
Using printk's is somewhat effective but lacks information useful for
reporting a bug such as the system vendor or model, BIOS revision, etc.
Using WARN_ONs is also questionable because the data like the backtrace
and the list of modules is usually unnecessary for firmware issues as the
warning stems from one call path during system or driver initialization.
We have heard many complaints from users about the excess verbosity and
confusing stacktraces for these messages.
I'm proposing with this patch to do something similar to the WARN()
mechanism that is currently implemented in the kernel. This patchset
introduces FW_WARN() and FW_WARN_DEV() which logs output like:
[ 230.661137] [Firmware Warn]: pci_bus 0000:00: at
/home/prarit_modules/prarit.c:21 Your BIOS is broken because it is
-ENOWORKY. [ 230.671076] [Firmware Warn]: Intel Corporation SandyBridge
Platform/To be filled by O.E.M., BIOS RMLCRB.86I.R3.27.D685.1305151733
05/15/2013
instead of the verbose back traces we are currently seeing. These
messages can be easily gleaned from /var/log/messages, etc., by automatic
bug reporting tools and system administrators to properly report bugs to
hardware vendors.
Also made some usage corrections.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/cpu/amd.c | 2 +-
arch/x86/kernel/cpu/mtrr/generic.c | 2 +-
drivers/acpi/apei/apei-base.c | 8 ++++----
drivers/acpi/apei/einj.c | 3 +--
drivers/acpi/apei/erst.c | 15 ++++++---------
drivers/acpi/apei/ghes.c | 35 +++++++++++++++++------------------
drivers/acpi/apei/hest.c | 11 +++++------
drivers/cpufreq/acpi-cpufreq.c | 4 ++--
drivers/cpufreq/powernow-k8.c | 2 +-
drivers/firmware/efi/cper.c | 2 +-
include/asm-generic/bug.h | 21 +++++++++++++++++++++
include/linux/printk.h | 1 -
12 files changed, 60 insertions(+), 46 deletions(-)
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index bca023b..1533b59 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -620,7 +620,7 @@ static void init_amd(struct cpuinfo_x86 *c)
rdmsrl(0xc0011005, value);
if (value & (1ULL << 54)) {
set_cpu_cap(c, X86_FEATURE_TOPOEXT);
- printk(KERN_INFO FW_INFO "CPU: Re-enabling "
+ printk(KERN_INFO FW_BUG "CPU: Re-enabling "
"disabled Topology Extensions Support\n");
}
}
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index ce2d0a2..bbab418 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -55,7 +55,7 @@ static inline void k8_check_syscfg_dram_mod_en(void)
rdmsr(MSR_K8_SYSCFG, lo, hi);
if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) {
- printk(KERN_ERR FW_WARN "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
+ printk(KERN_ERR FW_BUG "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
" not cleared by BIOS, clearing this bit\n",
smp_processor_id());
lo &= ~K8_MTRRFIXRANGE_DRAM_MODIFY;
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index 6d2c49b..bba2bd5 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -182,7 +182,7 @@ rewind:
if (ip == ctx->ip) {
if (entry->instruction >= ctx->instructions ||
!ctx->ins_table[entry->instruction].run) {
- pr_warning(FW_WARN APEI_PFX
+ FW_WARN(1, APEI_PFX
"Invalid action table, unknown instruction type: %d\n",
entry->instruction);
return -EINVAL;
@@ -223,9 +223,9 @@ static int apei_exec_for_each_entry(struct apei_exec_context *ctx,
if (end)
*end = i;
if (ins >= ctx->instructions || !ins_table[ins].run) {
- pr_warning(FW_WARN APEI_PFX
- "Invalid action table, unknown instruction type: %d\n",
- ins);
+ FW_WARN(1, APEI_PFX
+ "Invalid action table, unknown instruction type: %d\n",
+ ins);
return -EINVAL;
}
rc = func(ctx, entry, data);
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index fb57d03..b32bda7 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -183,8 +183,7 @@ static int einj_get_available_error_type(u32 *type)
static int einj_timedout(u64 *t)
{
if ((s64)*t < SPIN_UNIT) {
- pr_warning(FW_WARN EINJ_PFX
- "Firmware does not respond in time\n");
+ FW_WARN(1, EINJ_PFX "Firmware does not respond in time\n");
return 1;
}
*t -= SPIN_UNIT;
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 26311f2..dd47b38 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -110,7 +110,7 @@ static inline int erst_errno(int command_status)
static int erst_timedout(u64 *t, u64 spin_unit)
{
if ((s64)*t < spin_unit) {
- pr_warn(FW_WARN "Firmware does not respond in time.\n");
+ FW_WARN(1, "Firmware does not respond in time.\n");
return 1;
}
*t -= spin_unit;
@@ -186,9 +186,8 @@ static int erst_exec_stall(struct apei_exec_context *ctx,
if (ctx->value > FIRMWARE_MAX_STALL) {
if (!in_nmi())
- pr_warn(FW_WARN
- "Too long stall time for stall instruction: 0x%llx.\n",
- ctx->value);
+ FW_WARN(1, "Too long stall time for stall instruction: 0x%llx.\n",
+ ctx->value);
stall_time = FIRMWARE_MAX_STALL;
} else
stall_time = ctx->value;
@@ -206,9 +205,8 @@ static int erst_exec_stall_while_true(struct apei_exec_context *ctx,
if (ctx->var1 > FIRMWARE_MAX_STALL) {
if (!in_nmi())
- pr_warn(FW_WARN
- "Too long stall time for stall while true instruction: 0x%llx.\n",
- ctx->var1);
+ FW_WARN(1, "Too long stall time for stall while true instruction: 0x%llx.\n",
+ ctx->var1);
stall_time = FIRMWARE_MAX_STALL;
} else
stall_time = ctx->var1;
@@ -522,8 +520,7 @@ retry:
new_size = clamp_val(new_size, ERST_RECORD_ID_CACHE_SIZE_MIN,
ERST_RECORD_ID_CACHE_SIZE_MAX);
if (new_size <= erst_record_id_cache.size) {
- if (printk_ratelimit())
- pr_warn(FW_WARN "too many record IDs!\n");
+ FW_WARN(printk_ratelimit(), "too many record IDs!\n");
return 0;
}
alloc_size = new_size * sizeof(entries[0]);
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index a30bc31..c84a4b88 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -270,10 +270,9 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic)
goto err_free;
error_block_length = generic->error_block_length;
if (error_block_length > GHES_ESTATUS_MAX_SIZE) {
- pr_warning(FW_WARN GHES_PFX
- "Error status block length is too long: %u for "
- "generic hardware error source: %d.\n",
- error_block_length, generic->header.source_id);
+ FW_WARN(1,
+ GHES_PFX "Error status block length is too long: %u for generic hardware error source: %d.\n",
+ error_block_length, generic->header.source_id);
error_block_length = GHES_ESTATUS_MAX_SIZE;
}
ghes->estatus = kmalloc(error_block_length, GFP_KERNEL);
@@ -361,9 +360,9 @@ static int ghes_read_estatus(struct ghes *ghes, int silent)
rc = apei_read(&buf_paddr, &g->error_status_address);
if (rc) {
if (!silent && printk_ratelimit())
- pr_warning(FW_WARN GHES_PFX
-"Failed to read error status block address for hardware error source: %d.\n",
- g->header.source_id);
+ FW_WARN(1,
+ GHES_PFX "Failed to read error status block address for hardware error source: %d.\n",
+ g->header.source_id);
return -EIO;
}
if (!buf_paddr)
@@ -393,9 +392,8 @@ static int ghes_read_estatus(struct ghes *ghes, int silent)
rc = 0;
err_read_block:
- if (rc && !silent && printk_ratelimit())
- pr_warning(FW_WARN GHES_PFX
- "Failed to read error status block!\n");
+ FW_INFO((rc && !silent && printk_ratelimit()),
+ GHES_PFX "Failed to read error status block!\n");
return rc;
}
@@ -423,10 +421,10 @@ static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev)
pfn = mem_err->physical_addr >> PAGE_SHIFT;
if (pfn_valid(pfn))
memory_failure_queue(pfn, 0, MF_SOFT_OFFLINE);
- else if (printk_ratelimit())
- pr_warn(FW_WARN GHES_PFX
- "Invalid address in generic error data: %#llx\n",
- mem_err->physical_addr);
+ else
+ FW_INFO((printk_ratelimit()),
+ GHES_PFX "Invalid address in generic error data: %#llx\n",
+ mem_err->physical_addr);
}
if (sev == GHES_SEV_RECOVERABLE &&
sec_sev == GHES_SEV_RECOVERABLE &&
@@ -686,8 +684,9 @@ static void ghes_add_timer(struct ghes *ghes)
unsigned long expire;
if (!g->notify.poll_interval) {
- pr_warning(FW_WARN GHES_PFX "Poll interval is 0 for generic hardware error source: %d, disabled.\n",
- g->header.source_id);
+ FW_WARN(1,
+ GHES_PFX "Poll interval is 0 for generic hardware error source: %d, disabled.\n",
+ g->header.source_id);
return;
}
expire = jiffies + msecs_to_jiffies(g->notify.poll_interval);
@@ -916,8 +915,8 @@ static int ghes_probe(struct platform_device *ghes_dev)
generic->header.source_id);
goto err;
default:
- pr_warning(FW_WARN GHES_PFX "Unknown notification type: %u for generic hardware error source: %d\n",
- generic->notify.type, generic->header.source_id);
+ FW_WARN(1, GHES_PFX "Unknown notification type: %u for generic hardware error source: %d\n",
+ generic->notify.type, generic->header.source_id);
goto err;
}
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index f5e37f3..4c74bca 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -97,10 +97,9 @@ int apei_hest_parse(apei_hest_func_t func, void *data)
for (i = 0; i < hest_tab->error_source_count; i++) {
len = hest_esrc_len(hest_hdr);
if (!len) {
- pr_warning(FW_WARN HEST_PFX
- "Unknown or unused hardware error source "
- "type: %d for hardware error source: %d.\n",
- hest_hdr->type, hest_hdr->source_id);
+ FW_WARN(1, HEST_PFX
+ "Unknown or unused hardware error source type: %d for hardware error source: %d.\n",
+ hest_hdr->type, hest_hdr->source_id);
return -EINVAL;
}
if ((void *)hest_hdr + len >
@@ -187,8 +186,8 @@ static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data)
ghes_dev = ghes_arr->ghes_devs[i];
hdr = *(struct acpi_hest_header **)ghes_dev->dev.platform_data;
if (hdr->source_id == hest_hdr->source_id) {
- pr_warning(FW_WARN HEST_PFX "Duplicated hardware error source ID: %d.\n",
- hdr->source_id);
+ FW_WARN(1, HEST_PFX "Duplicated hardware error source ID: %d.\n",
+ hdr->source_id);
return -EIO;
}
}
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index caf41eb..824c0a7 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -813,8 +813,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
if (result)
goto err_freqfree;
- if (perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq)
- printk(KERN_WARNING FW_WARN "P-state 0 is not max freq\n");
+ FW_INFO((perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq),
+ "P-state 0 is not max freq\n");
switch (perf->control_register.space_id) {
case ACPI_ADR_SPACE_SYSTEM_IO:
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 0023c7d..6a521ff 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -917,7 +917,7 @@ static int get_transition_latency(struct powernow_k8_data *data)
max_latency = cur_latency;
}
if (max_latency == 0) {
- pr_err(FW_WARN PFX "Invalid zero transition latency\n");
+ FW_WARN(1, PFX "Invalid zero transition latency\n");
max_latency = 1;
}
/* value in usecs, needs to be in nanoseconds */
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
index 1491dd4..e242265 100644
--- a/drivers/firmware/efi/cper.c
+++ b/drivers/firmware/efi/cper.c
@@ -340,7 +340,7 @@ static void cper_estatus_print_section(
return;
err_section_too_small:
- pr_err(FW_WARN "error section length is too small\n");
+ FW_WARN(1, "error section length is too small\n");
}
void cper_estatus_print(const char *pfx,
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index b3cb4ed..e829d76 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -130,6 +130,14 @@ extern void warn_slowpath_null(const char *file, const int line);
})
#define FW_INFO(condition, format...) FW_INFO_DEV(condition, NULL, format)
+#define FW_WARN_DEV(condition, dev, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ if (unlikely(__ret_warn_on)) \
+ __WARN_printf_dev(dev, 2, format); \
+ unlikely(__ret_warn_on); \
+})
+#define FW_WARN(condition, format...) FW_WARN_DEV(condition, NULL, format)
+
#else /* !CONFIG_BUG */
#ifndef HAVE_ARCH_BUG
#define BUG() do {} while(0)
@@ -166,6 +174,19 @@ extern void warn_slowpath_null(const char *file, const int line);
pr_info(format); \
unlikely(__ret_warn_on); \
})
+
+#define FW_WARN_DEV(condition, dev, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ dev_warn(format); \
+ unlikely(__ret_warn_on); \
+})
+
+#define FW_WARN(condition, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ pr_warn(format); \
+ unlikely(__ret_warn_on); \
+})
+
#endif
#define WARN_ON_ONCE(condition) ({ \
diff --git a/include/linux/printk.h b/include/linux/printk.h
index db540cc..c5cf420 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -71,7 +71,6 @@ struct va_format {
* and medium priority BIOS bugs.
*/
#define FW_BUG "[Firmware Bug]: "
-#define FW_WARN "[Firmware Warn]: "
/*
* HW_ERR
--
1.7.9.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/3] Introduce FW_BUG* functions and messages
2013-12-02 15:19 [PATCH 0/3] Add Firmware Info, Warn, and Bug messages Prarit Bhargava
2013-12-02 15:19 ` [PATCH 1/3] Introduce FW_INFO* functions and messages Prarit Bhargava
2013-12-02 15:19 ` [PATCH 2/3] Introduce FW_WARN* " Prarit Bhargava
@ 2013-12-02 15:19 ` Prarit Bhargava
2013-12-02 17:34 ` [PATCH 0/3] Add Firmware Info, Warn, and Bug messages Joe Perches
3 siblings, 0 replies; 14+ messages in thread
From: Prarit Bhargava @ 2013-12-02 15:19 UTC (permalink / raw)
To: linux-kernel
Cc: Prarit Bhargava, Arnd Bergmann, Andrew Morton, Greg Kroah-Hartman
Logging and tracking firmware bugs in the kernel has long been an issue
for system administrators. The current kernel does not have a good
uniform method of reporting firmware bugs and the code in the kernel is a
mix of printk's and WARN_ONs. This causes problems for both system
administrators and QA engineers who attempt to diagnose problems within
the kernel.
Using printk's is somewhat effective but lacks information useful for
reporting a bug such as the system vendor or model, BIOS revision, etc.
Using WARN_ONs is also questionable because the data like the backtrace
and the list of modules is usually unnecessary for firmware issues as the
warning stems from one call path during system or driver initialization.
We have heard many complaints from users about the excess verbosity and
confusing stacktraces for these messages.
I'm proposing with this patch to do something similar to the WARN()
mechanism that is currently implemented in the kernel. This patchset
introduces FW_BUG() and FW_BUG_DEV() which logs output like:
[ 230.661137] [Firmware Bug]: pci_bus 0000:00: at
/home/prarit_modules/prarit.c:21 Your BIOS is broken because it is
-ENOWORKY. [ 230.671076] [Firmware Bug]: Intel Corporation SandyBridge
Platform/To be filled by O.E.M., BIOS RMLCRB.86I.R3.27.D685.1305151733
05/15/2013
instead of the verbose back traces we are currently seeing. These
messages can be easily gleaned from /var/log/messages, etc., by automatic
bug reporting tools and system administrators to properly report bugs to
hardware vendors.
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/apic/apic.c | 8 ++---
arch/x86/kernel/cpu/amd.c | 9 +++--
arch/x86/kernel/cpu/mcheck/mce.c | 2 +-
arch/x86/kernel/cpu/mcheck/mce_amd.c | 12 +++----
arch/x86/kernel/cpu/mtrr/generic.c | 4 +--
arch/x86/kernel/cpu/perf_event.c | 8 ++---
arch/x86/kernel/cpu/perf_event_amd_ibs.c | 10 +++---
arch/x86/pci/mmconfig-shared.c | 3 +-
drivers/acpi/apei/apei-base.c | 32 +++++++++---------
drivers/acpi/apei/einj.c | 6 ++--
drivers/acpi/apei/erst.c | 2 +-
drivers/acpi/apei/ghes.c | 7 ++--
drivers/acpi/apei/hest.c | 4 +--
drivers/acpi/battery.c | 12 ++++---
drivers/acpi/osl.c | 6 ++--
drivers/acpi/pci_root.c | 4 +--
drivers/acpi/processor_perflib.c | 16 ++++-----
drivers/acpi/thermal.c | 5 ++-
drivers/acpi/video.c | 17 ++++------
drivers/acpi/video_detect.c | 4 +--
drivers/cpufreq/powernow-k8.c | 54 ++++++++++++++----------------
drivers/firmware/dmi_scan.c | 2 +-
drivers/iommu/amd_iommu_init.c | 24 ++++++++-----
drivers/iommu/dmar.c | 3 +-
drivers/iommu/intel_irq_remapping.c | 4 +--
drivers/pci/quirks.c | 2 +-
drivers/pnp/quirks.c | 4 +--
include/asm-generic/bug.h | 22 ++++++++++++
include/linux/printk.h | 16 ---------
29 files changed, 149 insertions(+), 153 deletions(-)
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index d278736..d5a3ff7 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -437,17 +437,13 @@ int setup_APIC_eilvt(u8 offset, u8 vector, u8 msg_type, u8 mask)
reserved = reserve_eilvt_offset(offset, new);
if (reserved != new) {
- pr_err(FW_BUG "cpu %d, try to use APIC%lX (LVT offset %d) for "
- "vector 0x%x, but the register is already in use for "
- "vector 0x%x on another cpu\n",
+ FW_WARN(1, "cpu %d, try to use APIC%lX (LVT offset %d) for vector 0x%x, but the register is already in use for vector 0x%x on another cpu\n",
smp_processor_id(), reg, offset, new, reserved);
return -EINVAL;
}
if (!eilvt_entry_is_changeable(old, new)) {
- pr_err(FW_BUG "cpu %d, try to use APIC%lX (LVT offset %d) for "
- "vector 0x%x, but the register is already in use for "
- "vector 0x%x on this cpu\n",
+ FW_WARN(1, "cpu %d, try to use APIC%lX (LVT offset %d) for vector 0x%x, but the register is already in use for vector 0x%x on this cpu\n",
smp_processor_id(), reg, offset, new, old);
return -EBUSY;
}
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 1533b59..e33636c 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -456,9 +456,8 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
u64 val;
rdmsrl(MSR_K7_HWCR, val);
- if (!(val & BIT(24)))
- printk(KERN_WARNING FW_BUG "TSC doesn't count "
- "with P0 frequency!\n");
+ FW_INFO((!(val & BIT(24))),
+ "TSC doesn't count with P0 frequency!\n");
}
}
@@ -620,8 +619,8 @@ static void init_amd(struct cpuinfo_x86 *c)
rdmsrl(0xc0011005, value);
if (value & (1ULL << 54)) {
set_cpu_cap(c, X86_FEATURE_TOPOEXT);
- printk(KERN_INFO FW_BUG "CPU: Re-enabling "
- "disabled Topology Extensions Support\n");
+ FW_BUG(1,
+ "CPU: Re-enabling disabled Topology Extensions Support\n");
}
}
}
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index b3218cd..326e58d 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -1954,7 +1954,7 @@ static void __mce_disable_bank(void *arg)
void mce_disable_bank(int bank)
{
if (bank >= mca_cfg.banks) {
- pr_warn(FW_BUG
+ FW_WARN(1,
"Ignoring request to disable invalid MCA bank %d.\n",
bank);
return;
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 603df4f..e06974f 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -119,16 +119,16 @@ static int lvt_off_valid(struct threshold_block *b, int apic, u32 lo, u32 hi)
int msr = (hi & MASK_LVTOFF_HI) >> 20;
if (apic < 0) {
- pr_err(FW_BUG "cpu %d, failed to setup threshold interrupt "
- "for bank %d, block %d (MSR%08X=0x%x%08x)\n", b->cpu,
- b->bank, b->block, b->address, hi, lo);
+ FW_WARN(1,
+ "cpu %d, failed to setup threshold interrupt for bank %d, block %d (MSR%08X=0x%x%08x)\n",
+ b->cpu, b->bank, b->block, b->address, hi, lo);
return 0;
}
if (apic != msr) {
- pr_err(FW_BUG "cpu %d, invalid threshold interrupt offset %d "
- "for bank %d, block %d (MSR%08X=0x%x%08x)\n",
- b->cpu, apic, b->bank, b->block, b->address, hi, lo);
+ FW_WARN(1,
+ "cpu %d, invalid threshold interrupt offset %d for bank %d, block %d (MSR%08X=0x%x%08x)\n",
+ b->cpu, apic, b->bank, b->block, b->address, hi, lo);
return 0;
}
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index bbab418..831a468 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -55,8 +55,8 @@ static inline void k8_check_syscfg_dram_mod_en(void)
rdmsr(MSR_K8_SYSCFG, lo, hi);
if (lo & K8_MTRRFIXRANGE_DRAM_MODIFY) {
- printk(KERN_ERR FW_BUG "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn]"
- " not cleared by BIOS, clearing this bit\n",
+ FW_BUG(1,
+ "MTRR: CPU %u: SYSCFG[MtrrFixDramModEn] not cleared by BIOS, clearing this bit\n",
smp_processor_id());
lo &= ~K8_MTRRFIXRANGE_DRAM_MODIFY;
mtrr_wrmsr(MSR_K8_SYSCFG, lo, hi);
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c
index 8e13293..1fc4aad 100644
--- a/arch/x86/kernel/cpu/perf_event.c
+++ b/arch/x86/kernel/cpu/perf_event.c
@@ -231,16 +231,14 @@ static bool check_hw_exists(void)
/*
* We still allow the PMU driver to operate:
*/
- if (bios_fail) {
- printk(KERN_CONT "Broken BIOS detected, complain to your hardware vendor.\n");
- printk(KERN_ERR FW_BUG "the BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", reg_fail, val_fail);
- }
+ FW_INFO(bios_fail,
+ "The BIOS has corrupted hw-PMU resources (MSR %x is %Lx)\n", reg_fail, val_fail);
return true;
msr_fail:
printk(KERN_CONT "Broken PMU hardware detected, using software events only.\n");
- printk(KERN_ERR "Failed to access perfctr msr (MSR %x is %Lx)\n", reg, val_new);
+ printk(KERN_ERR HW_ERR "Failed to access perfctr msr (MSR %x is %Lx)\n", reg, val_new);
return false;
}
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
index e09f0bf..461e3be 100644
--- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c
+++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c
@@ -719,14 +719,16 @@ static inline int ibs_eilvt_valid(void)
offset = val & IBSCTL_LVT_OFFSET_MASK;
if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
- pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
- smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
+ FW_WARN(1,
+ "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
+ smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
goto out;
}
if (!get_eilvt(offset)) {
- pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
- smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
+ FW_WARN(1,
+ "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
+ smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
goto out;
}
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 3cb0eff..cf54185 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -718,8 +718,7 @@ int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
dev_warn(dev, "fail to add MMCONFIG (out of memory)\n");
rc = -ENOMEM;
} else if (!pci_mmcfg_check_reserved(dev, cfg, 0)) {
- dev_warn(dev, FW_BUG "MMCONFIG %pR isn't reserved\n",
- &cfg->res);
+ FW_INFO_DEV(1, dev, "MMCONFIG %pR isn't reserved\n", &cfg->res);
} else {
/* Insert resource if it's not in boot stage */
if (pci_mmcfg_running_state)
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index bba2bd5..bcadea3 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -570,18 +570,18 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr,
/* Handle possible alignment issues */
memcpy(paddr, ®->address, sizeof(*paddr));
if (!*paddr) {
- pr_warning(FW_BUG APEI_PFX
- "Invalid physical address in GAR [0x%llx/%u/%u/%u/%u]\n",
- *paddr, bit_width, bit_offset, access_size_code,
- space_id);
+ FW_WARN(1,
+ APEI_PFX "Invalid physical address in GAR [0x%llx/%u/%u/%u/%u]\n",
+ *paddr, bit_width, bit_offset, access_size_code,
+ space_id);
return -EINVAL;
}
if (access_size_code < 1 || access_size_code > 4) {
- pr_warning(FW_BUG APEI_PFX
- "Invalid access size code in GAR [0x%llx/%u/%u/%u/%u]\n",
- *paddr, bit_width, bit_offset, access_size_code,
- space_id);
+ FW_WARN(1,
+ APEI_PFX "Invalid access size code in GAR [0x%llx/%u/%u/%u/%u]\n",
+ *paddr, bit_width, bit_offset, access_size_code,
+ space_id);
return -EINVAL;
}
*access_bit_width = 1UL << (access_size_code + 2);
@@ -595,19 +595,19 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr,
*access_bit_width = 64;
if ((bit_width + bit_offset) > *access_bit_width) {
- pr_warning(FW_BUG APEI_PFX
- "Invalid bit width + offset in GAR [0x%llx/%u/%u/%u/%u]\n",
- *paddr, bit_width, bit_offset, access_size_code,
- space_id);
+ FW_WARN(1,
+ APEI_PFX "Invalid bit width + offset in GAR [0x%llx/%u/%u/%u/%u]\n",
+ *paddr, bit_width, bit_offset, access_size_code,
+ space_id);
return -EINVAL;
}
if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY &&
space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
- pr_warning(FW_BUG APEI_PFX
- "Invalid address space type in GAR [0x%llx/%u/%u/%u/%u]\n",
- *paddr, bit_width, bit_offset, access_size_code,
- space_id);
+ FW_WARN(1,
+ APEI_PFX "Invalid address space type in GAR [0x%llx/%u/%u/%u/%u]\n",
+ *paddr, bit_width, bit_offset, access_size_code,
+ space_id);
return -EINVAL;
}
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index b32bda7..4864cf4 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -326,8 +326,8 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
}
rc = einj_check_trigger_header(trigger_tab);
if (rc) {
- pr_warning(FW_BUG EINJ_PFX
- "The trigger error action table is invalid\n");
+ FW_WARN(1,
+ EINJ_PFX "The trigger error action table is invalid\n");
goto out_rel_header;
}
@@ -691,7 +691,7 @@ static int __init einj_init(void)
rc = einj_check_table(einj_tab);
if (rc) {
- pr_warning(FW_BUG EINJ_PFX "EINJ table is invalid\n");
+ FW_WARN(1, EINJ_PFX "EINJ table is invalid\n");
return -EINVAL;
}
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index dd47b38..17f561c 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -1145,7 +1145,7 @@ static int __init erst_init(void)
rc = erst_check_table(erst_tab);
if (rc) {
- pr_err(FW_BUG "ERST table is invalid.\n");
+ FW_WARN(1, "ERST table is invalid.\n");
goto err;
}
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index c84a4b88..5953995 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -923,9 +923,10 @@ static int ghes_probe(struct platform_device *ghes_dev)
rc = -EIO;
if (generic->error_block_length <
sizeof(struct acpi_generic_status)) {
- pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n",
- generic->error_block_length,
- generic->header.source_id);
+ FW_WARN(1,
+ GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n",
+ generic->error_block_length,
+ generic->header.source_id);
goto err;
}
ghes = ghes_new(generic);
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index 4c74bca..b3b6e79 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -104,8 +104,8 @@ int apei_hest_parse(apei_hest_func_t func, void *data)
}
if ((void *)hest_hdr + len >
(void *)hest_tab + hest_tab->header.length) {
- pr_warning(FW_BUG HEST_PFX
- "Table contents overflow for hardware error source: %d.\n",
+ FW_WARN(1,
+ HEST_PFX "Table contents overflow for hardware error source: %d.\n",
hest_hdr->source_id);
return -EINVAL;
}
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index fbf1ace..24e9e01 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -449,6 +449,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
int result = 0;
acpi_status status = 0;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ static bool print_once;
if (!acpi_battery_present(battery))
return 0;
@@ -477,12 +478,13 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
* charging or discharging current and/or report 0 as 65536
* due to bad math.
*/
- if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
- battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
- (s16)(battery->rate_now) < 0) {
+ if ((print_once == false) &&
+ battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA &&
+ battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN &&
+ (s16)(battery->rate_now) < 0) {
battery->rate_now = abs((s16)battery->rate_now);
- printk_once(KERN_WARNING FW_BUG "battery: (dis)charge rate"
- " invalid.\n");
+ FW_INFO(1, "battery: (dis)charge rate invalid.\n");
+ print_once = true;
}
if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 54a20ff..6550672 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -148,14 +148,12 @@ static struct osi_linux {
static u32 acpi_osi_handler(acpi_string interface, u32 supported)
{
if (!strcmp("Linux", interface)) {
-
- printk_once(KERN_NOTICE FW_BUG PREFIX
- "BIOS _OSI(Linux) query %s%s\n",
+ FW_INFO(1,
+ PREFIX "BIOS _OSI(Linux) query %s%s\n",
osi_linux.enable ? "honored" : "ignored",
osi_linux.cmdline ? " via cmdline" :
osi_linux.dmi ? " via DMI" : "");
}
-
return supported;
}
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 20360e4..cf970ff 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -533,8 +533,8 @@ static int acpi_pci_root_add(struct acpi_device *device,
* can do is assume [_BBN-0xFF] or [0-0xFF].
*/
root->secondary.end = 0xFF;
- dev_warn(&device->dev,
- FW_BUG "no secondary bus range in _CRS\n");
+ FW_INFO_DEV(1, &device->dev,
+ "no secondary bus range in _CRS\n");
status = acpi_evaluate_integer(handle, METHOD_NAME__BBN,
NULL, &bus);
if (ACPI_SUCCESS(status))
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 60a7c28..3ee2ef9 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -404,8 +404,8 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
if (!px->core_frequency ||
((u32)(px->core_frequency * 1000) !=
(px->core_frequency * 1000))) {
- printk(KERN_ERR FW_BUG PREFIX
- "Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n",
+ FW_WARN(1,
+ PREFIX "Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n",
pr->id, px->core_frequency);
if (last_invalid == -1)
last_invalid = i;
@@ -422,8 +422,8 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr)
}
if (last_invalid == 0) {
- printk(KERN_ERR FW_BUG PREFIX
- "No valid BIOS _PSS frequency found for processor %d\n", pr->id);
+ FW_WARN(1,
+ PREFIX "No valid BIOS _PSS frequency found for processor %d\n", pr->id);
result = -EFAULT;
kfree(pr->performance->states);
pr->performance->states = NULL;
@@ -471,11 +471,9 @@ int acpi_processor_get_performance_info(struct acpi_processor *pr)
*/
update_bios:
#ifdef CONFIG_X86
- if (acpi_has_method(pr->handle, "_PPC")) {
- if(boot_cpu_has(X86_FEATURE_EST))
- printk(KERN_WARNING FW_BUG "BIOS needs update for CPU "
- "frequency support\n");
- }
+ FW_INFO((acpi_has_method(pr->handle, "_PPC") &&
+ boot_cpu_has(X86_FEATURE_EST)),
+ "BIOS needs update for CPU frequency support\n");
#endif
return result;
}
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 0d9f46b..03da53a 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -299,8 +299,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"No critical threshold\n"));
} else if (tmp <= 2732) {
- pr_warn(FW_BUG "Invalid critical threshold (%llu)\n",
- tmp);
+ FW_WARN(1, "Invalid critical threshold (%llu)\n", tmp);
tz->trips.critical.flags.valid = 0;
} else {
tz->trips.critical.flags.valid = 1;
@@ -504,7 +503,7 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
valid |= tz->trips.active[i].flags.valid;
if (!valid) {
- pr_warn(FW_BUG "No valid trip found\n");
+ FW_WARN(1, "No valid trip found\n");
return -ENODEV;
}
return 0;
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 995e91b..cf32eee 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -833,7 +833,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
if (acpi_has_method(device->dev->handle, "_BQC")) {
device->cap._BQC = 1;
} else if (acpi_has_method(device->dev->handle, "_BCQ")) {
- printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
+ FW_WARN(1, "_BCQ is used instead of _BQC\n");
device->cap._BCQ = 1;
}
@@ -892,11 +892,9 @@ static int acpi_video_bus_check(struct acpi_video_bus *video)
/* Does this device support video switching? */
if (video->cap._DOS || video->cap._DOD) {
- if (!video->cap._DOS) {
- printk(KERN_WARNING FW_BUG
- "ACPI(%s) defines _DOD but not _DOS\n",
- acpi_device_bid(video->device));
- }
+ FW_WARN((!video->cap._DOS),
+ "ACPI(%s) defines _DOD but not _DOS\n",
+ acpi_device_bid(video->device));
video->flags.multihead = 1;
status = 0;
}
@@ -1746,11 +1744,8 @@ static int acpi_video_bus_add(struct acpi_device *device)
acpi_video_bus_match, NULL,
device, NULL);
if (status == AE_ALREADY_EXISTS) {
- printk(KERN_WARNING FW_BUG
- "Duplicate ACPI video bus devices for the"
- " same VGA controller, please try module "
- "parameter \"video.allow_duplicates=1\""
- "if the current driver doesn't work.\n");
+ FW_INFO(1,
+ "Duplicate ACPI video bus devices for the same VGA controller, please try module parameter \"video.allow_duplicates=1\" if the current driver doesn't work.\n");
if (!allow_duplicates)
return -ENODEV;
}
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 84875fd..fb6e817 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -60,8 +60,8 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
"support\n"));
*cap |= ACPI_VIDEO_BACKLIGHT;
if (!acpi_has_method(handle, "_BQC"))
- printk(KERN_WARNING FW_BUG PREFIX "No _BQC method, "
- "cannot determine initial brightness\n");
+ FW_WARN(1,
+ "No _BQC method, cannot determine initial brightness\n");
/* We have backlight support, no need to scan further */
return AE_CTRL_TERMINATE;
}
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 6a521ff..1ea9308 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -529,43 +529,39 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
for (j = 0; j < data->numps; j++) {
if (pst[j].vid > LEAST_VID) {
- printk(KERN_ERR FW_BUG PFX "vid %d invalid : 0x%x\n",
- j, pst[j].vid);
+ FW_WARN(1, PFX "vid %d invalid : 0x%x\n",
+ j, pst[j].vid);
return -EINVAL;
}
if (pst[j].vid < data->rvo) {
/* vid + rvo >= 0 */
- printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate"
- " %d\n", j);
+ FW_WARN(1, PFX "0 vid exceeded with pstate %d\n", j);
return -ENODEV;
}
if (pst[j].vid < maxvid + data->rvo) {
/* vid + rvo >= maxvid */
- printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate"
- " %d\n", j);
+ FW_WARN(1, PFX "maxvid exceeded with pstate %d\n", j);
return -ENODEV;
}
if (pst[j].fid > MAX_FID) {
- printk(KERN_ERR FW_BUG PFX "maxfid exceeded with pstate"
- " %d\n", j);
+ FW_WARN(1, PFX "maxfid exceeded with pstate %d\n", j);
return -ENODEV;
}
if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
/* Only first fid is allowed to be in "low" range */
- printk(KERN_ERR FW_BUG PFX "two low fids - %d : "
- "0x%x\n", j, pst[j].fid);
+ FW_WARN(1, PFX "two low fids - %d : 0x%x\n",
+ j, pst[j].fid);
return -EINVAL;
}
if (pst[j].fid < lastfid)
lastfid = pst[j].fid;
}
if (lastfid & 1) {
- printk(KERN_ERR FW_BUG PFX "lastfid invalid\n");
+ FW_WARN(1, PFX "lastfid invalid\n");
return -EINVAL;
}
- if (lastfid > LO_FID_TABLE_TOP)
- printk(KERN_INFO FW_BUG PFX
- "first fid not from lo freq table\n");
+ FW_INFO((lastfid > LO_FID_TABLE_TOP),
+ PFX "first fid not from lo freq table\n");
return 0;
}
@@ -681,13 +677,13 @@ static int find_psb_table(struct powernow_k8_data *data)
pr_debug("table vers: 0x%x\n", psb->tableversion);
if (psb->tableversion != PSB_VERSION_1_4) {
- printk(KERN_ERR FW_BUG PFX "PSB table is not v1.4\n");
+ FW_WARN(1, PFX "PSB table is not v1.4\n");
return -ENODEV;
}
pr_debug("flags: 0x%x\n", psb->flags1);
if (psb->flags1) {
- printk(KERN_ERR FW_BUG PFX "unknown flags\n");
+ FW_WARN(1, PFX "unknown flags\n");
return -ENODEV;
}
@@ -716,7 +712,7 @@ static int find_psb_table(struct powernow_k8_data *data)
cpst = 1;
}
if (cpst != 1) {
- printk(KERN_ERR FW_BUG PFX "numpst must be 1\n");
+ FW_WARN(1, PFX "numpst must be 1\n");
return -ENODEV;
}
@@ -742,9 +738,8 @@ static int find_psb_table(struct powernow_k8_data *data)
* BIOS and Kernel Developer's Guide, which is available on
* www.amd.com
*/
- printk(KERN_ERR FW_BUG PFX "No PSB or ACPI _PSS objects\n");
- printk(KERN_ERR PFX "Make sure that your BIOS is up to date"
- " and Cool'N'Quiet support is enabled in BIOS setup\n");
+ FW_INFO(1,
+ PFX "No PSB or ACPI _PSS objects. Make sure that your BIOS is up to date and Cool'N'Quiet support is enabled in BIOS setup\n");
return -ENODEV;
}
@@ -1072,9 +1067,9 @@ static void powernowk8_cpu_init_on_cpu(void *_init_on_cpu)
static const char missing_pss_msg[] =
KERN_ERR
- FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
- FW_BUG PFX "First, make sure Cool'N'Quiet is enabled in the BIOS.\n"
- FW_BUG PFX "If that doesn't help, try upgrading your BIOS.\n";
+ PFX "No compatible ACPI _PSS objects found.\n"
+ PFX "First, make sure Cool'N'Quiet is enabled in the BIOS.\n"
+ PFX "If that doesn't help, try upgrading your BIOS.\n";
/* per CPU init entry point to the driver */
static int powernowk8_cpu_init(struct cpufreq_policy *pol)
@@ -1082,6 +1077,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol)
struct powernow_k8_data *data;
struct init_on_cpu init_on_cpu;
int rc;
+ static bool print_once;
smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1);
if (rc)
@@ -1101,13 +1097,15 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol)
* an UP version, and is deprecated by AMD.
*/
if (num_online_cpus() != 1) {
- printk_once(missing_pss_msg);
+ if (print_once == false) {
+ FW_WARN(1, missing_pss_msg);
+ print_once = true;
+ }
goto err_out;
}
if (pol->cpu != 0) {
- printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for "
- "CPU other than CPU0. Complain to your BIOS "
- "vendor.\n");
+ FW_WARN(1,
+ PFX "No ACPI _PSS objects for CPU other than CPU0.\n");
goto err_out;
}
rc = find_psb_table(data);
@@ -1135,7 +1133,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol)
/* min/max the cpu is capable of */
if (cpufreq_table_validate_and_show(pol, data->powernow_table)) {
- printk(KERN_ERR FW_BUG PFX "invalid powernow_table\n");
+ FW_WARN(1, PFX "invalid powernow_table\n");
powernow_k8_cpu_exit_acpi(data);
kfree(data->powernow_table);
kfree(data);
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index c7e81ff..b9623af 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -345,7 +345,7 @@ static void __init save_mem_devices(const struct dmi_header *dm, void *v)
if (dm->type != DMI_ENTRY_MEM_DEVICE)
return;
if (nr >= dmi_memdev_nr) {
- pr_warn(FW_BUG "Too many DIMM entries in SMBIOS table\n");
+ FW_WARN(1, "Too many DIMM entries in SMBIOS table\n");
return;
}
dmi_memdev[nr].handle = get_unaligned(&dm->handle);
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
index 8f798be..2e10c54 100644
--- a/drivers/iommu/amd_iommu_init.c
+++ b/drivers/iommu/amd_iommu_init.c
@@ -1728,7 +1728,6 @@ static void __init free_on_init_error(void)
static bool __init check_ioapic_information(void)
{
- const char *fw_bug = FW_BUG;
bool ret, has_sb_ioapic;
int idx;
@@ -1736,20 +1735,23 @@ static bool __init check_ioapic_information(void)
ret = false;
/*
- * If we have map overrides on the kernel command line the
- * messages in this function might not describe firmware bugs
- * anymore - so be careful
+ * If we have map overrides on the kernel command line,
+ * ie) cmdline_maps is true, then the messages in this function
+ * might not describe firmware bugs anymore.
*/
- if (cmdline_maps)
- fw_bug = "";
for (idx = 0; idx < nr_ioapics; idx++) {
int devid, id = mpc_ioapic_id(idx);
devid = get_ioapic_devid(id);
if (devid < 0) {
- pr_err("%sAMD-Vi: IOAPIC[%d] not in IVRS table\n",
- fw_bug, id);
+ if (cmdline_maps)
+ pr_err("AMD-Vi: IOAPIC[%d] not in IVRS table\n",
+ id);
+ else
+ FW_WARN(1,
+ "AMD-Vi: IOAPIC[%d] not in IVRS table\n",
+ id);
ret = false;
} else if (devid == IOAPIC_SB_DEVID) {
has_sb_ioapic = true;
@@ -1766,7 +1768,11 @@ static bool __init check_ioapic_information(void)
* when the BIOS is buggy and provides us the wrong
* device id for the IOAPIC in the system.
*/
- pr_err("%sAMD-Vi: No southbridge IOAPIC found\n", fw_bug);
+ if (cmdline_maps)
+ pr_err("AMD-Vi: No southbridge IOAPIC found\n");
+ else
+ FW_INFO(1, "AMD-Vi: No southbridge IOAPIC found\n");
+
}
if (!ret)
diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
index 8b452c9..941ef5c 100644
--- a/drivers/iommu/dmar.c
+++ b/drivers/iommu/dmar.c
@@ -373,8 +373,7 @@ parse_dmar_table(void)
entry_header = ((void *)entry_header + entry_header->length);
}
- if (drhd_count == 0)
- pr_warn(FW_BUG "No DRHD structure found in DMAR table\n");
+ FW_INFO(!drhd_count, "No DRHD structure found in DMAR table\n");
return ret;
}
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
index bab10b1..489c448 100644
--- a/drivers/iommu/intel_irq_remapping.c
+++ b/drivers/iommu/intel_irq_remapping.c
@@ -797,8 +797,8 @@ int __init parse_ioapics_under_ir(void)
for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) {
int ioapic_id = mpc_ioapic_id(ioapic_idx);
if (!map_ioapic_to_ir(ioapic_id)) {
- pr_err(FW_BUG "ioapic %d has no mapping iommu, "
- "interrupt remapping will be disabled\n",
+ FW_WARN(1,
+ "ioapic %d has no mapping iommu, interrupt remapping will be disabled\n",
ioapic_id);
return -1;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 3a02717..e84a8a9 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -112,7 +112,7 @@ static void quirk_tigerpoint_bm_sts(struct pci_dev *dev)
pm1a = inw(pmbase);
if (pm1a & 0x10) {
- dev_info(&dev->dev, FW_BUG "TigerPoint LPC.BM_STS cleared\n");
+ FW_WARN_DEV(1, &dev->dev, "TigerPoint LPC.BM_STS cleared\n");
outw(0x10, pmbase);
}
}
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c
index 258fef2..78b4ea2 100644
--- a/drivers/pnp/quirks.c
+++ b/drivers/pnp/quirks.c
@@ -316,8 +316,8 @@ static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
(res->start == mmconfig->start && res->end == mmconfig->end))
continue;
- dev_info(&dev->dev, FW_BUG
- "%pR covers only part of AMD MMCONFIG area %pR; adding more reservations\n",
+ FW_WARN_DEV(1, &dev->dev,
+ "%pR covers only part of AMD MMCONFIG area %pR; adding more reservations\n",
res, mmconfig);
if (mmconfig->start < res->start) {
start = mmconfig->start;
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index e829d76..a3dee84 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -138,6 +138,15 @@ extern void warn_slowpath_null(const char *file, const int line);
})
#define FW_WARN(condition, format...) FW_WARN_DEV(condition, NULL, format)
+#define FW_BUG_DEV(condition, dev, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ if (unlikely(__ret_warn_on)) \
+ __WARN_printf_dev(dev, 3, format); \
+ unlikely(__ret_warn_on); \
+})
+#define FW_BUG(condition, format...) FW_BUG_DEV(condition, NULL, format)
+
+
#else /* !CONFIG_BUG */
#ifndef HAVE_ARCH_BUG
#define BUG() do {} while(0)
@@ -187,6 +196,19 @@ extern void warn_slowpath_null(const char *file, const int line);
unlikely(__ret_warn_on); \
})
+#define FW_BUG_DEV(condition, dev, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ dev_warn(format); \
+ unlikely(__ret_warn_on); \
+})
+
+#define FW_BUG(condition, format...) ({ \
+ int __ret_warn_on = !!(condition); \
+ pr_warn(format); \
+ unlikely(__ret_warn_on); \
+})
+
+
#endif
#define WARN_ON_ONCE(condition) ({ \
diff --git a/include/linux/printk.h b/include/linux/printk.h
index c5cf420..4fafb68 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -57,22 +57,6 @@ struct va_format {
};
/*
- * FW_BUG
- * Add this to a message where you are sure the firmware is buggy or behaves
- * really stupid or out of spec. Be aware that the responsible BIOS developer
- * should be able to fix this issue or at least get a concrete idea of the
- * problem by reading your message without the need of looking at the kernel
- * code.
- *
- * Use it for definite and high priority BIOS bugs.
- *
- * FW_WARN
- * Use it for not that clear (e.g. could the kernel messed up things already?)
- * and medium priority BIOS bugs.
- */
-#define FW_BUG "[Firmware Bug]: "
-
-/*
* HW_ERR
* Add this to a message for hardware errors, so that user can report
* it to hardware vendor instead of LKML or software vendor.
--
1.7.9.3
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 0/3] Add Firmware Info, Warn, and Bug messages
2013-12-02 15:19 [PATCH 0/3] Add Firmware Info, Warn, and Bug messages Prarit Bhargava
` (2 preceding siblings ...)
2013-12-02 15:19 ` [PATCH 3/3] Introduce FW_BUG* " Prarit Bhargava
@ 2013-12-02 17:34 ` Joe Perches
3 siblings, 0 replies; 14+ messages in thread
From: Joe Perches @ 2013-12-02 17:34 UTC (permalink / raw)
To: Prarit Bhargava
Cc: linux-kernel, Arnd Bergmann, Andrew Morton, Greg Kroah-Hartman
On Mon, 2013-12-02 at 10:19 -0500, Prarit Bhargava wrote:
> Logging and tracking firmware bugs in the kernel has long been an issue
> for system administrators. The current kernel does not have a good
> uniform method of reporting firmware bugs and the code in the kernel is a
> mix of printk's and WARN_ONs. This causes problems for both system
> administrators and QA engineers who attempt to diagnose problems within
> the kernel.
It'd be simpler if you introduced the macros in one patch
and then added patches that used them separately.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Introduce FW_INFO* functions and messages
2013-12-02 15:19 ` [PATCH 1/3] Introduce FW_INFO* functions and messages Prarit Bhargava
@ 2013-12-03 21:21 ` Andrew Morton
2013-12-04 11:51 ` Prarit Bhargava
2013-12-04 18:22 ` Arnd Bergmann
0 siblings, 2 replies; 14+ messages in thread
From: Andrew Morton @ 2013-12-03 21:21 UTC (permalink / raw)
To: Prarit Bhargava; +Cc: linux-kernel, Arnd Bergmann, Greg Kroah-Hartman
On Mon, 2 Dec 2013 10:19:37 -0500 Prarit Bhargava <prarit@redhat.com> wrote:
> Logging and tracking firmware bugs in the kernel has long been an issue
> for system administrators. The current kernel does not have a good
> uniform method of reporting firmware bugs and the code in the kernel is a
> mix of printk's and WARN_ONs. This causes problems for both system
> administrators and QA engineers who attempt to diagnose problems within
> the kernel.
>
> Using printk's is somewhat effective but lacks information useful for
> reporting a bug such as the system vendor or model, BIOS revision, etc.
> Using WARN_ONs is also questionable because the data like the backtrace
> and the list of modules is usually unnecessary for firmware issues as the
> warning stems from one call path during system or driver initialization.
> We have heard many complaints from users about the excess verbosity and
> confusing stacktraces for these messages.
>
> I'm proposing with this patch to do something similar to the WARN()
> mechanism that is currently implemented in the kernel. This
> patchset introduces FW_INFO() and FW_INFO_DEV() which logs output like:
>
> [ 230.661137] [Firmware Info]: pci_bus 0000:00: at
> /home/prarit_modules/prarit.c:21 Your BIOS is broken because it is
> -ENOWORKY.
> [ 230.671076] [Firmware Info]: Intel Corporation SandyBridge Platform/To
> be filled by O.E.M., BIOS RMLCRB.86I.R3.27.D685.1305151733 05/15/2013
>
> instead of the verbose back traces we are currently seeing. These messages
> can be easily gleaned from /var/log/messages, etc., by automatic bug
> reporting tools and system administrators to properly report bugs to
> hardware vendors.
>
> I found an improperly classified FW_INFO in arch/x86/kernel/cpu/amd.c
> which that should be a FW_BUG.
A slight simplification:
> +static inline char *dump_hadware_arch_desc(void)
> +{
> + return NULL;
> +}
return "unavailable";
> +void warn_slowpath_fmt_dev(const char *file, int line,
> + struct device *dev, int level, const char *fmt, ...)
> +{
> + struct slowpath_args args;
> + static char fw_str[16] = "\0";
> +
> + switch (level) {
> + case 1:
> + strcpy(fw_str, "[Firmware Info]");
> + break;
> + case 2:
> + strcpy(fw_str, "[Firmware Warn]");
> + break;
> + case 3:
> + strcpy(fw_str, "[Firmware Bug]");
What's With The Crazy Capitalization In This Code? It's Illiterate!
> + add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
> + break;
> + default:
> + strcpy(fw_str, "[Firmware Bug]");
> + break;
> + }
> +
> + if (dev)
> + pr_info("%s: %s %s ", fw_str,
> + dev_driver_string(dev), dev_name(dev));
> + pr_info("%s: at %s:%d\n", fw_str, file, line);
> +
> + args.fmt = fmt;
> + va_start(args.args, fmt);
> + printk(KERN_WARNING "%s: %pV", fw_str, &args);
> + va_end(args.args);
> +
> + if (dump_hardware_arch_desc())
> + pr_info("%s: System Info: %s\n", fw_str,
> + dump_hardware_arch_desc());
> + else
> + pr_info("%s: System Info: Hardware Unidentified\n", fw_str);
pr_info(""%s: system info: %s\n", fw_str, dump_hardware_arch_desc());
> +}
> +EXPORT_SYMBOL(warn_slowpath_fmt_dev);
> +
> +
> +char *dump_hardware_arch_desc(void)
> +{
> + if (dump_stack_arch_desc_str[0] != '\0')
> + return dump_stack_arch_desc_str;
> + return NULL;
return "unavaliable";
> +}
The general thrust of the patchset seems useful and important. I do
agree with Joe's suggestion regarding the presentation, although it
isn't a show-stopper.
I do wonder if it all should be generalised a bit - it creates a bunch
of infrastructure which is specific to system firmware issues, but
what's so special about firmware? Why can't I use this infrastructure
to log netdev errors or acpi errors or PM errors or...? But I didn't
think about it much ;)
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Introduce FW_INFO* functions and messages
2013-12-03 21:21 ` Andrew Morton
@ 2013-12-04 11:51 ` Prarit Bhargava
2013-12-04 17:20 ` Joe Perches
2013-12-04 18:22 ` Arnd Bergmann
1 sibling, 1 reply; 14+ messages in thread
From: Prarit Bhargava @ 2013-12-04 11:51 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, Arnd Bergmann, Greg Kroah-Hartman, Joe Perches
On 12/03/2013 04:21 PM, Andrew Morton wrote:
> On Mon, 2 Dec 2013 10:19:37 -0500 Prarit Bhargava <prarit@redhat.com> wrote:
> A slight simplification:
>
>> +static inline char *dump_hadware_arch_desc(void)
>> +{
>> + return NULL;
>> +}
>
> return "unavailable";
>
>> +void warn_slowpath_fmt_dev(const char *file, int line,
>> + struct device *dev, int level, const char *fmt, ...)
>> +{
>> + struct slowpath_args args;
>> + static char fw_str[16] = "\0";
>> +
>> + switch (level) {
>> + case 1:
>> + strcpy(fw_str, "[Firmware Info]");
>> + break;
>> + case 2:
>> + strcpy(fw_str, "[Firmware Warn]");
>> + break;
>> + case 3:
>> + strcpy(fw_str, "[Firmware Bug]");
>
> What's With The Crazy Capitalization In This Code? It's Illiterate!
Heh :) it's what the original FW_* strings were defined as. I was hoping it was
okay to change them but wasn't 100% sure if I should. I'll definitely take that
(and the suggestion above) into v2.
<snip>
>
> The general thrust of the patchset seems useful and important. I do
> agree with Joe's suggestion regarding the presentation, although it
> isn't a show-stopper.
In V2, I'll take Joe's suggestion into account. It isn't that difficult to
rework those chunks of the patch into a single patch.
>
> I do wonder if it all should be generalised a bit - it creates a bunch
> of infrastructure which is specific to system firmware issues, but
> what's so special about firmware? Why can't I use this infrastructure
> to log netdev errors or acpi errors or PM errors or...? But I didn't
> think about it much ;)
Well ... I was thinking about this. Some drivers do keep track of firmware
versions for their devices and I think there is probably a way to unify all that.
Also, I think after this initial change goes in I'm going to grep through the
PCI & ACPI code to see what FW_* changes need to be made there. AFAICT there
are many locations in those areas which should be FW_*.
I'll get a [v2] out in a little while. Thanks Joe & Andrew for looking.
P.
>
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Introduce FW_INFO* functions and messages
2013-12-04 11:51 ` Prarit Bhargava
@ 2013-12-04 17:20 ` Joe Perches
0 siblings, 0 replies; 14+ messages in thread
From: Joe Perches @ 2013-12-04 17:20 UTC (permalink / raw)
To: Prarit Bhargava
Cc: Andrew Morton, linux-kernel, Arnd Bergmann, Greg Kroah-Hartman
On Wed, 2013-12-04 at 06:51 -0500, Prarit Bhargava wrote:
>
> On 12/03/2013 04:21 PM, Andrew Morton wrote:
> > On Mon, 2 Dec 2013 10:19:37 -0500 Prarit Bhargava <prarit@redhat.com> wrote:
> > A slight simplification:
> >
> >> +static inline char *dump_hadware_arch_desc(void)
> >> +{
> >> + return NULL;
> >> +}
> >
> > return "unavailable";
> >
> >> +void warn_slowpath_fmt_dev(const char *file, int line,
> >> + struct device *dev, int level, const char *fmt, ...)
> >> +{
> >> + struct slowpath_args args;
> >> + static char fw_str[16] = "\0";
> >> +
> >> + switch (level) {
> >> + case 1:
> >> + strcpy(fw_str, "[Firmware Info]");
> >> + break;
> >> + case 2:
> >> + strcpy(fw_str, "[Firmware Warn]");
> >> + break;
> >> + case 3:
> >> + strcpy(fw_str, "[Firmware Bug]");
> >
> > What's With The Crazy Capitalization In This Code? It's Illiterate!
>
> Heh :) it's what the original FW_* strings were defined as. I was hoping it was
> okay to change them but wasn't 100% sure if I should. I'll definitely take that
> (and the suggestion above) into v2.
>
> <snip>
>
> >
> > The general thrust of the patchset seems useful and important. I do
> > agree with Joe's suggestion regarding the presentation, although it
> > isn't a show-stopper.
>
> In V2, I'll take Joe's suggestion into account. It isn't that difficult to
> rework those chunks of the patch into a single patch.
>
> >
> > I do wonder if it all should be generalised a bit - it creates a bunch
> > of infrastructure which is specific to system firmware issues, but
> > what's so special about firmware? Why can't I use this infrastructure
> > to log netdev errors or acpi errors or PM errors or...? But I didn't
> > think about it much ;)
>
> Well ... I was thinking about this. Some drivers do keep track of firmware
> versions for their devices and I think there is probably a way to unify all that.
Isn't that simply using the generic #define FW_<type>s?
> Also, I think after this initial change goes in I'm going to grep through the
> PCI & ACPI code to see what FW_* changes need to be made there. AFAICT there
> are many locations in those areas which should be FW_*.
>
> I'll get a [v2] out in a little while. Thanks Joe & Andrew for looking.
I think you should not remove the current #defines.
You can just leave them alone. Add the new facility
without removing the old capability and then as the
utility of your new system is proven, then the old uses
can be converted if appropriate.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Introduce FW_INFO* functions and messages
2013-12-03 21:21 ` Andrew Morton
2013-12-04 11:51 ` Prarit Bhargava
@ 2013-12-04 18:22 ` Arnd Bergmann
2013-12-05 11:30 ` Matt Fleming
1 sibling, 1 reply; 14+ messages in thread
From: Arnd Bergmann @ 2013-12-04 18:22 UTC (permalink / raw)
To: Andrew Morton; +Cc: Prarit Bhargava, linux-kernel, Greg Kroah-Hartman
On Tuesday 03 December 2013, Andrew Morton wrote:
> I do wonder if it all should be generalised a bit - it creates a bunch
> of infrastructure which is specific to system firmware issues, but
> what's so special about firmware? Why can't I use this infrastructure
> to log netdev errors or acpi errors or PM errors or...? But I didn't
> think about it much ;)
I had similar thoughts when I read this, but I can also remember a bunch
of very overdesigned attempts to reorganize and structure the kernel
logging code. I lot of time was wasted in the past for things that
ended up being too invasive or inconsistent.
The other part I noticed about this particular patchset is that it's
not really "firmware" as such, but specifically PC wiht ACPI that
gets covered here. So rather than generalizing the code, another
option would be to narrow down the scope and make it
acpi_{warn,info,dbg} instead.
Arnd
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Introduce FW_INFO* functions and messages
2013-12-04 18:22 ` Arnd Bergmann
@ 2013-12-05 11:30 ` Matt Fleming
2013-12-05 15:55 ` Joe Perches
0 siblings, 1 reply; 14+ messages in thread
From: Matt Fleming @ 2013-12-05 11:30 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Andrew Morton, Prarit Bhargava, linux-kernel, Greg Kroah-Hartman
On Wed, 04 Dec, at 07:22:57PM, Arnd Bergmann wrote:
> The other part I noticed about this particular patchset is that it's
> not really "firmware" as such, but specifically PC wiht ACPI that
> gets covered here. So rather than generalizing the code, another
> option would be to narrow down the scope and make it
> acpi_{warn,info,dbg} instead.
Making this specific to ACPI runs the risk of people introducing a
multitude of new logging functions for every subsystem, e.g.
efi_{warn,info,dbg}.
FWIW, I'd be interested in using something like this patch series to
properly log EFI implementation bugs. The logging for EFI is currently
done fairly haphazardly.
--
Matt Fleming, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Introduce FW_INFO* functions and messages
2013-12-05 11:30 ` Matt Fleming
@ 2013-12-05 15:55 ` Joe Perches
2013-12-06 12:30 ` Matt Fleming
0 siblings, 1 reply; 14+ messages in thread
From: Joe Perches @ 2013-12-05 15:55 UTC (permalink / raw)
To: Matt Fleming
Cc: Arnd Bergmann, Andrew Morton, Prarit Bhargava, linux-kernel,
Greg Kroah-Hartman
On Thu, 2013-12-05 at 11:30 +0000, Matt Fleming wrote:
> On Wed, 04 Dec, at 07:22:57PM, Arnd Bergmann wrote:
> > The other part I noticed about this particular patchset is that it's
> > not really "firmware" as such, but specifically PC wiht ACPI that
> > gets covered here. So rather than generalizing the code, another
> > option would be to narrow down the scope and make it
> > acpi_{warn,info,dbg} instead.
>
> Making this specific to ACPI runs the risk of people introducing a
> multitude of new logging functions for every subsystem, e.g.
> efi_{warn,info,dbg}.
There are many subsystem specific logging functions:
$ grep -rP --include=*.[ch] -oh "\b[a-z_]+_warn\b\s*\(" *| \
sed -r 's/\s*//g'|sort|uniq -c|sort -rn|head -25
3808 dev_warn(
1964 pr_warn(
468 netdev_warn(
194 xfs_warn(
120 xhci_warn(
102 ipoib_warn(
76 netif_warn(
64 tuner_warn(
53 hid_warn(
51 ata_dev_warn(
46 mthca_warn(
45 nv_warn(
41 ubi_warn(
32 wiphy_warn(
32 osm_warn(
31 rbd_warn(
28 ubifs_warn(
27 psmouse_warn(
27 e_warn(
25 blogic_warn(
23 en_warn(
23 ata_link_warn(
22 jfs_warn(
21 csio_warn(
21 cam_warn(
> FWIW, I'd be interested in using something like this patch series to
> properly log EFI implementation bugs. The logging for EFI is currently
> done fairly haphazardly.
I thought that was the point of embedding the existing
FW_INFO, FW_WARN and FW_BUG #defines in formats.
Using logging message scraping to find faults is not
a great approach as message content is subject to change.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Introduce FW_INFO* functions and messages
2013-12-05 15:55 ` Joe Perches
@ 2013-12-06 12:30 ` Matt Fleming
2013-12-16 13:01 ` Prarit Bhargava
0 siblings, 1 reply; 14+ messages in thread
From: Matt Fleming @ 2013-12-06 12:30 UTC (permalink / raw)
To: Joe Perches
Cc: Arnd Bergmann, Andrew Morton, Prarit Bhargava, linux-kernel,
Greg Kroah-Hartman
On Thu, 05 Dec, at 07:55:03AM, Joe Perches wrote:
> On Thu, 2013-12-05 at 11:30 +0000, Matt Fleming wrote:
> > On Wed, 04 Dec, at 07:22:57PM, Arnd Bergmann wrote:
> > > The other part I noticed about this particular patchset is that it's
> > > not really "firmware" as such, but specifically PC wiht ACPI that
> > > gets covered here. So rather than generalizing the code, another
> > > option would be to narrow down the scope and make it
> > > acpi_{warn,info,dbg} instead.
> >
> > Making this specific to ACPI runs the risk of people introducing a
> > multitude of new logging functions for every subsystem, e.g.
> > efi_{warn,info,dbg}.
>
> There are many subsystem specific logging functions:
Surely that's further justification to not introduce any more.
> > FWIW, I'd be interested in using something like this patch series to
> > properly log EFI implementation bugs. The logging for EFI is currently
> > done fairly haphazardly.
>
> I thought that was the point of embedding the existing
> FW_INFO, FW_WARN and FW_BUG #defines in formats.
>
> Using logging message scraping to find faults is not
> a great approach as message content is subject to change.
I wasn't planning on using them to scrape the kernel logs, just for more
informative messages.
--
Matt Fleming, Intel Open Source Technology Center
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Introduce FW_INFO* functions and messages
2013-12-06 12:30 ` Matt Fleming
@ 2013-12-16 13:01 ` Prarit Bhargava
2013-12-16 16:31 ` Joe Perches
0 siblings, 1 reply; 14+ messages in thread
From: Prarit Bhargava @ 2013-12-16 13:01 UTC (permalink / raw)
To: Matt Fleming
Cc: Joe Perches, Arnd Bergmann, Andrew Morton, linux-kernel,
Greg Kroah-Hartman
Sorry everyone, I was out on PTO for the past few weeks.
On 12/06/2013 07:30 AM, Matt Fleming wrote:
> On Thu, 05 Dec, at 07:55:03AM, Joe Perches wrote:
>> On Thu, 2013-12-05 at 11:30 +0000, Matt Fleming wrote:
>>> On Wed, 04 Dec, at 07:22:57PM, Arnd Bergmann wrote:
>>>> The other part I noticed about this particular patchset is that it's
>>>> not really "firmware" as such, but specifically PC wiht ACPI that
>>>> gets covered here. So rather than generalizing the code, another
>>>> option would be to narrow down the scope and make it
>>>> acpi_{warn,info,dbg} instead.
>>>
>>> Making this specific to ACPI runs the risk of people introducing a
>>> multitude of new logging functions for every subsystem, e.g.
>>> efi_{warn,info,dbg}.
>>
>> There are many subsystem specific logging functions:
>
> Surely that's further justification to not introduce any more.
That's what I was thinking when I saw this discussion.
>
>>> FWIW, I'd be interested in using something like this patch series to
>>> properly log EFI implementation bugs. The logging for EFI is currently
>>> done fairly haphazardly.
>>
>> I thought that was the point of embedding the existing
>> FW_INFO, FW_WARN and FW_BUG #defines in formats.
>>
>> Using logging message scraping to find faults is not
>> a great approach as message content is subject to change.
>
> I wasn't planning on using them to scrape the kernel logs, just for more
> informative messages.
Exactly. That's the whole point here -- the only mechanism that exists for
tracking firwmare related issues, like it or not, is the kernel log/dmesg/boot
log/whatever we're calling it these days. It's been done this way since the
beginning of time.
The problem I'm trying to solve, and as Andrew commented on, is a *real*
problem. The information we currently dump out is not useful to anyone.
Could this be expanded to other subsystems? Yes, without question. It's
actually the ACPI and PCI subsystems that I want to target next, however, both
of those will require a base change to FW_{INFO|WARN|BUG} to at least get us a
starting point.
P.
>
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 1/3] Introduce FW_INFO* functions and messages
2013-12-16 13:01 ` Prarit Bhargava
@ 2013-12-16 16:31 ` Joe Perches
0 siblings, 0 replies; 14+ messages in thread
From: Joe Perches @ 2013-12-16 16:31 UTC (permalink / raw)
To: Prarit Bhargava
Cc: Matt Fleming, Arnd Bergmann, Andrew Morton, linux-kernel,
Greg Kroah-Hartman
On Mon, 2013-12-16 at 08:01 -0500, Prarit Bhargava wrote:
> Sorry everyone, I was out on PTO for the past few weeks.
>
>
> On 12/06/2013 07:30 AM, Matt Fleming wrote:
> > On Thu, 05 Dec, at 07:55:03AM, Joe Perches wrote:
> >> On Thu, 2013-12-05 at 11:30 +0000, Matt Fleming wrote:
> >>> On Wed, 04 Dec, at 07:22:57PM, Arnd Bergmann wrote:
> >>>> The other part I noticed about this particular patchset is that it's
> >>>> not really "firmware" as such, but specifically PC wiht ACPI that
> >>>> gets covered here. So rather than generalizing the code, another
> >>>> option would be to narrow down the scope and make it
> >>>> acpi_{warn,info,dbg} instead.
> >>>
> >>> Making this specific to ACPI runs the risk of people introducing a
> >>> multitude of new logging functions for every subsystem, e.g.
> >>> efi_{warn,info,dbg}.
> >>
> >> There are many subsystem specific logging functions:
> >
> > Surely that's further justification to not introduce any more.
>
> That's what I was thinking when I saw this discussion.
I have no problem with introducing more <subsystem>_<kern_level>
functions/macros.
It can reduce overall object size quite a lot.
see commits like: 227842d1176019512d24236f7fb894f0fadd30d1
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2013-12-16 16:31 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-02 15:19 [PATCH 0/3] Add Firmware Info, Warn, and Bug messages Prarit Bhargava
2013-12-02 15:19 ` [PATCH 1/3] Introduce FW_INFO* functions and messages Prarit Bhargava
2013-12-03 21:21 ` Andrew Morton
2013-12-04 11:51 ` Prarit Bhargava
2013-12-04 17:20 ` Joe Perches
2013-12-04 18:22 ` Arnd Bergmann
2013-12-05 11:30 ` Matt Fleming
2013-12-05 15:55 ` Joe Perches
2013-12-06 12:30 ` Matt Fleming
2013-12-16 13:01 ` Prarit Bhargava
2013-12-16 16:31 ` Joe Perches
2013-12-02 15:19 ` [PATCH 2/3] Introduce FW_WARN* " Prarit Bhargava
2013-12-02 15:19 ` [PATCH 3/3] Introduce FW_BUG* " Prarit Bhargava
2013-12-02 17:34 ` [PATCH 0/3] Add Firmware Info, Warn, and Bug messages Joe Perches
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).