All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
	alan@lxorguk.ukuu.org.uk,
	Martin Schwidefsky <schwidefsky@de.ibm.com>
Subject: [ 56/75] [S390] fix tlb flushing for page table pages
Date: Thu, 19 Apr 2012 14:03:59 -0700	[thread overview]
Message-ID: <20120419210307.899074250@linuxfoundation.org> (raw)
In-Reply-To: <20120419210322.GA6478@kroah.com>

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

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

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

commit cd94154cc6a28dd9dc271042c1a59c08d26da886 upstream.

Git commit 36409f6353fc2d7b6516e631415f938eadd92ffa "use generic RCU
page-table freeing code" introduced a tlb flushing bug. Partially revert
the above git commit and go back to s390 specific page table flush code.

For s390 the TLB can contain three types of entries, "normal" TLB
page-table entries, TLB combined region-and-segment-table (CRST) entries
and real-space entries. Linux does not use real-space entries which
leaves normal TLB entries and CRST entries. The CRST entries are
intermediate steps in the page-table translation called translation paths.
For example a 4K page access in a three-level page table setup will
create two CRST TLB entries and one page-table TLB entry. The advantage
of that approach is that a page access next to the previous one can reuse
the CRST entries and needs just a single read from memory to create the
page-table TLB entry. The disadvantage is that the TLB flushing rules are
more complicated, before any page-table may be freed the TLB needs to be
flushed.

In short: the generic RCU page-table freeing code is incorrect for the
CRST entries, in particular the check for mm_users < 2 is troublesome.

This is applicable to 3.0+ kernels.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

---
 arch/s390/Kconfig               |    1 
 arch/s390/include/asm/pgalloc.h |    3 -
 arch/s390/include/asm/tlb.h     |   22 -------------
 arch/s390/mm/pgtable.c          |   63 ++++++++++++++++++++++++++++++++++++++--
 4 files changed, 61 insertions(+), 28 deletions(-)

--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -89,7 +89,6 @@ config S390
 	select HAVE_KERNEL_XZ
 	select HAVE_ARCH_MUTEX_CPU_RELAX
 	select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
-	select HAVE_RCU_TABLE_FREE if SMP
 	select ARCH_SAVE_PAGE_KEYS if HIBERNATION
 	select HAVE_MEMBLOCK
 	select HAVE_MEMBLOCK_NODE_MAP
