aboutsummaryrefslogtreecommitdiff
path: root/drivers/gator/gator_cookies.c
diff options
context:
space:
mode:
authorJon Medhurst <tixy@linaro.org>2014-04-10 09:02:02 +0100
committerJon Medhurst <tixy@linaro.org>2014-04-10 12:11:17 +0100
commit15ce78dafc08b1c5c3ec8f42070ae37160b5154c (patch)
treecdb25c6758ac3fe5ac6f9e151642a4779e2fc742 /drivers/gator/gator_cookies.c
parent34d9769988397a1edf93ad1966c167591ab29e79 (diff)
gator: Version 5.18
Signed-off-by: Jon Medhurst <tixy@linaro.org>
Diffstat (limited to 'drivers/gator/gator_cookies.c')
-rw-r--r--drivers/gator/gator_cookies.c82
1 files changed, 56 insertions, 26 deletions
diff --git a/drivers/gator/gator_cookies.c b/drivers/gator/gator_cookies.c
index 91adfdde9be..5c7d842070e 100644
--- a/drivers/gator/gator_cookies.c
+++ b/drivers/gator/gator_cookies.c
@@ -1,5 +1,5 @@
/**
- * Copyright (C) ARM Limited 2010-2013. All rights reserved.
+ * Copyright (C) ARM Limited 2010-2014. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -15,17 +15,22 @@
static uint32_t *gator_crc32_table;
static unsigned int translate_buffer_mask;
+struct cookie_args {
+ struct task_struct *task;
+ const char *text;
+};
+
static DEFINE_PER_CPU(char *, translate_text);
static DEFINE_PER_CPU(uint32_t, cookie_next_key);
static DEFINE_PER_CPU(uint64_t *, cookie_keys);
static DEFINE_PER_CPU(uint32_t *, cookie_values);
static DEFINE_PER_CPU(int, translate_buffer_read);
static DEFINE_PER_CPU(int, translate_buffer_write);
-static DEFINE_PER_CPU(void **, translate_buffer);
+static DEFINE_PER_CPU(struct cookie_args *, translate_buffer);
static uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq);
static void wq_cookie_handler(struct work_struct *unused);
-DECLARE_WORK(cookie_work, wq_cookie_handler);
+static DECLARE_WORK(cookie_work, wq_cookie_handler);
static struct timer_list app_process_wake_up_timer;
static void app_process_wake_up_handler(unsigned long unused_data);
@@ -109,36 +114,62 @@ static void cookiemap_add(uint64_t key, uint32_t value)
}
#ifndef CONFIG_PREEMPT_RT_FULL
-static void translate_buffer_write_ptr(int cpu, void *x)
+static void translate_buffer_write_args(int cpu, struct task_struct *task, const char *text)
{
- per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x;
- per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask;
+ unsigned long flags;
+ int write;
+ int next_write;
+ struct cookie_args *args;
+
+ local_irq_save(flags);
+
+ write = per_cpu(translate_buffer_write, cpu);
+ next_write = (write + 1) & translate_buffer_mask;
+
+ // At least one entry must always remain available as when read == write, the queue is empty not full
+ if (next_write != per_cpu(translate_buffer_read, cpu)) {
+ args = &per_cpu(translate_buffer, cpu)[write];
+ args->task = task;
+ args->text = text;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+ get_task_struct(task);
+#endif
+ per_cpu(translate_buffer_write, cpu) = next_write;
+ }
+
+ local_irq_restore(flags);
}
#endif
-static void *translate_buffer_read_ptr(int cpu)
+static void translate_buffer_read_args(int cpu, struct cookie_args *args)
{
- void *value = per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_read, cpu)++];
- per_cpu(translate_buffer_read, cpu) &= translate_buffer_mask;
- return value;
+ unsigned long flags;
+ int read;
+
+ local_irq_save(flags);
+
+ read = per_cpu(translate_buffer_read, cpu);
+ *args = per_cpu(translate_buffer, cpu)[read];
+ per_cpu(translate_buffer_read, cpu) = (read + 1) & translate_buffer_mask;
+
+ local_irq_restore(flags);
}
static void wq_cookie_handler(struct work_struct *unused)
{
- struct task_struct *task;
- char *text;
+ struct cookie_args args;
int cpu = get_physical_cpu(), cookie;
- unsigned int commit;
mutex_lock(&start_mutex);
if (gator_started != 0) {
- commit = per_cpu(translate_buffer_write, cpu);
- while (per_cpu(translate_buffer_read, cpu) != commit) {
- task = (struct task_struct *)translate_buffer_read_ptr(cpu);
- text = (char *)translate_buffer_read_ptr(cpu);
- cookie = get_cookie(cpu, task, text, true);
- marshal_link(cookie, task->tgid, task->pid);
+ while (per_cpu(translate_buffer_read, cpu) != per_cpu(translate_buffer_write, cpu)) {
+ translate_buffer_read_args(cpu, &args);
+ cookie = get_cookie(cpu, args.task, args.text, true);
+ marshal_link(cookie, args.task->tgid, args.task->pid);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39)
+ put_task_struct(args.task);
+#endif
}
}
@@ -169,15 +200,14 @@ static int translate_app_process(const char **text, int cpu, struct task_struct
// inconsistent during a context switch between android/linux versions
if (!from_wq) {
// Check if already in buffer
- int ptr = per_cpu(translate_buffer_read, cpu);
- while (ptr != per_cpu(translate_buffer_write, cpu)) {
- if (per_cpu(translate_buffer, cpu)[ptr] == (void *)task)
+ int pos = per_cpu(translate_buffer_read, cpu);
+ while (pos != per_cpu(translate_buffer_write, cpu)) {
+ if (per_cpu(translate_buffer, cpu)[pos].task == task)
goto out;
- ptr = (ptr + 2) & translate_buffer_mask;
+ pos = (pos + 1) & translate_buffer_mask;
}
- translate_buffer_write_ptr(cpu, (void *)task);
- translate_buffer_write_ptr(cpu, (void *)*text);
+ translate_buffer_write_args(cpu, task, *text);
// Not safe to call in RT-Preempt full in schedule switch context
mod_timer(&app_process_wake_up_timer, jiffies + 1);
@@ -340,7 +370,7 @@ static int cookies_initialize(void)
}
memset(per_cpu(cookie_values, cpu), 0, size);
- per_cpu(translate_buffer, cpu) = (void **)kmalloc(TRANSLATE_BUFFER_SIZE, GFP_KERNEL);
+ per_cpu(translate_buffer, cpu) = (struct cookie_args *)kmalloc(TRANSLATE_BUFFER_SIZE, GFP_KERNEL);
if (!per_cpu(translate_buffer, cpu)) {
err = -ENOMEM;
goto cookie_setup_error;