gpu: add lock before use other process's task

This commit is contained in:
杜坤明
2011-03-28 12:01:00 +08:00
parent a77f28b75e
commit 4d2c237101
3 changed files with 46 additions and 21 deletions

View File

@@ -755,7 +755,7 @@ static void gpu_early_suspend(struct early_suspend *h)
{
gceSTATUS status;
printk("Enter %s \n", __func__);
//printk("Enter %s \n", __func__);
msleep(50); //Wait for gpu finish
@@ -767,14 +767,14 @@ static void gpu_early_suspend(struct early_suspend *h)
return;
}
printk("Exit %s \n", __func__);
//printk("Exit %s \n", __func__);
}
static void gpu_early_resume(struct early_suspend *h)
{
gceSTATUS status;
printk("Enter %s \n", __func__);
//printk("Enter %s \n", __func__);
status = gckHARDWARE_SetPowerManagementState(galDevice->kernel->hardware, gcvPOWER_IDLE);
@@ -786,7 +786,7 @@ static void gpu_early_resume(struct early_suspend *h)
return;
}
printk("Exit %s \n", __func__);
//printk("Exit %s \n", __func__);
}
struct early_suspend gpu_early_suspend_info = {
@@ -857,7 +857,7 @@ static int __devinit gpu_suspend(struct platform_device *dev, pm_message_t state
gceSTATUS status;
gckGALDEVICE device;
printk("Enter %s \n", __func__);
//printk("Enter %s \n", __func__);
device = platform_get_drvdata(dev);
@@ -871,7 +871,7 @@ static int __devinit gpu_suspend(struct platform_device *dev, pm_message_t state
return -1;
}
printk("Exit %s \n", __func__);
//printk("Exit %s \n", __func__);
return 0;
}
@@ -881,7 +881,7 @@ static int __devinit gpu_resume(struct platform_device *dev)
gceSTATUS status;
gckGALDEVICE device;
printk("Enter %s \n", __func__);
//printk("Enter %s \n", __func__);
device = platform_get_drvdata(dev);
@@ -895,7 +895,7 @@ static int __devinit gpu_resume(struct platform_device *dev)
return -1;
}
printk("Exit %s \n", __func__);
//printk("Exit %s \n", __func__);
return 0;
}

View File

@@ -57,7 +57,7 @@
#include "gc_hal_kernel_os.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
#define FIND_TASK_BY_PID(x) pid_task(find_vpid(x), PIDTYPE_PID)
#define FIND_TASK_BY_PID(x) get_pid_task(find_vpid(x), PIDTYPE_PID)
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
#define FIND_TASK_BY_PID(x) find_task_by_vpid(x)
#else

View File

@@ -1105,6 +1105,7 @@ gckOS_UnmapMemory(
PLINUX_MDL_MAP mdlMap;
PLINUX_MDL mdl = (PLINUX_MDL)Physical;
struct task_struct * task;
struct mm_struct * mm;
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -1143,12 +1144,19 @@ gckOS_UnmapMemory(
/* Get the current pointer for the task with stored pid. */
task = FIND_TASK_BY_PID(mdlMap->pid);
if(task) {
mm = get_task_mm(task);
put_task_struct(task);
} else {
mm = gcvNULL;
}
if (task != gcvNULL && task->mm != gcvNULL)
if (mm)
{
down_write(&task->mm->mmap_sem);
do_munmap(task->mm, (unsigned long)Logical, mdl->numPages*PAGE_SIZE);
up_write(&task->mm->mmap_sem);
down_write(&mm->mmap_sem);
do_munmap(mm, (unsigned long)Logical, mdl->numPages*PAGE_SIZE);
up_write(&mm->mmap_sem);
mmput(mm);
}
else
{
@@ -1516,6 +1524,7 @@ gceSTATUS gckOS_FreeNonPagedMemory(
PLINUX_MDL mdl;
PLINUX_MDL_MAP mdlMap;
struct task_struct * task;
struct mm_struct * mm;
#ifdef NO_DMA_COHERENT
unsigned size;
@@ -1567,12 +1576,18 @@ gceSTATUS gckOS_FreeNonPagedMemory(
{
/* Get the current pointer for the task with stored pid. */
task = FIND_TASK_BY_PID(mdlMap->pid);
if(task) {
mm = get_task_mm(task);
put_task_struct(task);
} else {
mm = gcvNULL;
}
if (task != gcvNULL && task->mm != gcvNULL)
if (mm)
{
down_write(&task->mm->mmap_sem);
down_write(&mm->mmap_sem);
if (do_munmap(task->mm,
if (do_munmap(mm,
(unsigned long)mdlMap->vmaAddr,
mdl->numPages * PAGE_SIZE) < 0)
{
@@ -1585,7 +1600,8 @@ gceSTATUS gckOS_FreeNonPagedMemory(
(gctUINT32)mdlMap->vmaAddr);
}
up_write(&task->mm->mmap_sem);
up_write(&mm->mmap_sem);
mmput(mm);
}
mdlMap->vmaAddr = gcvNULL;
@@ -3260,6 +3276,7 @@ gceSTATUS gckOS_UnlockPages(
PLINUX_MDL_MAP mdlMap;
PLINUX_MDL mdl = (PLINUX_MDL)Physical;
struct task_struct * task;
struct mm_struct * mm;
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
@@ -3283,12 +3300,19 @@ gceSTATUS gckOS_UnlockPages(
{
/* Get the current pointer for the task with stored pid. */
task = FIND_TASK_BY_PID(mdlMap->pid);
if(task) {
mm = get_task_mm(task);
put_task_struct(task);
} else {
mm = gcvNULL;
}
if (task != gcvNULL && task->mm != gcvNULL)
if (mm)
{
down_write(&task->mm->mmap_sem);
do_munmap(task->mm, (unsigned long)Logical, mdl->numPages * PAGE_SIZE);
up_write(&task->mm->mmap_sem);
down_write(&mm->mmap_sem);
do_munmap(mm, (unsigned long)Logical, mdl->numPages * PAGE_SIZE);
up_write(&mm->mmap_sem);
mmput(mm);
}
mdlMap->vmaAddr = gcvNULL;
@@ -3878,6 +3902,7 @@ gckOS_UserSignal(
/* Success. */
status = gcvSTATUS_OK;
}
put_task_struct(task);
}
else
{