diff options
| -rw-r--r-- | arch/ia64/kernel/salinfo.c | 38 |
1 files changed, 10 insertions, 28 deletions
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index 1eeffb7fbb16..5313007d5423 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c | |||
| @@ -141,7 +141,7 @@ enum salinfo_state { | |||
| 141 | 141 | ||
| 142 | struct salinfo_data { | 142 | struct salinfo_data { |
| 143 | cpumask_t cpu_event; /* which cpus have outstanding events */ | 143 | cpumask_t cpu_event; /* which cpus have outstanding events */ |
| 144 | struct semaphore mutex; | 144 | wait_queue_head_t read_wait; |
| 145 | u8 *log_buffer; | 145 | u8 *log_buffer; |
| 146 | u64 log_size; | 146 | u64 log_size; |
| 147 | u8 *oemdata; /* decoded oem data */ | 147 | u8 *oemdata; /* decoded oem data */ |
| @@ -182,21 +182,6 @@ struct salinfo_platform_oemdata_parms { | |||
| 182 | int ret; | 182 | int ret; |
| 183 | }; | 183 | }; |
| 184 | 184 | ||
| 185 | /* Kick the mutex that tells user space that there is work to do. Instead of | ||
| 186 | * trying to track the state of the mutex across multiple cpus, in user | ||
| 187 | * context, interrupt context, non-maskable interrupt context and hotplug cpu, | ||
| 188 | * it is far easier just to grab the mutex if it is free then release it. | ||
| 189 | * | ||
| 190 | * This routine must be called with data_saved_lock held, to make the down/up | ||
| 191 | * operation atomic. | ||
| 192 | */ | ||
| 193 | static void | ||
| 194 | salinfo_work_to_do(struct salinfo_data *data) | ||
| 195 | { | ||
| 196 | (void)(down_trylock(&data->mutex) ?: 0); | ||
| 197 | up(&data->mutex); | ||
| 198 | } | ||
| 199 | |||
| 200 | static void | 185 | static void |
| 201 | salinfo_platform_oemdata_cpu(void *context) | 186 | salinfo_platform_oemdata_cpu(void *context) |
| 202 | { | 187 | { |
| @@ -258,7 +243,7 @@ salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe) | |||
| 258 | } | 243 | } |
| 259 | cpumask_set_cpu(smp_processor_id(), &data->cpu_event); | 244 | cpumask_set_cpu(smp_processor_id(), &data->cpu_event); |
| 260 | if (irqsafe) { | 245 | if (irqsafe) { |
| 261 | salinfo_work_to_do(data); | 246 | wake_up_interruptible(&data->read_wait); |
| 262 | spin_unlock_irqrestore(&data_saved_lock, flags); | 247 | spin_unlock_irqrestore(&data_saved_lock, flags); |
| 263 | } | 248 | } |
| 264 | } | 249 | } |
| @@ -271,14 +256,10 @@ extern void ia64_mlogbuf_dump(void); | |||
| 271 | static void | 256 | static void |
| 272 | salinfo_timeout_check(struct salinfo_data *data) | 257 | salinfo_timeout_check(struct salinfo_data *data) |
| 273 | { | 258 | { |
| 274 | unsigned long flags; | ||
| 275 | if (!data->open) | 259 | if (!data->open) |
| 276 | return; | 260 | return; |
| 277 | if (!cpumask_empty(&data->cpu_event)) { | 261 | if (!cpumask_empty(&data->cpu_event)) |
| 278 | spin_lock_irqsave(&data_saved_lock, flags); | 262 | wake_up_interruptible(&data->read_wait); |
| 279 | salinfo_work_to_do(data); | ||
| 280 | spin_unlock_irqrestore(&data_saved_lock, flags); | ||
| 281 | } | ||
| 282 | } | 263 | } |
| 283 | 264 | ||
| 284 | static void | 265 | static void |
| @@ -308,10 +289,11 @@ salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t | |||
| 308 | int i, n, cpu = -1; | 289 | int i, n, cpu = -1; |
| 309 | 290 | ||
| 310 | retry: | 291 | retry: |
| 311 | if (cpumask_empty(&data->cpu_event) && down_trylock(&data->mutex)) { | 292 | if (cpumask_empty(&data->cpu_event)) { |
| 312 | if (file->f_flags & O_NONBLOCK) | 293 | if (file->f_flags & O_NONBLOCK) |
| 313 | return -EAGAIN; | 294 | return -EAGAIN; |
| 314 | if (down_interruptible(&data->mutex)) | 295 | if (wait_event_interruptible(data->read_wait, |
| 296 | !cpumask_empty(&data->cpu_event))) | ||
| 315 | return -EINTR; | 297 | return -EINTR; |
| 316 | } | 298 | } |
| 317 | 299 | ||
| @@ -510,7 +492,7 @@ salinfo_log_clear(struct salinfo_data *data, int cpu) | |||
| 510 | if (data->state == STATE_LOG_RECORD) { | 492 | if (data->state == STATE_LOG_RECORD) { |
| 511 | spin_lock_irqsave(&data_saved_lock, flags); | 493 | spin_lock_irqsave(&data_saved_lock, flags); |
| 512 | cpumask_set_cpu(cpu, &data->cpu_event); | 494 | cpumask_set_cpu(cpu, &data->cpu_event); |
| 513 | salinfo_work_to_do(data); | 495 | wake_up_interruptible(&data->read_wait); |
| 514 | spin_unlock_irqrestore(&data_saved_lock, flags); | 496 | spin_unlock_irqrestore(&data_saved_lock, flags); |
| 515 | } | 497 | } |
| 516 | return 0; | 498 | return 0; |
| @@ -582,7 +564,7 @@ salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu | |||
| 582 | i < ARRAY_SIZE(salinfo_data); | 564 | i < ARRAY_SIZE(salinfo_data); |
| 583 | ++i, ++data) { | 565 | ++i, ++data) { |
| 584 | cpumask_set_cpu(cpu, &data->cpu_event); | 566 | cpumask_set_cpu(cpu, &data->cpu_event); |
| 585 | salinfo_work_to_do(data); | 567 | wake_up_interruptible(&data->read_wait); |
| 586 | } | 568 | } |
| 587 | spin_unlock_irqrestore(&data_saved_lock, flags); | 569 | spin_unlock_irqrestore(&data_saved_lock, flags); |
| 588 | break; | 570 | break; |
| @@ -640,7 +622,7 @@ salinfo_init(void) | |||
| 640 | for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { | 622 | for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) { |
| 641 | data = salinfo_data + i; | 623 | data = salinfo_data + i; |
| 642 | data->type = i; | 624 | data->type = i; |
| 643 | sema_init(&data->mutex, 1); | 625 | init_waitqueue_head(&data->read_wait); |
| 644 | dir = proc_mkdir(salinfo_log_name[i], salinfo_dir); | 626 | dir = proc_mkdir(salinfo_log_name[i], salinfo_dir); |
| 645 | if (!dir) | 627 | if (!dir) |
| 646 | continue; | 628 | continue; |
