summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorXinyu Chen <xinyu.chen@freescale.com>2012-03-30 11:36:25 +0800
committerXinyu Chen <xinyu.chen@freescale.com>2012-03-30 11:36:25 +0800
commit88f08b421c91f2d4db3a110e5e3a86d64e2b40c9 (patch)
treee3af9f0bf2a355fd69119ae9b680371d39012a2d /kernel
parent6cf2f136f3df6fad82ddabd89d93c53181564274 (diff)
parentf53c766e85d69add6a26d6f3e233dec6dc98de1e (diff)
Merge remote branch 'fsl-linux-sdk/imx_3.0.15' into imx_3.0.15_4.6.6
Conflicts: arch/arm/configs/imx6_defconfig arch/arm/configs/imx6_updater_defconfig arch/arm/mach-mx6/board-mx6q_sabreauto.c arch/arm/mach-mx6/board-mx6q_sabresd.c arch/arm/mach-mx6/clock.c arch/arm/mach-mx6/localtimer.c drivers/cpufreq/Makefile drivers/cpufreq/cpufreq_interactive.c drivers/input/keyboard/gpio_keys.c drivers/media/video/mxc/capture/Kconfig drivers/media/video/mxc/capture/mxc_v4l2_capture.c drivers/mmc/card/block.c drivers/mmc/host/sdhci-esdhc-imx.c drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_device.c drivers/usb/otg/fsl_otg.c drivers/video/mxc/mxc_ipuv3_fb.c include/linux/fsl_devices.h include/linux/mmc/host.h sound/soc/imx/Kconfig sound/soc/imx/Makefile sound/soc/imx/imx-hdmi-dma.c sound/soc/imx/imx-wm8958.c
Diffstat (limited to 'kernel')
-rw-r--r--kernel/futex.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/kernel/futex.c b/kernel/futex.c
index 11cbe052b2e8..e250f004c6e3 100644
--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -314,17 +314,29 @@ again:
#endif
lock_page(page_head);
+
+ /*
+ * If page_head->mapping is NULL, then it cannot be a PageAnon
+ * page; but it might be the ZERO_PAGE or in the gate area or
+ * in a special mapping (all cases which we are happy to fail);
+ * or it may have been a good file page when get_user_pages_fast
+ * found it, but truncated or holepunched or subjected to
+ * invalidate_complete_page2 before we got the page lock (also
+ * cases which we are happy to fail). And we hold a reference,
+ * so refcount care in invalidate_complete_page's remove_mapping
+ * prevents drop_caches from setting mapping to NULL beneath us.
+ *
+ * The case we do have to guard against is when memory pressure made
+ * shmem_writepage move it from filecache to swapcache beneath us:
+ * an unlikely race, but we do need to retry for page_head->mapping.
+ */
if (!page_head->mapping) {
+ int shmem_swizzled = PageSwapCache(page_head);
unlock_page(page_head);
put_page(page_head);
- /*
- * ZERO_PAGE pages don't have a mapping. Avoid a busy loop
- * trying to find one. RW mapping would have COW'd (and thus
- * have a mapping) so this page is RO and won't ever change.
- */
- if ((page_head == ZERO_PAGE(address)))
- return -EFAULT;
- goto again;
+ if (shmem_swizzled)
+ goto again;
+ return -EFAULT;
}
/*
@@ -854,7 +866,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
{
struct task_struct *new_owner;
struct futex_pi_state *pi_state = this->pi_state;
- u32 curval, newval;
+ u32 uninitialized_var(curval), newval;
if (!pi_state)
return -EINVAL;
@@ -916,7 +928,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this)
static int unlock_futex_pi(u32 __user *uaddr, u32 uval)
{
- u32 oldval;
+ u32 uninitialized_var(oldval);
/*
* There is no waiter, so we unlock the futex. The owner died
@@ -1576,7 +1588,7 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS;
struct futex_pi_state *pi_state = q->pi_state;
struct task_struct *oldowner = pi_state->owner;
- u32 uval, curval, newval;
+ u32 uval, uninitialized_var(curval), newval;
int ret;
/* Owner died? */
@@ -1793,7 +1805,7 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
*
* Returns:
* 0 - uaddr contains val and hb has been locked
- * <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlcoked
+ * <1 - -EFAULT or -EWOULDBLOCK (uaddr does not contain val) and hb is unlocked
*/
static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags,
struct futex_q *q, struct futex_hash_bucket **hb)
@@ -2481,7 +2493,7 @@ err_unlock:
*/
int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, int pi)
{
- u32 uval, nval, mval;
+ u32 uval, uninitialized_var(nval), mval;
retry:
if (get_user(uval, uaddr))