diff options
Diffstat (limited to 'driver/gator_cookies.c')
-rw-r--r-- | driver/gator_cookies.c | 36 |
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--) { |