diff options
| -rw-r--r-- | arch/ia64/kernel/smp.c | 68 |
1 files changed, 35 insertions, 33 deletions
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index 9a9d4c489330..983296f1c813 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c | |||
| @@ -98,8 +98,33 @@ unlock_ipi_calllock(void) | |||
| 98 | spin_unlock_irq(&call_lock); | 98 | spin_unlock_irq(&call_lock); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | static inline void | ||
| 102 | handle_call_data(void) | ||
| 103 | { | ||
| 104 | struct call_data_struct *data; | ||
| 105 | void (*func)(void *info); | ||
| 106 | void *info; | ||
| 107 | int wait; | ||
| 108 | |||
| 109 | /* release the 'pointer lock' */ | ||
| 110 | data = (struct call_data_struct *)call_data; | ||
| 111 | func = data->func; | ||
| 112 | info = data->info; | ||
| 113 | wait = data->wait; | ||
| 114 | |||
| 115 | mb(); | ||
| 116 | atomic_inc(&data->started); | ||
| 117 | /* At this point the structure may be gone unless wait is true. */ | ||
| 118 | (*func)(info); | ||
| 119 | |||
| 120 | /* Notify the sending CPU that the task is done. */ | ||
| 121 | mb(); | ||
| 122 | if (wait) | ||
| 123 | atomic_inc(&data->finished); | ||
| 124 | } | ||
| 125 | |||
| 101 | static void | 126 | static void |
| 102 | stop_this_cpu (void) | 127 | stop_this_cpu(void) |
| 103 | { | 128 | { |
| 104 | /* | 129 | /* |
| 105 | * Remove this CPU: | 130 | * Remove this CPU: |
| @@ -138,44 +163,21 @@ handle_IPI (int irq, void *dev_id) | |||
| 138 | ops &= ~(1 << which); | 163 | ops &= ~(1 << which); |
| 139 | 164 | ||
| 140 | switch (which) { | 165 | switch (which) { |
| 141 | case IPI_CALL_FUNC: | 166 | case IPI_CALL_FUNC: |
| 142 | { | 167 | handle_call_data(); |
| 143 | struct call_data_struct *data; | 168 | break; |
| 144 | void (*func)(void *info); | 169 | |
| 145 | void *info; | 170 | case IPI_CPU_STOP: |
| 146 | int wait; | ||
| 147 | |||
| 148 | /* release the 'pointer lock' */ | ||
| 149 | data = (struct call_data_struct *) call_data; | ||
| 150 | func = data->func; | ||
| 151 | info = data->info; | ||
| 152 | wait = data->wait; | ||
| 153 | |||
| 154 | mb(); | ||
| 155 | atomic_inc(&data->started); | ||
| 156 | /* | ||
| 157 | * At this point the structure may be gone unless | ||
| 158 | * wait is true. | ||
| 159 | */ | ||
| 160 | (*func)(info); | ||
| 161 | |||
| 162 | /* Notify the sending CPU that the task is done. */ | ||
| 163 | mb(); | ||
| 164 | if (wait) | ||
| 165 | atomic_inc(&data->finished); | ||
| 166 | } | ||
| 167 | break; | ||
| 168 | |||
| 169 | case IPI_CPU_STOP: | ||
| 170 | stop_this_cpu(); | 171 | stop_this_cpu(); |
| 171 | break; | 172 | break; |
| 172 | #ifdef CONFIG_KEXEC | 173 | #ifdef CONFIG_KEXEC |
| 173 | case IPI_KDUMP_CPU_STOP: | 174 | case IPI_KDUMP_CPU_STOP: |
| 174 | unw_init_running(kdump_cpu_freeze, NULL); | 175 | unw_init_running(kdump_cpu_freeze, NULL); |
| 175 | break; | 176 | break; |
| 176 | #endif | 177 | #endif |
| 177 | default: | 178 | default: |
| 178 | printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", this_cpu, which); | 179 | printk(KERN_CRIT "Unknown IPI on CPU %d: %lu\n", |
| 180 | this_cpu, which); | ||
| 179 | break; | 181 | break; |
| 180 | } | 182 | } |
| 181 | } while (ops); | 183 | } while (ops); |
