Commit 765a8447 authored by Alex Williamson's avatar Alex Williamson Committed by David Mosberger

[PATCH] ia64: New CMC/CPE polling

Here's a redesign of the CMC and CPE polling for both 2.6.0-test2
and 2.4.21.  This is roughly the same design I requested comment on
a while back (BTW, nobody commented...).  Basically, rather than
flooding all the cpus in parallel, I used some low priority interrupts
to cascade through the cpus.  This should be much more scalable.  I
also added a new feature of enabling interrupts for the CMC and CPE
handlers.  The SAL spec claims these functions are SMP safe and
re-entrant and even recommends that the corrected error handlers
should run with interrupts enabled.  It works on HP boxes, others
might want to double check that their firmware adheres to the spec.
The combination of these things should keep polling from impacting
system response time.
parent 6fd79ab5
...@@ -543,7 +543,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi, ...@@ -543,7 +543,7 @@ iosapic_register_platform_intr (u32 int_type, unsigned int gsi,
delivery = IOSAPIC_INIT; delivery = IOSAPIC_INIT;
break; break;
case ACPI_INTERRUPT_CPEI: case ACPI_INTERRUPT_CPEI:
vector = IA64_PCE_VECTOR; vector = IA64_CPE_VECTOR;
delivery = IOSAPIC_LOWEST_PRIORITY; delivery = IOSAPIC_LOWEST_PRIORITY;
break; break;
default: default:
......
This diff is collapsed.
...@@ -280,7 +280,7 @@ sn_setup(char **cmdline_p) ...@@ -280,7 +280,7 @@ sn_setup(char **cmdline_p)
else else
sn_rtc_cycles_per_second = ticks_per_sec; sn_rtc_cycles_per_second = ticks_per_sec;
platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_PCE_VECTOR; platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR;
if ( IS_RUNNING_ON_SIMULATOR() ) if ( IS_RUNNING_ON_SIMULATOR() )
......
...@@ -38,7 +38,9 @@ typedef u8 ia64_vector; ...@@ -38,7 +38,9 @@ typedef u8 ia64_vector;
/* /*
* Vectors 0x10-0x1f are used for low priority interrupts, e.g. CMCI. * Vectors 0x10-0x1f are used for low priority interrupts, e.g. CMCI.
*/ */
#define IA64_PCE_VECTOR 0x1e /* platform corrected error interrupt vector */ #define IA64_CPEP_VECTOR 0x1c /* corrected platform error polling vector */
#define IA64_CMCP_VECTOR 0x1d /* correctable machine-check polling vector */
#define IA64_CPE_VECTOR 0x1e /* corrected platform error interrupt vector */
#define IA64_CMC_VECTOR 0x1f /* correctable machine-check interrupt vector */ #define IA64_CMC_VECTOR 0x1f /* correctable machine-check interrupt vector */
/* /*
* Vectors 0x20-0x2f are reserved for legacy ISA IRQs. * Vectors 0x20-0x2f are reserved for legacy ISA IRQs.
......
...@@ -137,7 +137,9 @@ extern void ia64_slave_init_handler(void); ...@@ -137,7 +137,9 @@ extern void ia64_slave_init_handler(void);
extern irqreturn_t ia64_mca_rendez_int_handler(int,void *,struct pt_regs *); extern irqreturn_t ia64_mca_rendez_int_handler(int,void *,struct pt_regs *);
extern irqreturn_t ia64_mca_wakeup_int_handler(int,void *,struct pt_regs *); extern irqreturn_t ia64_mca_wakeup_int_handler(int,void *,struct pt_regs *);
extern irqreturn_t ia64_mca_cmc_int_handler(int,void *,struct pt_regs *); extern irqreturn_t ia64_mca_cmc_int_handler(int,void *,struct pt_regs *);
extern irqreturn_t ia64_mca_cmc_int_caller(int,void *,struct pt_regs *);
extern irqreturn_t ia64_mca_cpe_int_handler(int,void *,struct pt_regs *); extern irqreturn_t ia64_mca_cpe_int_handler(int,void *,struct pt_regs *);
extern irqreturn_t ia64_mca_cpe_int_caller(int,void *,struct pt_regs *);
extern int ia64_log_print(int,prfunc_t); extern int ia64_log_print(int,prfunc_t);
extern void ia64_mca_cmc_vector_setup(void); extern void ia64_mca_cmc_vector_setup(void);
extern int ia64_mca_check_errors(void); extern int ia64_mca_check_errors(void);
......
...@@ -68,6 +68,13 @@ extern spinlock_t sal_lock; ...@@ -68,6 +68,13 @@ extern spinlock_t sal_lock;
ia64_load_scratch_fpregs(__ia64_scn_fr); \ ia64_load_scratch_fpregs(__ia64_scn_fr); \
} while (0) } while (0)
# define SAL_CALL_REENTRANT(result,args...) do { \
struct ia64_fpreg __ia64_scs_fr[6]; \
ia64_save_scratch_fpregs(__ia64_scs_fr); \
__SAL_CALL(result, args); \
ia64_load_scratch_fpregs(__ia64_scs_fr); \
} while (0)
#define SAL_SET_VECTORS 0x01000000 #define SAL_SET_VECTORS 0x01000000
#define SAL_GET_STATE_INFO 0x01000001 #define SAL_GET_STATE_INFO 0x01000001
#define SAL_GET_STATE_INFO_SIZE 0x01000002 #define SAL_GET_STATE_INFO_SIZE 0x01000002
...@@ -665,8 +672,8 @@ static inline s64 ...@@ -665,8 +672,8 @@ static inline s64
ia64_sal_clear_state_info (u64 sal_info_type) ia64_sal_clear_state_info (u64 sal_info_type)
{ {
struct ia64_sal_retval isrv; struct ia64_sal_retval isrv;
SAL_CALL(isrv, SAL_CLEAR_STATE_INFO, sal_info_type, 0, SAL_CALL_REENTRANT(isrv, SAL_CLEAR_STATE_INFO, sal_info_type, 0,
0, 0, 0, 0, 0); 0, 0, 0, 0, 0);
return isrv.status; return isrv.status;
} }
...@@ -678,8 +685,8 @@ static inline u64 ...@@ -678,8 +685,8 @@ static inline u64
ia64_sal_get_state_info (u64 sal_info_type, u64 *sal_info) ia64_sal_get_state_info (u64 sal_info_type, u64 *sal_info)
{ {
struct ia64_sal_retval isrv; struct ia64_sal_retval isrv;
SAL_CALL(isrv, SAL_GET_STATE_INFO, sal_info_type, 0, SAL_CALL_REENTRANT(isrv, SAL_GET_STATE_INFO, sal_info_type, 0,
sal_info, 0, 0, 0, 0); sal_info, 0, 0, 0, 0);
if (isrv.status) if (isrv.status)
return 0; return 0;
...@@ -694,8 +701,8 @@ static inline u64 ...@@ -694,8 +701,8 @@ static inline u64
ia64_sal_get_state_info_size (u64 sal_info_type) ia64_sal_get_state_info_size (u64 sal_info_type)
{ {
struct ia64_sal_retval isrv; struct ia64_sal_retval isrv;
SAL_CALL(isrv, SAL_GET_STATE_INFO_SIZE, sal_info_type, 0, SAL_CALL_REENTRANT(isrv, SAL_GET_STATE_INFO_SIZE, sal_info_type, 0,
0, 0, 0, 0, 0); 0, 0, 0, 0, 0);
if (isrv.status) if (isrv.status)
return 0; return 0;
return isrv.v0; return isrv.v0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment