diff options
author | Xinyu Chen <xinyu.chen@freescale.com> | 2012-03-30 11:36:25 +0800 |
---|---|---|
committer | Xinyu Chen <xinyu.chen@freescale.com> | 2012-03-30 11:36:25 +0800 |
commit | 88f08b421c91f2d4db3a110e5e3a86d64e2b40c9 (patch) | |
tree | e3af9f0bf2a355fd69119ae9b680371d39012a2d /kernel | |
parent | 6cf2f136f3df6fad82ddabd89d93c53181564274 (diff) | |
parent | f53c766e85d69add6a26d6f3e233dec6dc98de1e (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.c | 38 |
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)) |