+ revert-mm-msync-cleanup.patch added to -mm tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled

     revert mm-msync-cleanup

has been added to the -mm tree.  Its filename is

     revert-mm-msync-cleanup.patch

See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find
out what to do about this

------------------------------------------------------
Subject: revert mm-msync-cleanup
From: Andrew Morton <akpm@xxxxxxxx>

It broke msync.  (Thanks Arjan for diagnosing..)

Cc: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
Cc: Hugh Dickins <hugh@xxxxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxx>
---

 mm/msync.c |  194 ++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 163 insertions(+), 31 deletions(-)

diff -puN mm/msync.c~revert-mm-msync-cleanup mm/msync.c
--- a/mm/msync.c~revert-mm-msync-cleanup
+++ a/mm/msync.c
@@ -7,33 +7,149 @@
 /*
  * The msync() system call.
  */
+#include <linux/slab.h>
+#include <linux/pagemap.h>
 #include <linux/fs.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
+#include <linux/hugetlb.h>
+#include <linux/writeback.h>
 #include <linux/file.h>
 #include <linux/syscalls.h>
 
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+static unsigned long msync_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
+				unsigned long addr, unsigned long end)
+{
+	pte_t *pte;
+	spinlock_t *ptl;
+	int progress = 0;
+	unsigned long ret = 0;
+
+again:
+	pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
+	do {
+		struct page *page;
+
+		if (progress >= 64) {
+			progress = 0;
+			if (need_resched() || need_lockbreak(ptl))
+				break;
+		}
+		progress++;
+		if (!pte_present(*pte))
+			continue;
+		if (!pte_maybe_dirty(*pte))
+			continue;
+		page = vm_normal_page(vma, addr, *pte);
+		if (!page)
+			continue;
+		if (ptep_clear_flush_dirty(vma, addr, pte) ||
+				page_test_and_clear_dirty(page))
+			ret += set_page_dirty(page);
+		progress += 3;
+	} while (pte++, addr += PAGE_SIZE, addr != end);
+	pte_unmap_unlock(pte - 1, ptl);
+	cond_resched();
+	if (addr != end)
+		goto again;
+	return ret;
+}
+
+static inline unsigned long msync_pmd_range(struct vm_area_struct *vma,
+			pud_t *pud, unsigned long addr, unsigned long end)
+{
+	pmd_t *pmd;
+	unsigned long next;
+	unsigned long ret = 0;
+
+	pmd = pmd_offset(pud, addr);
+	do {
+		next = pmd_addr_end(addr, end);
+		if (pmd_none_or_clear_bad(pmd))
+			continue;
+		ret += msync_pte_range(vma, pmd, addr, next);
+	} while (pmd++, addr = next, addr != end);
+	return ret;
+}
+
+static inline unsigned long msync_pud_range(struct vm_area_struct *vma,
+			pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+	pud_t *pud;
+	unsigned long next;
+	unsigned long ret = 0;
+
+	pud = pud_offset(pgd, addr);
+	do {
+		next = pud_addr_end(addr, end);
+		if (pud_none_or_clear_bad(pud))
+			continue;
+		ret += msync_pmd_range(vma, pud, addr, next);
+	} while (pud++, addr = next, addr != end);
+	return ret;
+}
+
+static unsigned long msync_page_range(struct vm_area_struct *vma,
+				unsigned long addr, unsigned long end)
+{
+	pgd_t *pgd;
+	unsigned long next;
+	unsigned long ret = 0;
+
+	/* For hugepages we can't go walking the page table normally,
+	 * but that's ok, hugetlbfs is memory based, so we don't need
+	 * to do anything more on an msync().
+	 */
+	if (vma->vm_flags & VM_HUGETLB)
+		return 0;
+
+	BUG_ON(addr >= end);
+	pgd = pgd_offset(vma->vm_mm, addr);
+	flush_cache_range(vma, addr, end);
+	do {
+		next = pgd_addr_end(addr, end);
+		if (pgd_none_or_clear_bad(pgd))
+			continue;
+		ret += msync_pud_range(vma, pgd, addr, next);
+	} while (pgd++, addr = next, addr != end);
+	return ret;
+}
+
 /*
  * MS_SYNC syncs the entire file - including mappings.
  *
- * MS_ASYNC does not start I/O (it used to, up to 2.5.67).
- * Nor does it marks the relevant pages dirty (it used to up to 2.6.17).
- * Now it doesn't do anything, since dirty pages are properly tracked.
- *
- * The application may now run fsync() to
+ * MS_ASYNC does not start I/O (it used to, up to 2.5.67).  Instead, it just
+ * marks the relevant pages dirty.  The application may now run fsync() to
  * write out the dirty pages and wait on the writeout and check the result.
  * Or the application may run fadvise(FADV_DONTNEED) against the fd to start
  * async writeout immediately.
  * So by _not_ starting I/O in MS_ASYNC we provide complete flexibility to
  * applications.
  */
+static int msync_interval(struct vm_area_struct *vma, unsigned long addr,
+			unsigned long end, int flags,
+			unsigned long *nr_pages_dirtied)
+{
+	struct file *file = vma->vm_file;
+
+	if ((flags & MS_INVALIDATE) && (vma->vm_flags & VM_LOCKED))
+		return -EBUSY;
+
+	if (file && (vma->vm_flags & VM_SHARED))
+		*nr_pages_dirtied = msync_page_range(vma, addr, end);
+	return 0;
+}
+
 asmlinkage long sys_msync(unsigned long start, size_t len, int flags)
 {
 	unsigned long end;
-	struct mm_struct *mm = current->mm;
 	struct vm_area_struct *vma;
 	int unmapped_error = 0;
 	int error = -EINVAL;
+	int done = 0;
 
 	if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC))
 		goto out;
@@ -53,48 +169,64 @@ asmlinkage long sys_msync(unsigned long 
 	 * If the interval [start,end) covers some unmapped address ranges,
 	 * just ignore them, but return -ENOMEM at the end.
 	 */
-	down_read(&mm->mmap_sem);
-	vma = find_vma(mm, start);
-	for (;;) {
+	down_read(&current->mm->mmap_sem);
+	vma = find_vma(current->mm, start);
+	if (!vma) {
+		error = -ENOMEM;
+		goto out_unlock;
+	}
+	do {
+		unsigned long nr_pages_dirtied = 0;
 		struct file *file;
 
-		/* Still start < end. */
-		error = -ENOMEM;
-		if (!vma)
-			goto out_unlock;
 		/* Here start < vma->vm_end. */
 		if (start < vma->vm_start) {
-			start = vma->vm_start;
-			if (start >= end)
-				goto out_unlock;
 			unmapped_error = -ENOMEM;
+			start = vma->vm_start;
 		}
 		/* Here vma->vm_start <= start < vma->vm_end. */
-		if ((flags & MS_INVALIDATE) &&
-				(vma->vm_flags & VM_LOCKED)) {
-			error = -EBUSY;
-			goto out_unlock;
+		if (end <= vma->vm_end) {
+			if (start < end) {
+				error = msync_interval(vma, start, end, flags,
+							&nr_pages_dirtied);
+				if (error)
+					goto out_unlock;
+			}
+			error = unmapped_error;
+			done = 1;
+		} else {
+			/* Here vma->vm_start <= start < vma->vm_end < end. */
+			error = msync_interval(vma, start, vma->vm_end, flags,
+						&nr_pages_dirtied);
+			if (error)
+				goto out_unlock;
 		}
 		file = vma->vm_file;
 		start = vma->vm_end;
-		if ((flags & MS_SYNC) && file &&
+		if ((flags & MS_ASYNC) && file && nr_pages_dirtied) {
+			get_file(file);
+			up_read(&current->mm->mmap_sem);
+			balance_dirty_pages_ratelimited_nr(file->f_mapping,
+							nr_pages_dirtied);
+			fput(file);
+			down_read(&current->mm->mmap_sem);
+			vma = find_vma(current->mm, start);
+		} else if ((flags & MS_SYNC) && file &&
 				(vma->vm_flags & VM_SHARED)) {
 			get_file(file);
-			up_read(&mm->mmap_sem);
+			up_read(&current->mm->mmap_sem);
 			error = do_fsync(file, 0);
 			fput(file);
-			if (error || start >= end)
-				goto out;
-			down_read(&mm->mmap_sem);
-			vma = find_vma(mm, start);
-		} else {
-			if (start >= end)
+			down_read(&current->mm->mmap_sem);
+			if (error)
 				goto out_unlock;
+			vma = find_vma(current->mm, start);
+		} else {
 			vma = vma->vm_next;
 		}
-	}
+	} while (vma && !done);
 out_unlock:
-	up_read(&mm->mmap_sem);
+	up_read(&current->mm->mmap_sem);
 out:
-	return error ? : unmapped_error;
+	return error;
 }
_

Patches currently in -mm which might be from akpm@xxxxxxxx are

origin.patch
msrc-use-register_hotcpu_notifier.patch
disable-debugging-version-of-write_lock.patch
git-acpi.patch
git-acpi-fixup.patch
acpi_srat-needs-acpi.patch
acpi-asus-s3-resume-fix-fix.patch
sony_apci-resume.patch
git-agpgart.patch
git-agpgart-fixup.patch
kauditd_thread-warning-fix.patch
git-dvb.patch
i2c-801-64bit-resource-fix.patch
git-geode-fixup.patch
git-gfs2.patch
git-gfs2-fixup.patch
gfs2-get_sb_dev-fix.patch
git-ia64-fixup.patch
genirq-rename-desc-handler-to-desc-chip-ia64-fix-2.patch
revert-input-atkbd-fix-hangeul-hanja-keys.patch
revert-ignore-makes-built-in-rules-variables.patch
revert-sparc-build-breakage.patch
git-klibc.patch
git-klibc-fixup.patch
git-hdrcleanup-vs-git-klibc-on-ia64.patch
git-hdrcleanup-vs-git-klibc-on-ia64-2.patch
git-libata-all.patch
sata-is-bust-on-s390.patch
forcedeth-typecast-cleanup.patch
drivers-net-ns83820c-add-paramter-to-disable-auto.patch
af_unix-datagram-getpeersec-fix.patch
git-pcmcia-fixup.patch
git-sas.patch
serial-8250-sysrq-deadlock-fix.patch
serial-fix-uart_bug_txen-test.patch
revert-gregkh-pci-pci-test-that-drivers-properly-call-pci_set_master.patch
clear-abnormal-poweroff-flag-on-via-southbridges-fix-resume-fix.patch
revert-VIA-quirk-fixup-additional-PCI-IDs.patch
revert-PCI-quirk-VIA-IRQ-fixup-should-only-run-for-VIA-southbridges.patch
git-scsi-misc.patch
areca-raid-linux-scsi-driver.patch
git-scsi-target-fixup.patch
pm-usb-hcds-use-pm_event_prethaw-fix.patch
git-supertrak-fixup.patch
bcm43xx-opencoded-locking-fix.patch
adix-tree-rcu-lockless-readside-update-tidy.patch
zoned-vm-counters-create-vmstatc-h-from-page_allocc-h-s390-fix.patch
zoned-vm-counters-create-vmstatc-h-from-page_allocc-h-fix.patch
zoned-vm-counters-basic-zvc-zoned-vm-counter-implementation-tidy.patch
zoned-vm-counters-basic-zvc-zoned-vm-counter-implementation-export-vm_stat.patch
zoned-vm-counters-convert-nr_mapped-to-per-zone-counter-fix.patch
zoned-vm-counters-remove-nr_file_mapped-from-scan-control-structure-fix.patch
zoned-vm-counters-conversion-of-nr_slab-to-per-zone-counter-fix.patch
zoned-vm-counters-conversion-of-nr_pagetables-to-per-zone-counter-fix.patch
zoned-vm-counters-conversion-of-nr_dirty-to-per-zone-counter-fix.patch
zoned-vm-counters-conversion-of-nr_writeback-to-per-zone-counter.patch
zoned-vm-counters-conversion-of-nr_writeback-to-per-zone-counter-fix.patch
zoned-vm-counters-conversion-of-nr_unstable-to-per-zone-counter-nfs-fix.patch
zoned-vm-counters-conversion-of-nr_unstable-to-per-zone-counter-fix.patch
zoned-vm-counters-conversion-of-nr_bounce-to-per-zone-counter.patch
zoned-vm-counters-conversion-of-nr_bounce-to-per-zone-counter-fix.patch
zoned-vm-counters-remove-read_page_state.patch
mm-tracking-shared-dirty-pages-checks.patch
mm-tracking-shared-dirty-pages-wimp.patch
slab-consolidate-code-to-free-slabs-from-freelist-fix.patch
acx1xx-wireless-driver.patch
tiacx-pci-build-fix.patch
tiacx-ia64-fix.patch
add-smp_setup_processor_id.patch
deprecate-smbfs-in-favour-of-cifs.patch
destroy-the-dentries-contributed-by-a-superblock-on-unmounting-fix.patch
cond_resched-fix.patch
reiserfs-on-demand-bitmap-loading-fix.patch
per-task-delay-accounting-proc-export-of-aggregated-block-i-o-delays-warning-fix.patch
delay-accounting-taskstats-interface-send-tgid-once-fixes.patch
sched-clean-up-fallout-of-recent-changes-fix.patch
swap_prefetch-vs-zoned-counters.patch
mark-address_space_operations-const-vs-ecryptfs-mmap-operations.patch
ecryptfs-alpha-build-fix.patch
ecryptfs-more-elegant-aes-key-size-manipulation-tidy.patch
ecryptfs-get_sb_dev-fix.patch
namespaces-add-nsproxy-dont-include-compileh.patch
namespaces-utsname-switch-to-using-uts-namespaces-alpha-fix.patch
namespaces-utsname-use-init_utsname-when-appropriate-cifs-update.patch
namespaces-utsname-implement-utsname-namespaces-export.patch
namespaces-utsname-implement-utsname-namespaces-dont-include-compileh.patch
namespaces-utsname-sysctl-hack-cleanup-2-fix.patch
ipc-namespace-core-fix.patch
task-watchers-task-watchers-tidy.patch
task-watchers-add-support-for-per-task-watchers-warning-fix.patch
readahead-sysctl-parameters-fix.patch
make-copy_from_user_inatomic-not-zero-the-tail-on-i386-vs-reiser4.patch
reiser4-hardirq-include-fix.patch
reiser4-run-truncate_inode_pages-in-reiser4_delete_inode.patch
reiser4-get_sb_dev-fix.patch
reiser4-vs-zoned-allocator.patch
hpt3xx-rework-rate-filtering-tidy.patch
lockdep-add-disable-enable_irq_lockdep-api.patch
lockdep-irqtrace-subsystem-x86_64-support.patch
genirq-convert-the-i386-architecture-to-irq-chips-fix-2.patch
genirq-msi-simplify-msi-enable-and-disable-fix.patch
genirq-i386-irq-remove-the-msi-assumption-that-irq-==-vector-fix-tidies.patch
srcu-rcu-variant-permitting-read-side-blocking-fixes.patch
srcu-add-srcu-operations-to-rcutorture-fix.patch
srcu-2-add-srcu-operations-to-rcutorture-fix.patch
nr_blockdev_pages-in_interrupt-warning.patch
device-suspend-debug.patch
revert-tty-buffering-comment-out-debug-code.patch
slab-leaks3-default-y.patch
x86-kmap_atomic-debugging.patch
revert-mm-msync-cleanup.patch

-
To unsubscribe from this list: send the line "unsubscribe mm-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Kernel Newbies FAQ]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Photo]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux