ia64/xen-unstable

changeset 19132:af992824b5cf

[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@jp.fujitsu.com>
author Isaku Yamahata <yamahata@valinux.co.jp>
date Fri Feb 13 10:56:01 2009 +0900 (2009-02-13)
parents 46b4096813dc
children c7cba853583d
files xen/arch/ia64/linux-xen/mca.c xen/arch/ia64/xen/fw_emul.c
line diff
     1.1 --- a/xen/arch/ia64/linux-xen/mca.c	Mon Feb 02 11:11:36 2009 +0900
     1.2 +++ b/xen/arch/ia64/linux-xen/mca.c	Fri Feb 13 10:56:01 2009 +0900
     1.3 @@ -210,6 +210,7 @@ static ia64_state_log_t ia64_state_log[I
     1.4  #define IA64_LOG_COUNT(it)         ia64_state_log[it].isl_count
     1.5  
     1.6  #ifdef XEN
     1.7 +sal_queue_entry_t sal_entry[NR_CPUS][IA64_MAX_LOG_TYPES];
     1.8  struct list_head *sal_queue, sal_log_queues[IA64_MAX_LOG_TYPES];
     1.9  sal_log_record_header_t *sal_record;
    1.10  DEFINE_SPINLOCK(sal_queue_lock);
    1.11 @@ -358,6 +359,7 @@ ia64_log_queue(int sal_info_type, int vi
    1.12  
    1.13  	if (total_len) {
    1.14  		int queue_type;
    1.15 +		int cpuid = smp_processor_id();
    1.16  
    1.17  		spin_lock_irqsave(&sal_queue_lock, flags);
    1.18  
    1.19 @@ -366,15 +368,22 @@ ia64_log_queue(int sal_info_type, int vi
    1.20  		else
    1.21  			queue_type = sal_info_type;
    1.22  
    1.23 -		e = xmalloc(sal_queue_entry_t);
    1.24 -		BUG_ON(e == NULL);
    1.25 -		e->cpuid = smp_processor_id();
    1.26 +		/* Skip if sal_entry is already listed in sal_queue */
    1.27 +		list_for_each_entry(e, &sal_queue[queue_type], list) {
    1.28 +			if (e == &sal_entry[cpuid][queue_type])
    1.29 +				goto found;
    1.30 +		}
    1.31 +		e = &sal_entry[cpuid][queue_type];
    1.32 +		memset(e, 0, sizeof(sal_queue_entry_t));
    1.33 +		e->cpuid = cpuid;
    1.34  		e->sal_info_type = sal_info_type;
    1.35  		e->vector = IA64_CMC_VECTOR;
    1.36  		e->virq = virq;
    1.37  		e->length = total_len;
    1.38  
    1.39  		list_add_tail(&e->list, &sal_queue[queue_type]);
    1.40 +
    1.41 +	found:
    1.42  		spin_unlock_irqrestore(&sal_queue_lock, flags);
    1.43  
    1.44  		IA64_LOG_INDEX_INC(sal_info_type);
     2.1 --- a/xen/arch/ia64/xen/fw_emul.c	Mon Feb 02 11:11:36 2009 +0900
     2.2 +++ b/xen/arch/ia64/xen/fw_emul.c	Fri Feb 13 10:56:01 2009 +0900
     2.3 @@ -95,7 +95,7 @@ void get_state_info_on(void *data) {
     2.4  	               rec_name[arg->type], smp_processor_id(), arg->ret);
     2.5  	if (arg->corrected) {
     2.6  		sal_record->severity = sal_log_severity_corrected;
     2.7 -		IA64_SAL_DEBUG("%s: IA64_SAL_CLEAR_STATE_INFO(SAL_INFO_TYPE_MCA)"
     2.8 +		IA64_SAL_DEBUG("%s: IA64_SAL_GET_STATE_INFO(SAL_INFO_TYPE_MCA)"
     2.9  		               " force\n", __FUNCTION__);
    2.10  	}
    2.11  	if (arg->ret > 0) {
    2.12 @@ -293,9 +293,7 @@ sal_emulator (long index, unsigned long 
    2.13  			}
    2.14  			r9 = arg.ret;
    2.15  			status = arg.status;
    2.16 -			if (r9 == 0) {
    2.17 -				xfree(e);
    2.18 -			} else {
    2.19 +			if (r9 != 0) {
    2.20  				/* Re-add the entry to sal_queue */
    2.21  				spin_lock_irqsave(&sal_queue_lock, flags);
    2.22  				list_add(&e->list, &sal_queue[in1]);
    2.23 @@ -359,7 +357,12 @@ sal_emulator (long index, unsigned long 
    2.24  			}
    2.25  			r9 = arg.ret;
    2.26  			status = arg.status;
    2.27 -			xfree(e);
    2.28 +			if (r9 >= 0) {
    2.29 +				IA64_SAL_DEBUG("SAL_CLEAR_STATE_INFO: more errors are available\n");
    2.30 +				spin_lock_irqsave(&sal_queue_lock, flags);
    2.31 +				list_add(&e->list, &sal_queue[in1]);
    2.32 +				spin_unlock_irqrestore(&sal_queue_lock, flags);
    2.33 +			}
    2.34  		}
    2.35  		break;
    2.36  	    case SAL_MC_RENDEZ: