public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org, Hugh Dickins <hughd@google.com>,
	Sasha Levin <sasha.levin@oracle.com>,
	Dave Jones <davej@redhat.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 3.15 029/109] shmem: fix faulting into a hole while its punched
Date: Sat, 26 Jul 2014 12:01:51 -0700	[thread overview]
Message-ID: <20140726190224.704741629@linuxfoundation.org> (raw)
In-Reply-To: <20140726190223.834037485@linuxfoundation.org>

3.15-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Hugh Dickins <hughd@google.com>

commit f00cdc6df7d7cfcabb5b740911e6788cb0802bdb upstream.

Trinity finds that mmap access to a hole while it's punched from shmem
can prevent the madvise(MADV_REMOVE) or fallocate(FALLOC_FL_PUNCH_HOLE)
from completing, until the reader chooses to stop; with the puncher's
hold on i_mutex locking out all other writers until it can complete.

It appears that the tmpfs fault path is too light in comparison with its
hole-punching path, lacking an i_data_sem to obstruct it; but we don't
want to slow down the common case.

Extend shmem_fallocate()'s existing range notification mechanism, so
shmem_fault() can refrain from faulting pages into the hole while it's
punched, waiting instead on i_mutex (when safe to sleep; or repeatedly
faulting when not).

[akpm@linux-foundation.org: coding-style fixes]
Signed-off-by: Hugh Dickins <hughd@google.com>
Reported-by: Sasha Levin <sasha.levin@oracle.com>
Tested-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Dave Jones <davej@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 mm/shmem.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 52 insertions(+), 4 deletions(-)

--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -80,11 +80,12 @@ static struct vfsmount *shm_mnt;
 #define SHORT_SYMLINK_LEN 128
 
 /*
- * shmem_fallocate and shmem_writepage communicate via inode->i_private
- * (with i_mutex making sure that it has only one user at a time):
- * we would prefer not to enlarge the shmem inode just for that.
+ * shmem_fallocate communicates with shmem_fault or shmem_writepage via
+ * inode->i_private (with i_mutex making sure that it has only one user at
+ * a time): we would prefer not to enlarge the shmem inode just for that.
  */
 struct shmem_falloc {
+	int	mode;		/* FALLOC_FL mode currently operating */
 	pgoff_t start;		/* start of range currently being fallocated */
 	pgoff_t next;		/* the next page offset to be fallocated */
 	pgoff_t nr_falloced;	/* how many new pages have been fallocated */
@@ -759,6 +760,7 @@ static int shmem_writepage(struct page *
 			spin_lock(&inode->i_lock);
 			shmem_falloc = inode->i_private;
 			if (shmem_falloc &&
+			    !shmem_falloc->mode &&
 			    index >= shmem_falloc->start &&
 			    index < shmem_falloc->next)
 				shmem_falloc->nr_unswapped++;
@@ -1233,6 +1235,44 @@ static int shmem_fault(struct vm_area_st
 	int error;
 	int ret = VM_FAULT_LOCKED;
 
+	/*
+	 * Trinity finds that probing a hole which tmpfs is punching can
+	 * prevent the hole-punch from ever completing: which in turn
+	 * locks writers out with its hold on i_mutex.  So refrain from
+	 * faulting pages into the hole while it's being punched, and
+	 * wait on i_mutex to be released if vmf->flags permits.
+	 */
+	if (unlikely(inode->i_private)) {
+		struct shmem_falloc *shmem_falloc;
+
+		spin_lock(&inode->i_lock);
+		shmem_falloc = inode->i_private;
+		if (!shmem_falloc ||
+		    shmem_falloc->mode != FALLOC_FL_PUNCH_HOLE ||
+		    vmf->pgoff < shmem_falloc->start ||
+		    vmf->pgoff >= shmem_falloc->next)
+			shmem_falloc = NULL;
+		spin_unlock(&inode->i_lock);
+		/*
+		 * i_lock has protected us from taking shmem_falloc seriously
+		 * once return from shmem_fallocate() went back up that stack.
+		 * i_lock does not serialize with i_mutex at all, but it does
+		 * not matter if sometimes we wait unnecessarily, or sometimes
+		 * miss out on waiting: we just need to make those cases rare.
+		 */
+		if (shmem_falloc) {
+			if ((vmf->flags & FAULT_FLAG_ALLOW_RETRY) &&
+			   !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT)) {
+				up_read(&vma->vm_mm->mmap_sem);
+				mutex_lock(&inode->i_mutex);
+				mutex_unlock(&inode->i_mutex);
+				return VM_FAULT_RETRY;
+			}
+			/* cond_resched? Leave that to GUP or return to user */
+			return VM_FAULT_NOPAGE;
+		}
+	}
+
 	error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, &ret);
 	if (error)
 		return ((error == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS);
@@ -1733,18 +1773,26 @@ static long shmem_fallocate(struct file
 
 	mutex_lock(&inode->i_mutex);
 
+	shmem_falloc.mode = mode & ~FALLOC_FL_KEEP_SIZE;
+
 	if (mode & FALLOC_FL_PUNCH_HOLE) {
 		struct address_space *mapping = file->f_mapping;
 		loff_t unmap_start = round_up(offset, PAGE_SIZE);
 		loff_t unmap_end = round_down(offset + len, PAGE_SIZE) - 1;
 
+		shmem_falloc.start = unmap_start >> PAGE_SHIFT;
+		shmem_falloc.next = (unmap_end + 1) >> PAGE_SHIFT;
+		spin_lock(&inode->i_lock);
+		inode->i_private = &shmem_falloc;
+		spin_unlock(&inode->i_lock);
+
 		if ((u64)unmap_end > (u64)unmap_start)
 			unmap_mapping_range(mapping, unmap_start,
 					    1 + unmap_end - unmap_start, 0);
 		shmem_truncate_range(inode, offset, offset + len - 1);
 		/* No need to unmap again: hole-punching leaves COWed pages */
 		error = 0;
-		goto out;
+		goto undone;
 	}
 
 	/* We need to check rlimit even when FALLOC_FL_KEEP_SIZE */



  parent reply	other threads:[~2014-07-26 19:36 UTC|newest]

Thread overview: 107+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-26 19:01 [PATCH 3.15 000/109] 3.15.7-stable review Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 001/109] usb: Check if port status is equal to RxDetect Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 002/109] usb: chipidea: udc: Disable auto ZLP generation on ep0 Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 003/109] media: gspca_pac7302: Add new usb-id for Genius i-Look 317 Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 004/109] ALSA: hda - Revert stream assignment order for Intel controllers Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 005/109] ALSA: hda - Fix broken PM due to incomplete i915 initialization Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 006/109] Drivers: hv: hv_fcopy: fix a race condition for SMP guest Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 007/109] Drivers: hv: util: Fix a bug in the KVP code Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 008/109] Revert "Bluetooth: Add a new PID/VID 0cf3/e005 for AR3012." Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 009/109] Bluetooth: Ignore H5 non-link packets in non-active state Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 010/109] fuse: timeout comparison fix Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 011/109] fuse: avoid scheduling while atomic Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 012/109] fuse: handle large user and group ID Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 013/109] fuse: ignore entry-timeout on LOOKUP_REVAL Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 014/109] iio:core: Handle error when mask type is not separate Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 015/109] tracing: instance_rmdir() leaks ftrace_event_file->filter Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 016/109] tracing: Fix graph tracer with stack tracer on other archs Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 017/109] tracing: Add ftrace_trace_stack into __trace_puts/__trace_bputs Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 018/109] tracing: Add TRACE_ITER_PRINTK flag check in __trace_puts/__trace_bputs Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 019/109] xen/balloon: set ballooned out pages as invalid in p2m Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 020/109] xen/manage: fix potential deadlock when resuming the console Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 021/109] hwmon: (da9055) Dont use dash in the name attribute Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 022/109] hwmon: (da9052) " Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 023/109] hwmon: (adt7470) Fix writes to temperature limit registers Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 024/109] igb: Workaround for i210 Errata 25: Slow System Clock Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 025/109] igb: do a reset on SR-IOV re-init if device is down Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 026/109] quota: missing lock in dqcache_shrink_scan() Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 027/109] iwlwifi: update the 7265 series HW IDs Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 028/109] iwlwifi: dvm: dont enable CTS to self Greg Kroah-Hartman
2014-07-26 19:01 ` Greg Kroah-Hartman [this message]
2014-07-26 19:01 ` [PATCH 3.15 030/109] shmem: fix faulting into a hole, not taking i_mutex Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 031/109] shmem: fix splicing from a hole while its punched Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 032/109] net/mlx4_core: Fix the error flow when probing with invalid VF configuration Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 033/109] net/mlx4_en: Dont configure the HW vxlan parser when vxlan offloading isnt set Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 034/109] ip_tunnel: fix ip_tunnel_lookup Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 035/109] slip: Fix deadlock in write_wakeup Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 036/109] slcan: Port write_wakeup deadlock fix from slip Greg Kroah-Hartman
2014-07-26 19:01 ` [PATCH 3.15 037/109] net: sctp: propagate sysctl errors from proc_do* properly Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 038/109] net: filter: fix upper BPF instruction limit Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 039/109] tcp: fix tcp_match_skb_to_sack() for unaligned SACK at end of an skb Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 040/109] net: sctp: check proc_dointvec result in proc_sctp_do_auth Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 041/109] 8021q: fix a potential memory leak Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 042/109] drivers: net: cpsw: fix dual EMAC stall when connected to same switch Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 044/109] net: fix UDP tunnel GSO of frag_list GRO packets Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 045/109] ipv4: fix dst race in sk_dst_get() Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 046/109] ipv4: irq safe sk_dst_[re]set() and ipv4_sk_update_pmtu() fix Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 047/109] net: fix sparse warning in sk_dst_set() Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 048/109] vlan: free percpu stats in device destructor Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 049/109] bnx2x: fix possible panic under memory stress Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 050/109] tcp: Fix divide by zero when pushing during tcp-repair Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 051/109] ipv4: icmp: Fix pMTU handling for rare case Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 054/109] net: Fix NETDEV_CHANGE notifier usage causing spurious arp flush Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 055/109] igmp: fix the problem when mc leave group Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 056/109] tcp: fix false undo corner cases Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 057/109] appletalk: Fix socket referencing in skb Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 058/109] net: mvneta: fix operation in 10 Mbit/s mode Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 059/109] net: mvneta: Fix big endian issue in mvneta_txq_desc_csum() Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 060/109] netlink: Fix handling of error from netlink_dump() Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 061/109] be2net: set EQ DB clear-intr bit in be_open() Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 062/109] r8152: fix r8152_csum_workaround function Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 063/109] tipc: clear next-pointer of message fragments before reassembly Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 064/109] net: sctp: fix information leaks in ulpevent layer Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 065/109] net: pppoe: use correct channel MTU when using Multilink PPP Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 066/109] bonding: fix ad_select module param check Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 067/109] net-gre-gro: Fix a bug that breaks the forwarding path Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 068/109] sunvnet: clean up objects created in vnet_new() on vnet_exit() Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 069/109] net: ppp: fix creating PPP pass and active filters Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 071/109] net: ppp: dont call sk_chk_filter twice Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 073/109] dns_resolver: Null-terminate the right string Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 074/109] ipv4: fix buffer overflow in ip_options_compile() Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 075/109] xen-netback: Fix handling frag_list on grant op error path Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 076/109] xen-netback: Fix releasing frag_list skbs in " Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 077/109] xen-netback: Fix releasing header slot on " Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 078/109] xen-netback: Fix pointer incrementation to avoid incorrect logging Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 079/109] perf: Do not allow optimized switch for non-cloned events Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 081/109] mwifiex: fix Tx timeout issue Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 082/109] ring-buffer: Fix polling on trace_pipe Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 083/109] irqchip: gic: Add support for cortex a7 compatible string Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 084/109] irqchip: gic: Add binding probe for ARM GIC400 Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 085/109] irqchip: gic: Fix core ID calculation when topology is read from DT Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 086/109] drm/radeon: set default bl level to something reasonable Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 087/109] drm/qxl: return IRQ_NONE if it was not our irq Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 088/109] drm/radeon: avoid leaking edid data Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 089/109] Revert "drm/i915: reverse dp link param selection, prefer fast over wide again" Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 090/109] alarmtimer: Fix bug where relative alarm timers were treated as absolute Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 091/109] hwrng: fetch randomness only after device init Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 092/109] x86, tsc: Fix cpufreq lockup Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 093/109] cpufreq: move policy kobj to policy->cpu at resume Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 094/109] random: check for increase of entropy_count because of signed conversion Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 095/109] mtd: devices: elm: fix elm_context_save() and elm_context_restore() functions Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 096/109] dm thin metadata: do not allow the data block size to change Greg Kroah-Hartman
2014-07-26 19:02 ` [PATCH 3.15 097/109] dm cache " Greg Kroah-Hartman
2014-07-26 19:03 ` [PATCH 3.15 098/109] RDMA/cxgb4: Initialize the device status page Greg Kroah-Hartman
2014-07-26 19:03 ` [PATCH 3.15 099/109] PM / sleep: Fix request_firmware() error at resume Greg Kroah-Hartman
2014-07-26 19:03 ` [PATCH 3.15 100/109] locking/mutex: Disable optimistic spinning on some architectures Greg Kroah-Hartman
2014-07-26 19:03 ` [PATCH 3.15 101/109] sched: Fix possible divide by zero in avg_atom() calculation Greg Kroah-Hartman
2014-07-26 19:03 ` [PATCH 3.15 103/109] IB/mlx5: Enable "block multicast loopback" for kernel consumers Greg Kroah-Hartman
2014-07-26 19:03 ` [PATCH 3.15 104/109] aio: protect reqs_available updates from changes in interrupt handlers Greg Kroah-Hartman
2014-07-26 19:03 ` [PATCH 3.15 105/109] gpio: dwapb: drop irq_setup_generic_chip() Greg Kroah-Hartman
2014-07-26 19:03 ` [PATCH 3.15 106/109] ARM: dts: imx: Add alias for ethernet controller Greg Kroah-Hartman
2014-07-26 19:03 ` [PATCH 3.15 107/109] iwlwifi: mvm: disable CTS to Self Greg Kroah-Hartman
2014-07-26 19:03 ` [PATCH 3.15 108/109] Dont trigger congestion wait on dirty-but-not-writeout pages Greg Kroah-Hartman
2014-07-26 19:03 ` [PATCH 3.15 109/109] ARC: Implement ptrace(PTRACE_GET_THREAD_AREA) Greg Kroah-Hartman
2014-07-27  7:04 ` [PATCH 3.15 000/109] 3.15.7-stable review Satoru Takeuchi
2014-07-27 14:51   ` Greg Kroah-Hartman
2014-07-27 15:01 ` Guenter Roeck
2014-07-27 15:09   ` Greg Kroah-Hartman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140726190224.704741629@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=davej@redhat.com \
    --cc=hughd@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sasha.levin@oracle.com \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox