summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/nvos
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2009-12-21 20:37:10 -0800
committerGary King <gking@nvidia.com>2009-12-21 20:37:10 -0800
commit9906366d955a8f43661eb5d44af8638d52c750b1 (patch)
treef7acbeacccf7c1366cc64390e1f4d2ecb82693dc /arch/arm/mach-tegra/nvos
parent479accfb4dec15c9eb19ea40c2b7b1cb80c02855 (diff)
tegra: fix race condition in NvOs interrupt registration
sema_init wasn't called until after the first call to wake_up_process, resulting in a race condition between the kernel thread down'ing the semaphore and the main thread initializing it. move sema_init to before kthread_create to eliminate this race.
Diffstat (limited to 'arch/arm/mach-tegra/nvos')
-rw-r--r--arch/arm/mach-tegra/nvos/nvos.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/arm/mach-tegra/nvos/nvos.c b/arch/arm/mach-tegra/nvos/nvos.c
index 15b18606d4fe..baa6b339bd7d 100644
--- a/arch/arm/mach-tegra/nvos/nvos.c
+++ b/arch/arm/mach-tegra/nvos/nvos.c
@@ -1474,16 +1474,16 @@ NvError NvOsInterruptRegisterInternal(
{
struct sched_param p;
p.sched_priority = KTHREAD_IRQ_PRIO;
+ sema_init(&(pNewBlock->IrqList[i].sem), 0);
pNewBlock->IrqList[i].task =
kthread_create(NvOsInterruptThreadWrapper,
(void *)((pIrqList[i]&0xffff) | ((i&0xffff)<<16)),
- "NvOsIntrThread/%d", pIrqList[i]);
+ pNewBlock->IrqList[i].IrqName);
if (sched_setscheduler(pNewBlock->IrqList[i].task,
SCHED_FIFO, &p)<0)
NvOsDebugPrintf("Failed to elevate priority for IRQ %u\n",
pIrqList[i]);
wake_up_process( pNewBlock->IrqList[i].task );
- sema_init( &(pNewBlock->IrqList[i].sem), 0);
}
if ((pNewBlock->Flags & NVOS_IRQ_TYPE_MASK)==NVOS_IRQ_IS_TASKLET)
@@ -1506,6 +1506,7 @@ NvError NvOsInterruptRegisterInternal(
goto clean_fail;
}
}
+ *handle = (NvOsInterruptHandle)pNewBlock;
if (InterruptEnable)
{
pNewBlock->Flags |= NVOS_IRQ_IS_ENABLED;
@@ -1514,7 +1515,6 @@ NvError NvOsInterruptRegisterInternal(
for ( ; i<IrqListSize; i++)
enable_irq(pIrqList[i]);
- *handle = (NvOsInterruptHandle)pNewBlock;
return NvSuccess;
clean_fail: