summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXianzhong <b07117@freescale.com>2013-01-26 02:20:55 +0800
committerXianzhong <b07117@freescale.com>2013-01-27 20:01:14 +0800
commit7aca46617dbf94a1a62220408c629771e0377e9e (patch)
treea8d4e0802f6f7d293822e84941abc58ce751c178
parent16182cc8f6d6b51280f7bb9e5c1621ad309afd7d (diff)
ENGR00241777 fix rare kernel panic by gpu lowmem killer
task_free notification procedure cannot be registered/unregistered during gpu memory allocation dynamically, when the lowmem killer triggers a kill signal to one app, and then rescan to check if memory is available, if other 3d apps free some memory prior to the killed app in unlikely case, then task_free notification procedure will be unregistered before the notification of the killed app is received, that causes kernel panic in task_free processing. the fix is to move task_free procedures into gpu kernel drv_init and drv_exit. Signed-off-by: Xianzhong <b07117@freescale.com> Acked-by: Lily Zhang
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c36
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c27
2 files changed, 28 insertions, 35 deletions
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
index 0a0253a23e33..8b76091dbc4c 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
@@ -502,27 +502,9 @@ gckKERNEL_Destroy(
#include <linux/sched.h>
#include <linux/notifier.h>
-static struct task_struct *lowmem_deathpending;
+extern struct task_struct *lowmem_deathpending;
static unsigned long lowmem_deathpending_timeout;
-static int
-task_notify_func(struct notifier_block *self, unsigned long val, void *data);
-
-static struct notifier_block task_nb = {
- .notifier_call = task_notify_func,
-};
-
-static int
-task_notify_func(struct notifier_block *self, unsigned long val, void *data)
-{
- struct task_struct *task = data;
-
- if (task == lowmem_deathpending)
- lowmem_deathpending = NULL;
-
- return NOTIFY_OK;
-}
-
static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel)
{
struct task_struct *p;
@@ -644,9 +626,6 @@ _AllocateMemory(
gcuVIDMEM_NODE_PTR node = gcvNULL;
gctBOOL tileStatusInVirtual;
gctBOOL forceContiguous = gcvFALSE;
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
- gctBOOL forceContiguousShrinking = gcvFALSE;
-#endif
gcmkHEADER_ARG("Kernel=0x%x *Pool=%d Bytes=%lu Alignment=%lu Type=%d",
Kernel, *Pool, Bytes, Alignment, Type);
@@ -806,12 +785,6 @@ _AllocateMemory_Retry:
#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
if(forceContiguous == gcvTRUE)
{
- if(forceContiguousShrinking == gcvFALSE)
- {
- forceContiguousShrinking = gcvTRUE;
- task_free_register(&task_nb);
- }
-
if(force_contiguous_lowmem_shrink(Kernel) == 0)
{
/* Sleep 1 millisecond. */
@@ -824,13 +797,6 @@ _AllocateMemory_Retry:
gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY);
}
-#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
- if(forceContiguous == gcvTRUE && forceContiguousShrinking == gcvTRUE)
- {
- task_free_unregister(&task_nb);
- }
-#endif
-
/* Return node and pool used for allocation. */
*Node = node;
*Pool = pool;
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
index 9683cb7bedcf..334c495f0d01 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
@@ -41,6 +41,31 @@
#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
# include <linux/resmem_account.h>
+# include <linux/kernel.h>
+# include <linux/mm.h>
+# include <linux/oom.h>
+# include <linux/sched.h>
+# include <linux/notifier.h>
+
+struct task_struct *lowmem_deathpending;
+
+static int
+task_notify_func(struct notifier_block *self, unsigned long val, void *data);
+
+static struct notifier_block task_nb = {
+ .notifier_call = task_notify_func,
+};
+
+static int
+task_notify_func(struct notifier_block *self, unsigned long val, void *data)
+{
+ struct task_struct *task = data;
+
+ if (task == lowmem_deathpending)
+ lowmem_deathpending = NULL;
+
+ return NOTIFY_OK;
+}
#endif
@@ -819,6 +844,7 @@ static int drv_init(void)
}
#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
+ task_free_register(&task_nb);
viv_gpu_resmem_handler.data = device->kernels[gcvCORE_MAJOR];
register_reserved_memory_account(&viv_gpu_resmem_handler);
#endif
@@ -904,6 +930,7 @@ static void drv_exit(void)
gcmkHEADER();
#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT
+ task_free_unregister(&task_nb);
unregister_reserved_memory_account(&viv_gpu_resmem_handler);
#endif