--- a/arch/s390/include/asm/pgalloc.h
+++ b/arch/s390/include/asm/pgalloc.h
@@ -22,10 +22,7 @@ void crst_table_free(struct mm_struct *,
 
 unsigned long *page_table_alloc(struct mm_struct *, unsigned long);
 void page_table_free(struct mm_struct *, unsigned long *);
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 void page_table_free_rcu(struct mmu_gather *, unsigned long *);
-void __tlb_remove_table(void *_table);
-#endif
 
 static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
 {
--- a/arch/s390/include/asm/tlb.h
+++ b/arch/s390/include/asm/tlb.h
@@ -30,14 +30,10 @@
 
 struct mmu_gather {
 	struct mm_struct *mm;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 	struct mmu_table_batch *batch;
-#endif
 	unsigned int fullmm;
-	unsigned int need_flush;
 };
 
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 struct mmu_table_batch {
 	struct rcu_head		rcu;
 	unsigned int		nr;
@@ -49,7 +45,6 @@ struct mmu_table_batch {
 
 extern void tlb_table_flush(struct mmu_gather *tlb);
 extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
-#endif
 
 static inline void tlb_gather_mmu(struct mmu_gather *tlb,
 				  struct mm_struct *mm,
@@ -57,29 +52,20 @@ static inline void tlb_gather_mmu(struct
 {
 	tlb->mm = mm;
 	tlb->fullmm = full_mm_flush;
-	tlb->need_flush = 0;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 	tlb->batch = NULL;
-#endif
 	if (tlb->fullmm)
 		__tlb_flush_mm(mm);
 }
 
 static inline void tlb_flush_mmu(struct mmu_gather *tlb)
 {
-	if (!tlb->need_flush)
-		return;
-	tlb->need_flush = 0;
-	__tlb_flush_mm(tlb->mm);
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 	tlb_table_flush(tlb);
-#endif
 }
 
 static inline void tlb_finish_mmu(struct mmu_gather *tlb,
 				  unsigned long start, unsigned long end)
 {
-	tlb_flush_mmu(tlb);
+	tlb_table_flush(tlb);
 }
 
 /*
@@ -105,10 +91,8 @@ static inline void tlb_remove_page(struc
 static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
 				unsigned long address)
 {
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 	if (!tlb->fullmm)
 		return page_table_free_rcu(tlb, (unsigned long *) pte);
-#endif
 	page_table_free(tlb->mm, (unsigned long *) pte);
 }
 
@@ -125,10 +109,8 @@ static inline void pmd_free_tlb(struct m
 #ifdef __s390x__
 	if (tlb->mm->context.asce_limit <= (1UL << 31))
 		return;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 	if (!tlb->fullmm)
 		return tlb_remove_table(tlb, pmd);
-#endif
 	crst_table_free(tlb->mm, (unsigned long *) pmd);
 #endif
 }
@@ -146,10 +128,8 @@ static inline void pud_free_tlb(struct m
 #ifdef __s390x__
 	if (tlb->mm->context.asce_limit <= (1UL << 42))
 		return;
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
 	if (!tlb->fullmm)
 		return tlb_remove_table(tlb, pud);
-#endif
 	crst_table_free(tlb->mm, (unsigned long *) pud);
 #endif
 }
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -679,8 +679,6 @@ void page_table_free(struct mm_struct *m
 	}
 }
 
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
-
 static void __page_table_free_rcu(void *table, unsigned bit)
 {
 	struct page *page;
@@ -734,7 +732,66 @@ void __tlb_remove_table(void *_table)
 		free_pages((unsigned long) table, ALLOC_ORDER);
 }
 
-#endif
+static void tlb_remove_table_smp_sync(void *arg)
+{
+	/* Simply deliver the interrupt */
+}
+
+static void tlb_remove_table_one(void *table)
+{
+	/*
+	 * This isn't an RCU grace period and hence the page-tables cannot be
+	 * assumed to be actually RCU-freed.
+	 *
+	 * It is however sufficient for software page-table walkers that rely
+	 * on IRQ disabling. See the comment near struct mmu_table_batch.
+	 */
+	smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
+	__tlb_remove_table(table);
+}
+
+static void tlb_remove_table_rcu(struct rcu_head *head)
+{
+	struct mmu_table_batch *batch;
+	int i;
+
+	batch = container_of(head, struct mmu_table_batch, rcu);
+
+	for (i = 0; i < batch->nr; i++)
+		__tlb_remove_table(batch->tables[i]);
+
+	free_page((unsigned long)batch);
+}
+
+void tlb_table_flush(struct mmu_gather *tlb)
+{
+	struct mmu_table_batch **batch = &tlb->batch;
+
+	if (*batch) {
+		__tlb_flush_mm(tlb->mm);
+		call_rcu_sched(&(*batch)->rcu, tlb_remove_table_rcu);
+		*batch = NULL;
+	}
+}
+
+void tlb_remove_table(struct mmu_gather *tlb, void *table)
+{
+	struct mmu_table_batch **batch = &tlb->batch;
+
+	if (*batch == NULL) {
+		*batch = (struct mmu_table_batch *)
+			__get_free_page(GFP_NOWAIT | __GFP_NOWARN);
+		if (*batch == NULL) {
+			__tlb_flush_mm(tlb->mm);
+			tlb_remove_table_one(table);
+			return;
+		}
+		(*batch)->nr = 0;
+	}
+	(*batch)->tables[(*batch)->nr++] = table;
+	if ((*batch)->nr == MAX_TABLE_BATCH)
+		tlb_table_flush(tlb);
+}
 
 /*
  * switch on pgstes for its userspace process (for kvm)



  parent reply	other threads:[~2012-04-19 21:15 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-19 21:03 [ 00/75] 3.3.3-stable review Greg KH
2012-04-19 21:03 ` [ 01/75] Btrfs: fix regression in scrub path resolving Greg KH
2012-04-19 21:03 ` [ 02/75] drm/radeon/kms: fix DVO setup on some r4xx chips Greg KH
2012-04-19 21:03 ` [ 03/75] drm/i915: Removed IVB forced enable of sprite dest key Greg KH
2012-04-19 21:03 ` [ 04/75] drm/i915/ringbuffer: Exclude last 2 cachlines of ring on 845g Greg KH
2012-04-19 21:03 ` [ 05/75] drm/radeon: only add the mm i2c bus if the hw_i2c module param is set Greg KH
2012-04-19 21:03 ` [ 06/75] drm/i915: properly compute dp dithering for user-created modes Greg KH
2012-04-19 21:03 ` [ 07/75] drm/i915: make rc6 module parameter read-only Greg KH
2012-04-19 21:03 ` [ 08/75] rtlwifi: Preallocate USB read buffers and eliminate kalloc in read routine Greg KH
2012-04-19 21:03 ` [ 09/75] rtlwifi: Add missing DMA buffer unmapping for PCI drivers Greg KH
2012-04-19 21:03 ` [ 10/75] ARM: 7379/1: DT: fix atags_to_fdt() second call site Greg KH
2012-04-19 21:03 ` [ 11/75] ARM: 7384/1: ThumbEE: Disable userspace TEEHBR access for !CONFIG_ARM_THUMBEE Greg KH
2012-04-19 21:03 ` [ 12/75] md/raid1,raid10: Fix calculation of vcnt when processing error recovery Greg KH
2012-04-19 21:03 ` [ 13/75] md/bitmap: prevent bitmap_daemon_work running while initialising bitmap Greg KH
2012-04-19 21:03 ` [ 14/75] [PATCH] Bluetooth: uart-ldisc: Fix memory leak Greg KH
2012-04-19 21:03 ` [ 15/75] Bluetooth: hci_ldisc: fix NULL-pointer dereference on tty_close Greg KH
2012-04-19 21:03 ` [ 16/75] Bluetooth: hci_core: fix NULL-pointer dereference at unregister Greg KH
2012-04-19 21:03 ` [ 17/75] Bluetooth: Remove unneeded locking Greg KH
2012-04-19 21:03 ` [ 18/75] Revert "Btrfs: increase the global block reserve estimates" Greg KH
2012-04-19 21:03 ` [ 19/75] ALSA: hda/realtek - Add a fixup entry for Acer Aspire 8940G Greg KH
2012-04-19 21:03 ` [ 20/75] ext4: address scalability issue by removing extent cache statistics Greg KH
2012-04-19 21:03 ` [ 21/75] ia64: fix futex_atomic_cmpxchg_inatomic() Greg KH
2012-04-19 21:03 ` [ 22/75] panic: fix stack dump print on direct call to panic() Greg KH
2012-04-19 21:03 ` [ 23/75] drivers/rtc/rtc-pl031.c: enable clock on all ST variants Greg KH
2012-04-19 21:03 ` [ 24/75] hugetlb: fix race condition in hugetlb_fault() Greg KH
2012-04-19 21:03 ` [ 25/75] staging: iio: hmc5843: Fix crash in probe function Greg KH
2012-04-19 21:03 ` [ 26/75] Revert "serial/8250_pci: init-quirk msi support for kt serial controller" Greg KH
2012-04-19 21:03 ` [ 27/75] serial: samsung: fix omission initialize ulcon in reset port fn() Greg KH
2012-04-19 21:03 ` [ 28/75] Revert "serial/8250_pci: setup-quirk workaround for the kt serial controller" Greg KH
2012-04-19 21:03 ` [ 29/75] serial/8250_pci: add a "force background timer" flag and use it for the "kt" serial port Greg KH
2012-04-19 21:03 ` [ 30/75] tty: serial: altera_uart: Check for NULL platform_data in probe Greg KH
2012-04-19 21:03 ` [ 31/75] sparc64: Eliminate obsolete __handle_softirq() function Greg KH
2012-04-19 21:03 ` [ 32/75] sparc64: Fix bootup crash on sun4v Greg KH
2012-04-19 21:03 ` [ 33/75] cciss: Initialize scsi host max_sectors for tape drive support Greg KH
2012-04-19 21:03 ` [ 34/75] cciss: Fix scsi tape io with more than 255 scatter gather elements Greg KH
2012-04-19 21:03 ` [ 35/75] perf hists: Catch and handle out-of-date hist entry maps Greg KH
2012-04-19 21:03 ` [ 36/75] video:uvesafb: Fix oops that uvesafb try to execute NX-protected page Greg KH
2012-04-19 21:03 ` [ 37/75] IB/srpt: Set srq_type to IB_SRQT_BASIC Greg KH
2012-04-19 21:03 ` [ 38/75] nohz: Fix stale jiffies update in tick_nohz_restart() Greg KH
2012-04-19 21:03 ` [ 39/75] pch_uart: Fix MSI setting issue Greg KH
2012-04-19 21:03 ` [ 40/75] x86: Use correct byte-sized register constraint in __xchg_op() Greg KH
2012-04-19 21:03 ` [ 41/75] x86: Use correct byte-sized register constraint in __add() Greg KH
2012-04-19 21:03 ` [ 42/75] USB: serial: fix race between probe and open Greg KH
2012-04-19 21:03 ` [ 43/75] USB: pl2303: fix DTR/RTS being raised on baud rate change Greg KH
2012-04-19 21:03 ` [ 44/75] USB: option: re-add NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED to option_id array Greg KH
2012-04-19 21:03 ` [ 45/75] USB: ftdi_sio: fix status line change handling for TIOCMIWAIT and TIOCGICOUNT Greg KH
2012-04-19 21:03 ` [ 46/75] USB: ftdi_sio: fix race condition in TIOCMIWAIT, and abort of TIOCMIWAIT when the device is removed Greg KH
2012-04-19 21:03 ` [ 47/75] USB: sierra: add support for Sierra Wireless MC7710 Greg KH
2012-04-19 21:03 ` [ 48/75] USB: dont clear urb->dev in scatter-gather library Greg KH
2012-04-19 21:03 ` [ 49/75] USB: dont ignore suspend errors for root hubs Greg KH
2012-04-19 21:03 ` [ 50/75] xhci: dont re-enable IE constantly Greg KH
2012-04-19 21:03 ` [ 51/75] xhci: Dont write zeroed pointers to xHC registers Greg KH
2012-04-19 21:03 ` [ 52/75] xhci: Restore event ring dequeue pointer on resume Greg KH
2012-04-19 21:03 ` [ 53/75] USB: fix bug of device descriptor got from superspeed device Greg KH
2012-04-19 21:03 ` [ 54/75] xHCI: add XHCI_RESET_ON_RESUME quirk for VIA xHCI host Greg KH
2012-04-19 21:03 ` [ 55/75] xHCI: Correct the #define XHCI_LEGACY_DISABLE_SMI Greg KH
2012-04-19 21:03 ` Greg KH [this message]
2012-04-19 21:04 ` [ 57/75] memcg: fix Bad page state after replace_page_cache Greg KH
2012-04-19 21:04 ` [ 58/75] serial: PL011: clear pending interrupts Greg KH
2012-04-19 21:04 ` [ 59/75] serial: PL011: move interrupt clearing Greg KH
2012-04-19 21:04 ` [ 60/75] fcaps: clear the same personality flags as suid when fcaps are used Greg KH
2012-04-19 21:04 ` [ 61/75] xhci: Fix register save/restore order Greg KH
2012-04-19 21:04 ` [ 62/75] usb: gadget: pch_udc: Fix disconnect issue Greg KH
2012-04-19 21:04 ` [ 63/75] usb: gadget: pch_udc: Fix wrong return value Greg KH
2012-04-19 21:04 ` [ 64/75] usb: gadget: pch_udc: Fix USB suspend issue Greg KH
2012-04-19 21:04 ` [ 65/75] usb: gadget: pch_udc: Fix usb/gadget/pch_udc: Fix ether gadget connect/disconnect issue Greg KH
2012-04-19 21:04 ` [ 66/75] usb: gadget: pch_udc: Reduce redundant interrupt Greg KH
2012-04-19 21:04 ` [ 67/75] security: fix compile error in commoncap.c Greg KH
2012-04-19 21:04 ` [ 68/75] spi-topcliff-pch: fix -Wuninitialized warning Greg KH
2012-04-19 21:04 ` [ 69/75] Bluetooth: Adding USB device 13d3:3375 as an Atheros AR3012 Greg KH
2012-04-19 21:04 ` [ 70/75] Bluetooth: Add Atheros maryann PIDVID support Greg KH
2012-04-19 21:04 ` [ 71/75] futex: Do not leak robust list to unprivileged process Greg KH
2012-04-19 21:04 ` [ 72/75] drm/i915: Hold mode_config lock whilst changing mode for lastclose() Greg KH
2012-04-19 21:04 ` [ 73/75] drm/radeon/kms: fix the regression of DVI connector check Greg KH
2012-04-19 21:04 ` [ 74/75] drm/radeon: disable MSI on RV515 Greg KH
2012-04-19 21:04 ` [ 75/75] drm/radeon: fix load detect on rn50 with hardcoded EDIDs Greg KH

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=20120419210307.899074250@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=schwidefsky@de.ibm.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.