struct salinfo_data {
cpumask_t cpu_event; /* which cpus have outstanding events */
- struct semaphore mutex;
+ wait_queue_head_t read_wait;
u8 *log_buffer;
u64 log_size;
u8 *oemdata; /* decoded oem data */
int ret;
};
-/* Kick the mutex that tells user space that there is work to do. Instead of
- * trying to track the state of the mutex across multiple cpus, in user
- * context, interrupt context, non-maskable interrupt context and hotplug cpu,
- * it is far easier just to grab the mutex if it is free then release it.
- *
- * This routine must be called with data_saved_lock held, to make the down/up
- * operation atomic.
- */
-static void
-salinfo_work_to_do(struct salinfo_data *data)
-{
- (void)(down_trylock(&data->mutex) ?: 0);
- up(&data->mutex);
-}
-
static void
salinfo_platform_oemdata_cpu(void *context)
{
}
cpumask_set_cpu(smp_processor_id(), &data->cpu_event);
if (irqsafe) {
- salinfo_work_to_do(data);
+ wake_up_interruptible(&data->read_wait);
spin_unlock_irqrestore(&data_saved_lock, flags);
}
}
static void
salinfo_timeout_check(struct salinfo_data *data)
{
- unsigned long flags;
if (!data->open)
return;
- if (!cpumask_empty(&data->cpu_event)) {
- spin_lock_irqsave(&data_saved_lock, flags);
- salinfo_work_to_do(data);
- spin_unlock_irqrestore(&data_saved_lock, flags);
- }
+ if (!cpumask_empty(&data->cpu_event))
+ wake_up_interruptible(&data->read_wait);
}
static void
int i, n, cpu = -1;
retry:
- if (cpumask_empty(&data->cpu_event) && down_trylock(&data->mutex)) {
+ if (cpumask_empty(&data->cpu_event)) {
if (file->f_flags & O_NONBLOCK)
return -EAGAIN;
- if (down_interruptible(&data->mutex))
+ if (wait_event_interruptible(data->read_wait,
+ !cpumask_empty(&data->cpu_event)))
return -EINTR;
}
if (data->state == STATE_LOG_RECORD) {
spin_lock_irqsave(&data_saved_lock, flags);
cpumask_set_cpu(cpu, &data->cpu_event);
- salinfo_work_to_do(data);
+ wake_up_interruptible(&data->read_wait);
spin_unlock_irqrestore(&data_saved_lock, flags);
}
return 0;
i < ARRAY_SIZE(salinfo_data);
++i, ++data) {
cpumask_set_cpu(cpu, &data->cpu_event);
- salinfo_work_to_do(data);
+ wake_up_interruptible(&data->read_wait);
}
spin_unlock_irqrestore(&data_saved_lock, flags);
break;
for (i = 0; i < ARRAY_SIZE(salinfo_log_name); i++) {
data = salinfo_data + i;
data->type = i;
- sema_init(&data->mutex, 1);
+ init_waitqueue_head(&data->read_wait);
dir = proc_mkdir(salinfo_log_name[i], salinfo_dir);
if (!dir)
continue;