summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-01-25 18:06:05 -0800
committerGary King <gking@nvidia.com>2010-01-26 14:16:13 -0800
commit73f6d4ab65fb57e19e3983421538637595b44a13 (patch)
treeb87c1496acdb2fb418acbbe1e2b9ccc70a1b5597 /arch
parent3ede8bfc14f5398d5458b14413ab297943469213 (diff)
tegra nvos: fix mutex and semaphore handling for frozen tasks
if a kernel mutex lock or semaphore wait is interrupted because the task is being frozen, the correct action to take is to call try_to_freeze, similar to wait_event_freezable -ERESTARTSYS is not returned to higher-level software in the event of a resume; the assumption is that the resume process will ensure that any freezable task is resumed in a state where the NvOsSemaphore will be signalable, and that the Wait operation should only return once the semaphore is actually signalled. bug 645292 Change-Id: Ia9c6c2426d889851437d93506ce33cb23cee5e8c
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/nvos/nvos.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/arch/arm/mach-tegra/nvos/nvos.c b/arch/arm/mach-tegra/nvos/nvos.c
index 620c9ed1b624..e41c5a99cce5 100644
--- a/arch/arm/mach-tegra/nvos/nvos.c
+++ b/arch/arm/mach-tegra/nvos/nvos.c
@@ -60,6 +60,7 @@
#include <asm/setup.h>
#include <asm/cacheflush.h>
#include <mach/irqs.h>
+#include <linux/freezer.h>
#if NVOS_TRACE || NV_DEBUG
#undef NvOsAlloc
@@ -984,10 +985,9 @@ void NvOsMutexLock(NvOsMutexHandle mutex)
/* FIXME: interruptible mutexes may not be necessary, since this
* implementation is only used by the kernel tasks. */
ret = mutex_lock_interruptible( &mutex->mutex );
-
// If a signal arrives while the task is sleeping,
// re-schedule it and attempt to reacquire the mutex
- if (ret)
+ if (ret && !try_to_freeze())
schedule();
} while (ret);
mutex->owner = info;
@@ -1108,16 +1108,16 @@ NvError NvOsSemaphoreUnmarshal(
int NvOsSemaphoreWaitInterruptible(NvOsSemaphoreHandle semaphore);
int NvOsSemaphoreWaitInterruptible(NvOsSemaphoreHandle semaphore)
{
- NV_ASSERT( semaphore );
+ NV_ASSERT(semaphore);
- return down_interruptible( &semaphore->sem );
+ return down_interruptible(&semaphore->sem);
}
void NvOsSemaphoreWait(NvOsSemaphoreHandle semaphore)
{
int ret;
- NV_ASSERT( semaphore );
+ NV_ASSERT(semaphore);
do
{
@@ -1125,13 +1125,13 @@ void NvOsSemaphoreWait(NvOsSemaphoreHandle semaphore)
* one for semaphore that were created by users ioctl'ing into
* the nvos device (which need down_interruptible), and others that
* are created and used by the kernel drivers, which do not */
- ret = down_interruptible( &semaphore->sem );
-
- //The kernel doesn't reschedule tasks
- //that have pending signals. If a signal
- //is pending, forcibly reschedule the task.
- if (ret)
- schedule();
+ ret = down_interruptible(&semaphore->sem);
+ /* The kernel doesn't reschedule tasks
+ * that have pending signals. If a signal
+ * is pending, forcibly reschedule the task.
+ */
+ if (ret && !try_to_freeze())
+ schedule();
} while (ret);
}
@@ -1163,7 +1163,7 @@ NvError NvOsSemaphoreWaitTimeout(
/* FIXME: The kernel doesn't provide an interruptible timed
* semaphore wait, which would be preferable for our the ioctl'd
* NvOs sempahores. */
- t = down_timeout( &semaphore->sem, (long)msecs_to_jiffies( msec ) );
+ t = down_timeout(&semaphore->sem, (long)msecs_to_jiffies( msec ));
if (t == -ETIME)
return NvError_Timeout;