# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1234490161 -32400
# Node ID af992824b5cfa3b81dbe68293216a5df3ec0bdf4
# Parent 46b4096813dca3c707a60148f560aba31f521c56
[IA64] MCA: Avoid calling xmcalloc from interrupt handler
This patch fixes to avoid calling xmalloc() from the interrupt handler.
Calling xmalloc() with interrupt disabled triggers the following
BUG_ON().
> (XEN) Xen BUG at xmalloc_tlsf.c:548
Signed-off-by: Kazuhiro Suzuki <kaz@xxxxxxxxxxxxxx>
---
xen/arch/ia64/linux-xen/mca.c | 15 ++++++++++++---
xen/arch/ia64/xen/fw_emul.c | 13 ++++++++-----
2 files changed, 20 insertions(+), 8 deletions(-)
diff -r 46b4096813dc -r af992824b5cf xen/arch/ia64/linux-xen/mca.c
--- a/xen/arch/ia64/linux-xen/mca.c Mon Feb 02 11:11:36 2009 +0900
+++ b/xen/arch/ia64/linux-xen/mca.c Fri Feb 13 10:56:01 2009 +0900
@@ -210,6 +210,7 @@ static ia64_state_log_t ia64_state_log[I
#define IA64_LOG_COUNT(it) ia64_state_log[it].isl_count
#ifdef XEN
+sal_queue_entry_t sal_entry[NR_CPUS][IA64_MAX_LOG_TYPES];
struct list_head *sal_queue, sal_log_queues[IA64_MAX_LOG_TYPES];
sal_log_record_header_t *sal_record;
DEFINE_SPINLOCK(sal_queue_lock);
@@ -358,6 +359,7 @@ ia64_log_queue(int sal_info_type, int vi
if (total_len) {
int queue_type;
+ int cpuid = smp_processor_id();
spin_lock_irqsave(&sal_queue_lock, flags);
@@ -366,15 +368,22 @@ ia64_log_queue(int sal_info_type, int vi
else
queue_type = sal_info_type;
- e = xmalloc(sal_queue_entry_t);
- BUG_ON(e == NULL);
- e->cpuid = smp_processor_id();
+ /* Skip if sal_entry is already listed in sal_queue */
+ list_for_each_entry(e, &sal_queue[queue_type], list) {
+ if (e == &sal_entry[cpuid][queue_type])
+ goto found;
+ }
+ e = &sal_entry[cpuid][queue_type];
+ memset(e, 0, sizeof(sal_queue_entry_t));
+ e->cpuid = cpuid;
e->sal_info_type = sal_info_type;
e->vector = IA64_CMC_VECTOR;
e->virq = virq;
e->length = total_len;
list_add_tail(&e->list, &sal_queue[queue_type]);
+
+ found:
spin_unlock_irqrestore(&sal_queue_lock, flags);
IA64_LOG_INDEX_INC(sal_info_type);
diff -r 46b4096813dc -r af992824b5cf xen/arch/ia64/xen/fw_emul.c
--- a/xen/arch/ia64/xen/fw_emul.c Mon Feb 02 11:11:36 2009 +0900
+++ b/xen/arch/ia64/xen/fw_emul.c Fri Feb 13 10:56:01 2009 +0900
@@ -95,7 +95,7 @@ void get_state_info_on(void *data) {
rec_name[arg->type], smp_processor_id(), arg->ret);
if (arg->corrected) {
sal_record->severity = sal_log_severity_corrected;
- IA64_SAL_DEBUG("%s:
IA64_SAL_CLEAR_STATE_INFO(SAL_INFO_TYPE_MCA)"
+ IA64_SAL_DEBUG("%s: IA64_SAL_GET_STATE_INFO(SAL_INFO_TYPE_MCA)"
" force\n", __FUNCTION__);
}
if (arg->ret > 0) {
@@ -293,9 +293,7 @@ sal_emulator (long index, unsigned long
}
r9 = arg.ret;
status = arg.status;
- if (r9 == 0) {
- xfree(e);
- } else {
+ if (r9 != 0) {
/* Re-add the entry to sal_queue */
spin_lock_irqsave(&sal_queue_lock, flags);
list_add(&e->list, &sal_queue[in1]);
@@ -359,7 +357,12 @@ sal_emulator (long index, unsigned long
}
r9 = arg.ret;
status = arg.status;
- xfree(e);
+ if (r9 >= 0) {
+ IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO: more
errors are available\n");
+ spin_lock_irqsave(&sal_queue_lock, flags);
+ list_add(&e->list, &sal_queue[in1]);
+ spin_unlock_irqrestore(&sal_queue_lock, flags);
+ }
}
break;
case SAL_MC_RENDEZ:
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|