[IA64] MCA/INIT: avoid reading INIT record during INIT event

Reading the INIT record from SAL during the INIT event has proved to be
unreliable, and a source of hangs during INIT processing. The new
MCA/INIT handlers remove the need to get the INIT record from SAL.
Change salinfo.c so mca.c can just flag that a new record is available,
without having to read the record during INIT processing. This patch
can be applied without the new MCA/INIT handlers.

Also clean up some usage of NR_CPUS which should have been using
cpu_online().

Signed-off-by: Keith Owens <kaos@sgi.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>

authored by

Keith Owens and committed by
Tony Luck
289d773e e619ae0b

+34 -28
+34 -28
arch/ia64/kernel/salinfo.c
··· 22 22 * 23 23 * Dec 5 2004 kaos@sgi.com 24 24 * Standardize which records are cleared automatically. 25 + * 26 + * Aug 18 2005 kaos@sgi.com 27 + * mca.c may not pass a buffer, a NULL buffer just indicates that a new 28 + * record is available in SAL. 29 + * Replace some NR_CPUS by cpus_online, for hotplug cpu. 25 30 */ 26 31 27 32 #include <linux/types.h> ··· 198 193 * The buffer passed from mca.c points to the output from ia64_log_get. This is 199 194 * a persistent buffer but its contents can change between the interrupt and 200 195 * when user space processes the record. Save the record id to identify 201 - * changes. 196 + * changes. If the buffer is NULL then just update the bitmap. 202 197 */ 203 198 void 204 199 salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe) ··· 211 206 212 207 BUG_ON(type >= ARRAY_SIZE(salinfo_log_name)); 213 208 214 - if (irqsafe) 215 - spin_lock_irqsave(&data_saved_lock, flags); 216 - for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) { 217 - if (!data_saved->buffer) 218 - break; 209 + if (buffer) { 210 + if (irqsafe) 211 + spin_lock_irqsave(&data_saved_lock, flags); 212 + for (i = 0, data_saved = data->data_saved; i < saved_size; ++i, ++data_saved) { 213 + if (!data_saved->buffer) 214 + break; 215 + } 216 + if (i == saved_size) { 217 + if (!data->saved_num) { 218 + shift1_data_saved(data, 0); 219 + data_saved = data->data_saved + saved_size - 1; 220 + } else 221 + data_saved = NULL; 222 + } 223 + if (data_saved) { 224 + data_saved->cpu = smp_processor_id(); 225 + data_saved->id = ((sal_log_record_header_t *)buffer)->id; 226 + data_saved->size = size; 227 + data_saved->buffer = buffer; 228 + } 229 + if (irqsafe) 230 + spin_unlock_irqrestore(&data_saved_lock, flags); 219 231 } 220 - if (i == saved_size) { 221 - if (!data->saved_num) { 222 - shift1_data_saved(data, 0); 223 - data_saved = data->data_saved + saved_size - 1; 224 - } else 225 - data_saved = NULL; 226 - } 227 - if (data_saved) { 228 - data_saved->cpu = smp_processor_id(); 229 - data_saved->id = ((sal_log_record_header_t *)buffer)->id; 230 - data_saved->size = size; 231 - data_saved->buffer = buffer; 232 - } 233 - if (irqsafe) 234 - spin_unlock_irqrestore(&data_saved_lock, flags); 235 232 236 233 if (!test_and_set_bit(smp_processor_id(), &data->cpu_event)) { 237 234 if (irqsafe) ··· 251 244 int i; 252 245 if (!data->open) 253 246 return; 254 - for (i = 0; i < NR_CPUS; ++i) { 247 + for_each_online_cpu(i) { 255 248 if (test_bit(i, &data->cpu_event)) { 256 249 /* double up() is not a problem, user space will see no 257 250 * records for the additional "events". ··· 298 291 299 292 n = data->cpu_check; 300 293 for (i = 0; i < NR_CPUS; i++) { 301 - if (test_bit(n, &data->cpu_event)) { 294 + if (test_bit(n, &data->cpu_event) && cpu_online(n)) { 302 295 cpu = n; 303 296 break; 304 297 } ··· 592 585 593 586 /* we missed any events before now */ 594 587 online = 0; 595 - for (j = 0; j < NR_CPUS; j++) 596 - if (cpu_online(j)) { 597 - set_bit(j, &data->cpu_event); 598 - ++online; 599 - } 588 + for_each_online_cpu(j) { 589 + set_bit(j, &data->cpu_event); 590 + ++online; 591 + } 600 592 sema_init(&data->sem, online); 601 593 602 594 *sdir++ = dir;