aboutsummaryrefslogtreecommitdiff
path: root/driver/gator_cookies.c
diff options
context:
space:
mode:
Diffstat (limited to 'driver/gator_cookies.c')
-rw-r--r--driver/gator_cookies.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/driver/gator_cookies.c b/driver/gator_cookies.c
index 5f98a1c..91adfdd 100644
--- a/driver/gator_cookies.c
+++ b/driver/gator_cookies.c
@@ -8,7 +8,8 @@
*/
#define COOKIEMAP_ENTRIES 1024 /* must be power of 2 */
-#define TRANSLATE_SIZE 256
+#define TRANSLATE_BUFFER_SIZE 512 // must be a power of 2 - 512/4 = 128 entries
+#define TRANSLATE_TEXT_SIZE 256
#define MAX_COLLISIONS 2
static uint32_t *gator_crc32_table;
@@ -22,7 +23,7 @@ static DEFINE_PER_CPU(int, translate_buffer_read);
static DEFINE_PER_CPU(int, translate_buffer_write);
static DEFINE_PER_CPU(void **, translate_buffer);
-static inline uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq);
+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 struct timer_list app_process_wake_up_timer;
@@ -107,11 +108,13 @@ static void cookiemap_add(uint64_t key, uint32_t value)
values[0] = value;
}
+#ifndef CONFIG_PREEMPT_RT_FULL
static void translate_buffer_write_ptr(int cpu, void *x)
{
per_cpu(translate_buffer, cpu)[per_cpu(translate_buffer_write, cpu)++] = x;
per_cpu(translate_buffer_write, cpu) &= translate_buffer_mask;
}
+#endif
static void *translate_buffer_read_ptr(int cpu)
{
@@ -124,7 +127,7 @@ static void wq_cookie_handler(struct work_struct *unused)
{
struct task_struct *task;
char *text;
- int cpu = get_physical_cpu();
+ int cpu = get_physical_cpu(), cookie;
unsigned int commit;
mutex_lock(&start_mutex);
@@ -134,7 +137,8 @@ static void wq_cookie_handler(struct work_struct *unused)
while (per_cpu(translate_buffer_read, cpu) != commit) {
task = (struct task_struct *)translate_buffer_read_ptr(cpu);
text = (char *)translate_buffer_read_ptr(cpu);
- get_cookie(cpu, task, text, true);
+ cookie = get_cookie(cpu, task, text, true);
+ marshal_link(cookie, task->tgid, task->pid);
}
}
@@ -156,15 +160,16 @@ static int translate_app_process(const char **text, int cpu, struct task_struct
struct mm_struct *mm;
struct page *page = NULL;
struct vm_area_struct *page_vma;
- int bytes, offset, retval = 0, ptr;
+ int bytes, offset, retval = 0;
char *buf = per_cpu(translate_text, cpu);
+#ifndef CONFIG_PREEMPT_RT_FULL
// Push work into a work queue if in atomic context as the kernel functions below might sleep
// Rely on the in_interrupt variable rather than in_irq() or in_interrupt() kernel functions, as the value of these functions seems
// inconsistent during a context switch between android/linux versions
if (!from_wq) {
// Check if already in buffer
- ptr = per_cpu(translate_buffer_read, cpu);
+ 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)
goto out;
@@ -174,9 +179,11 @@ static int translate_app_process(const char **text, int cpu, struct task_struct
translate_buffer_write_ptr(cpu, (void *)task);
translate_buffer_write_ptr(cpu, (void *)*text);
+ // Not safe to call in RT-Preempt full in schedule switch context
mod_timer(&app_process_wake_up_timer, jiffies + 1);
goto out;
}
+#endif
mm = get_task_mm(task);
if (!mm)
@@ -186,8 +193,8 @@ static int translate_app_process(const char **text, int cpu, struct task_struct
addr = mm->arg_start;
len = mm->arg_end - mm->arg_start;
- if (len > TRANSLATE_SIZE)
- len = TRANSLATE_SIZE;
+ if (len > TRANSLATE_TEXT_SIZE)
+ len = TRANSLATE_TEXT_SIZE;
down_read(&mm->mmap_sem);
while (len) {
@@ -225,7 +232,7 @@ out:
return retval;
}
-static inline uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq)
+static uint32_t get_cookie(int cpu, struct task_struct *task, const char *text, bool from_wq)
{
unsigned long flags, cookie;
uint64_t key;
@@ -312,8 +319,7 @@ static int cookies_initialize(void)
uint32_t crc, poly;
int i, j, cpu, size, err = 0;
- int translate_buffer_size = 512; // must be a power of 2
- translate_buffer_mask = translate_buffer_size / sizeof(per_cpu(translate_buffer, 0)[0]) - 1;
+ translate_buffer_mask = TRANSLATE_BUFFER_SIZE / sizeof(per_cpu(translate_buffer, 0)[0]) - 1;
for_each_present_cpu(cpu) {
per_cpu(cookie_next_key, cpu) = nr_cpu_ids + cpu;
@@ -334,7 +340,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) = (void **)kmalloc(TRANSLATE_BUFFER_SIZE, GFP_KERNEL);
if (!per_cpu(translate_buffer, cpu)) {
err = -ENOMEM;
goto cookie_setup_error;
@@ -343,7 +349,7 @@ static int cookies_initialize(void)
per_cpu(translate_buffer_write, cpu) = 0;
per_cpu(translate_buffer_read, cpu) = 0;
- per_cpu(translate_text, cpu) = (char *)kmalloc(TRANSLATE_SIZE, GFP_KERNEL);
+ per_cpu(translate_text, cpu) = (char *)kmalloc(TRANSLATE_TEXT_SIZE, GFP_KERNEL);
if (!per_cpu(translate_text, cpu)) {
err = -ENOMEM;
goto cookie_setup_error;
@@ -353,6 +359,10 @@ static int cookies_initialize(void)
// build CRC32 table
poly = 0x04c11db7;
gator_crc32_table = (uint32_t *)kmalloc(256 * sizeof(uint32_t), GFP_KERNEL);
+ if (!gator_crc32_table) {
+ err = -ENOMEM;
+ goto cookie_setup_error;
+ }
for (i = 0; i < 256; i++) {
crc = i;
for (j = 8; j > 0; j--) {