|
@@ -141,7 +141,7 @@ enum salinfo_state {
|
|
|
|
|
|
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 */
|
|
@@ -182,21 +182,6 @@ struct salinfo_platform_oemdata_parms {
|
|
|
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)
|
|
|
{
|
|
@@ -258,7 +243,7 @@ salinfo_log_wakeup(int type, u8 *buffer, u64 size, int irqsafe)
|
|
|
}
|
|
|
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);
|
|
|
}
|
|
|
}
|
|
@@ -271,14 +256,10 @@ extern void ia64_mlogbuf_dump(void);
|
|
|
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
|
|
@@ -308,10 +289,11 @@ salinfo_event_read(struct file *file, char __user *buffer, size_t count, loff_t
|
|
|
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;
|
|
|
}
|
|
|
|
|
@@ -510,7 +492,7 @@ salinfo_log_clear(struct salinfo_data *data, int cpu)
|
|
|
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;
|
|
@@ -582,7 +564,7 @@ salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu
|
|
|
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;
|
|
@@ -640,7 +622,7 @@ salinfo_init(void)
|
|
|
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;
|