All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Fitzhardinge <jeremy@goop.org>
To: Andi Kleen <ak@suse.de>
Cc: virtualization@lists.osdl.org,
	Andrew Morton <akpm@linux-foundation.org>,
	lkml <linux-kernel@vger.kernel.org>
Subject: [patch 15/20] add flush_tlb_others paravirt_op
Date: Wed, 04 Apr 2007 12:12:06 -0700	[thread overview]
Message-ID: <20070404191206.181792507@goop.org> (raw)
In-Reply-To: 20070404191151.009821039@goop.org

[-- Attachment #1: paravirt-flush_tlb_others.patch --]
[-- Type: text/plain, Size: 5276 bytes --]

This patch adds a pv_op for flush_tlb_others.  Linux running on native
hardware uses cross-CPU IPIs to flush the TLB on any CPU which may
have a particular mm's pagetable entries cached in its TLB.  This is
inefficient in a paravirtualized environment, since the hypervisor
knows which real CPUs actually contain cached mappings, which may be a
small subset of a guest's VCPUs.

Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>

---
 arch/i386/kernel/paravirt.c |    1 +
 arch/i386/kernel/smp.c      |   15 ++++++++-------
 include/asm-i386/paravirt.h |    9 +++++++++
 include/asm-i386/tlbflush.h |   19 +++++++++++++++++--
 4 files changed, 35 insertions(+), 9 deletions(-)

===================================================================
--- a/arch/i386/kernel/paravirt.c
+++ b/arch/i386/kernel/paravirt.c
@@ -301,6 +301,7 @@ struct paravirt_ops paravirt_ops = {
 	.flush_tlb_user = native_flush_tlb,
 	.flush_tlb_kernel = native_flush_tlb_global,
 	.flush_tlb_single = native_flush_tlb_single,
+	.flush_tlb_others = native_flush_tlb_others,
 
 	.map_pt_hook = paravirt_nop,
 
===================================================================
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -256,7 +256,6 @@ static struct mm_struct * flush_mm;
 static struct mm_struct * flush_mm;
 static unsigned long flush_va;
 static DEFINE_SPINLOCK(tlbstate_lock);
-#define FLUSH_ALL	0xffffffff
 
 /*
  * We cannot call mmdrop() because we are in interrupt context, 
@@ -338,7 +337,7 @@ fastcall void smp_invalidate_interrupt(s
 		 
 	if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) {
 		if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) {
-			if (flush_va == FLUSH_ALL)
+			if (flush_va == TLB_FLUSH_ALL)
 				local_flush_tlb();
 			else
 				__flush_tlb_one(flush_va);
@@ -353,9 +352,11 @@ out:
 	put_cpu_no_resched();
 }
 
-static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
-						unsigned long va)
-{
+void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
+			     unsigned long va)
+{
+	cpumask_t cpumask = *cpumaskp;
+
 	/*
 	 * A couple of (to be removed) sanity checks:
 	 *
@@ -417,7 +418,7 @@ void flush_tlb_current_task(void)
 
 	local_flush_tlb();
 	if (!cpus_empty(cpu_mask))
-		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+		flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
 	preempt_enable();
 }
 
@@ -436,7 +437,7 @@ void flush_tlb_mm (struct mm_struct * mm
 			leave_mm(smp_processor_id());
 	}
 	if (!cpus_empty(cpu_mask))
-		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+		flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
 
 	preempt_enable();
 }
===================================================================
--- a/include/asm-i386/paravirt.h
+++ b/include/asm-i386/paravirt.h
@@ -15,6 +15,7 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
+#include <linux/cpumask.h>
 
 struct thread_struct;
 struct Xgt_desc_struct;
@@ -125,6 +126,8 @@ struct paravirt_ops
 	void (*flush_tlb_user)(void);
 	void (*flush_tlb_kernel)(void);
 	void (*flush_tlb_single)(unsigned long addr);
+	void (*flush_tlb_others)(const cpumask_t *cpus, struct mm_struct *mm,
+				 unsigned long va);
 
 	void (*map_pt_hook)(int type, pte_t *va, u32 pfn);
 
@@ -731,6 +734,12 @@ static inline void __flush_tlb_single(un
 	PVOP_VCALL1(flush_tlb_single, addr);
 }
 
+static inline void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
+				    unsigned long va)
+{
+	PVOP_VCALL3(flush_tlb_others, &cpumask, mm, va);
+}
+
 static inline void paravirt_map_pt_hook(int type, pte_t *va, u32 pfn)
 {
 	PVOP_VCALL3(map_pt_hook, type, va, pfn);
===================================================================
--- a/include/asm-i386/tlbflush.h
+++ b/include/asm-i386/tlbflush.h
@@ -79,10 +79,14 @@
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
+ *  - flush_tlb_others(cpumask, mm, va) flushes a TLBs on other cpus
  *
  * ..but the i386 has somewhat limited tlb flushing capabilities,
  * and page-granular flushes are available only on i486 and up.
  */
+
+#define TLB_FLUSH_ALL	0xffffffff
+
 
 #ifndef CONFIG_SMP
 
@@ -110,7 +114,12 @@ static inline void flush_tlb_range(struc
 		__flush_tlb();
 }
 
-#else
+static inline void native_flush_tlb_others(const cpumask_t *cpumask,
+					   struct mm_struct *mm, unsigned long va)
+{
+}
+
+#else  /* SMP */
 
 #include <asm/smp.h>
 
@@ -129,6 +138,9 @@ static inline void flush_tlb_range(struc
 	flush_tlb_mm(vma->vm_mm);
 }
 
+void native_flush_tlb_others(const cpumask_t *cpumask, struct mm_struct *mm,
+			     unsigned long va);
+
 #define TLBSTATE_OK	1
 #define TLBSTATE_LAZY	2
 
@@ -139,8 +151,11 @@ struct tlb_state
 	char __cacheline_padding[L1_CACHE_BYTES-8];
 };
 DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate);
+#endif	/* SMP */
 
-
+#ifndef CONFIG_PARAVIRT
+#define flush_tlb_others(mask, mm, va)		\
+	native_flush_tlb_others(&mask, mm, va)
 #endif
 
 #define flush_tlb_kernel_range(start, end) flush_tlb_all()

-- 

WARNING: multiple messages have this Message-ID (diff)
From: Jeremy Fitzhardinge <jeremy@goop.org>
To: Andi Kleen <ak@suse.de>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	virtualization@lists.osdl.org,
	lkml <linux-kernel@vger.kernel.org>
Subject: [patch 15/20] add flush_tlb_others paravirt_op
Date: Wed, 04 Apr 2007 12:12:06 -0700	[thread overview]
Message-ID: <20070404191206.181792507@goop.org> (raw)
In-Reply-To: 20070404191151.009821039@goop.org

[-- Attachment #1: paravirt-flush_tlb_others.patch --]
[-- Type: text/plain, Size: 5109 bytes --]

This patch adds a pv_op for flush_tlb_others.  Linux running on native
hardware uses cross-CPU IPIs to flush the TLB on any CPU which may
have a particular mm's pagetable entries cached in its TLB.  This is
inefficient in a paravirtualized environment, since the hypervisor
knows which real CPUs actually contain cached mappings, which may be a
small subset of a guest's VCPUs.

Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>

---
 arch/i386/kernel/paravirt.c |    1 +
 arch/i386/kernel/smp.c      |   15 ++++++++-------
 include/asm-i386/paravirt.h |    9 +++++++++
 include/asm-i386/tlbflush.h |   19 +++++++++++++++++--
 4 files changed, 35 insertions(+), 9 deletions(-)

===================================================================
--- a/arch/i386/kernel/paravirt.c
+++ b/arch/i386/kernel/paravirt.c
@@ -301,6 +301,7 @@ struct paravirt_ops paravirt_ops = {
 	.flush_tlb_user = native_flush_tlb,
 	.flush_tlb_kernel = native_flush_tlb_global,
 	.flush_tlb_single = native_flush_tlb_single,
+	.flush_tlb_others = native_flush_tlb_others,
 
 	.map_pt_hook = paravirt_nop,
 
===================================================================
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -256,7 +256,6 @@ static struct mm_struct * flush_mm;
 static struct mm_struct * flush_mm;
 static unsigned long flush_va;
 static DEFINE_SPINLOCK(tlbstate_lock);
-#define FLUSH_ALL	0xffffffff
 
 /*
  * We cannot call mmdrop() because we are in interrupt context, 
@@ -338,7 +337,7 @@ fastcall void smp_invalidate_interrupt(s
 		 
 	if (flush_mm == per_cpu(cpu_tlbstate, cpu).active_mm) {
 		if (per_cpu(cpu_tlbstate, cpu).state == TLBSTATE_OK) {
-			if (flush_va == FLUSH_ALL)
+			if (flush_va == TLB_FLUSH_ALL)
 				local_flush_tlb();
 			else
 				__flush_tlb_one(flush_va);
@@ -353,9 +352,11 @@ out:
 	put_cpu_no_resched();
 }
 
-static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
-						unsigned long va)
-{
+void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
+			     unsigned long va)
+{
+	cpumask_t cpumask = *cpumaskp;
+
 	/*
 	 * A couple of (to be removed) sanity checks:
 	 *
@@ -417,7 +418,7 @@ void flush_tlb_current_task(void)
 
 	local_flush_tlb();
 	if (!cpus_empty(cpu_mask))
-		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+		flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
 	preempt_enable();
 }
 
@@ -436,7 +437,7 @@ void flush_tlb_mm (struct mm_struct * mm
 			leave_mm(smp_processor_id());
 	}
 	if (!cpus_empty(cpu_mask))
-		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+		flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
 
 	preempt_enable();
 }
===================================================================
--- a/include/asm-i386/paravirt.h
+++ b/include/asm-i386/paravirt.h
@@ -15,6 +15,7 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/types.h>
+#include <linux/cpumask.h>
 
 struct thread_struct;
 struct Xgt_desc_struct;
@@ -125,6 +126,8 @@ struct paravirt_ops
 	void (*flush_tlb_user)(void);
 	void (*flush_tlb_kernel)(void);
 	void (*flush_tlb_single)(unsigned long addr);
+	void (*flush_tlb_others)(const cpumask_t *cpus, struct mm_struct *mm,
+				 unsigned long va);
 
 	void (*map_pt_hook)(int type, pte_t *va, u32 pfn);
 
@@ -731,6 +734,12 @@ static inline void __flush_tlb_single(un
 	PVOP_VCALL1(flush_tlb_single, addr);
 }
 
+static inline void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
+				    unsigned long va)
+{
+	PVOP_VCALL3(flush_tlb_others, &cpumask, mm, va);
+}
+
 static inline void paravirt_map_pt_hook(int type, pte_t *va, u32 pfn)
 {
 	PVOP_VCALL3(map_pt_hook, type, va, pfn);
===================================================================
--- a/include/asm-i386/tlbflush.h
+++ b/include/asm-i386/tlbflush.h
@@ -79,10 +79,14 @@
  *  - flush_tlb_range(vma, start, end) flushes a range of pages
  *  - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
  *  - flush_tlb_pgtables(mm, start, end) flushes a range of page tables
+ *  - flush_tlb_others(cpumask, mm, va) flushes a TLBs on other cpus
  *
  * ..but the i386 has somewhat limited tlb flushing capabilities,
  * and page-granular flushes are available only on i486 and up.
  */
+
+#define TLB_FLUSH_ALL	0xffffffff
+
 
 #ifndef CONFIG_SMP
 
@@ -110,7 +114,12 @@ static inline void flush_tlb_range(struc
 		__flush_tlb();
 }
 
-#else
+static inline void native_flush_tlb_others(const cpumask_t *cpumask,
+					   struct mm_struct *mm, unsigned long va)
+{
+}
+
+#else  /* SMP */
 
 #include <asm/smp.h>
 
@@ -129,6 +138,9 @@ static inline void flush_tlb_range(struc
 	flush_tlb_mm(vma->vm_mm);
 }
 
+void native_flush_tlb_others(const cpumask_t *cpumask, struct mm_struct *mm,
+			     unsigned long va);
+
 #define TLBSTATE_OK	1
 #define TLBSTATE_LAZY	2
 
@@ -139,8 +151,11 @@ struct tlb_state
 	char __cacheline_padding[L1_CACHE_BYTES-8];
 };
 DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate);
+#endif	/* SMP */
 
-
+#ifndef CONFIG_PARAVIRT
+#define flush_tlb_others(mask, mm, va)		\
+	native_flush_tlb_others(&mask, mm, va)
 #endif
 
 #define flush_tlb_kernel_range(start, end) flush_tlb_all()

-- 


  parent reply	other threads:[~2007-04-04 19:12 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-04 19:11 [patch 00/20] paravirt_ops updates Jeremy Fitzhardinge
2007-04-04 19:11 ` Jeremy Fitzhardinge
2007-04-04 19:11 ` [patch 01/20] update MAINTAINERS Jeremy Fitzhardinge
2007-04-04 19:11   ` Jeremy Fitzhardinge
2007-04-04 19:11 ` [patch 02/20] Remove CONFIG_DEBUG_PARAVIRT Jeremy Fitzhardinge
2007-04-04 19:11   ` Jeremy Fitzhardinge
2007-04-04 19:11 ` [patch 03/20] use paravirt_nop to consistently mark no-op operations Jeremy Fitzhardinge
2007-04-04 19:11   ` Jeremy Fitzhardinge
2007-04-04 19:11 ` [patch 04/20] Add pagetable accessors to pack and unpack pagetable entries Jeremy Fitzhardinge
2007-04-04 19:11   ` Jeremy Fitzhardinge
2007-04-04 19:11 ` [patch 05/20] Hooks to set up initial pagetable Jeremy Fitzhardinge
2007-04-04 19:11   ` Jeremy Fitzhardinge
2007-04-04 19:11 ` [patch 06/20] Allocate a fixmap slot Jeremy Fitzhardinge
2007-04-04 19:11   ` Jeremy Fitzhardinge
2007-04-04 19:11 ` [patch 07/20] Allow paravirt backend to choose kernel PMD sharing Jeremy Fitzhardinge
2007-04-04 19:11   ` Jeremy Fitzhardinge
2007-04-05  0:30   ` Christoph Lameter
2007-04-05  0:43     ` Jeremy Fitzhardinge
2007-04-05  1:29     ` Chris Wright
2007-04-06 23:41   ` Andrew Morton
2007-04-06 23:41     ` Andrew Morton
2007-04-07  0:02     ` Jeremy Fitzhardinge
2007-04-07  0:02       ` Jeremy Fitzhardinge
2007-04-07  0:28       ` Andrew Morton
2007-04-07  0:40         ` Jeremy Fitzhardinge
2007-04-07  0:40           ` Jeremy Fitzhardinge
2007-04-07  1:21           ` Andrew Morton
2007-04-07  5:47             ` Jeremy Fitzhardinge
2007-04-09  2:36         ` William Lee Irwin III
2007-04-04 19:11 ` [patch 08/20] add hooks to intercept mm creation and destruction Jeremy Fitzhardinge
2007-04-04 19:11   ` Jeremy Fitzhardinge
2007-04-04 19:12 ` [patch 09/20] rename struct paravirt_patch to paravirt_patch_site for clarity Jeremy Fitzhardinge
2007-04-04 19:12   ` Jeremy Fitzhardinge
2007-04-06 23:18   ` Andrew Morton
2007-04-06 23:18     ` Andrew Morton
2007-04-06 23:24     ` Jeremy Fitzhardinge
2007-04-04 19:12 ` [patch 10/20] Use patch site IDs computed from offset in paravirt_ops structure Jeremy Fitzhardinge
2007-04-04 19:12   ` Jeremy Fitzhardinge
2007-04-04 19:12 ` [patch 11/20] Fix patch site clobbers to include return register Jeremy Fitzhardinge
2007-04-04 19:12   ` Jeremy Fitzhardinge
2007-04-04 19:12 ` [patch 12/20] Consistently wrap paravirt ops callsites to make them patchable Jeremy Fitzhardinge
2007-04-04 19:12   ` Jeremy Fitzhardinge
2007-04-04 19:12 ` [patch 13/20] Document asm-i386/paravirt.h Jeremy Fitzhardinge
2007-04-04 19:12   ` Jeremy Fitzhardinge
2007-04-04 19:12 ` [patch 14/20] add common patching machinery Jeremy Fitzhardinge
2007-04-04 19:12   ` Jeremy Fitzhardinge
2007-04-04 19:12 ` Jeremy Fitzhardinge [this message]
2007-04-04 19:12   ` [patch 15/20] add flush_tlb_others paravirt_op Jeremy Fitzhardinge
2007-04-04 19:12 ` [patch 16/20] revert map_pt_hook Jeremy Fitzhardinge
2007-04-04 19:12   ` Jeremy Fitzhardinge
2007-04-04 19:12 ` [patch 17/20] add kmap_atomic_pte for mapping highpte pages Jeremy Fitzhardinge
2007-04-04 19:12   ` Jeremy Fitzhardinge
2007-04-04 19:12 ` [patch 18/20] clean up tsc-based sched_clock Jeremy Fitzhardinge
2007-04-04 19:12   ` Jeremy Fitzhardinge
2007-04-06 23:22   ` Andrew Morton
2007-04-06 23:27     ` Jeremy Fitzhardinge
2007-04-06 23:45       ` Andrew Morton
2007-04-06 23:40     ` Jeremy Fitzhardinge
2007-04-04 19:12 ` [patch 19/20] Add a sched_clock paravirt_op Jeremy Fitzhardinge
2007-04-04 19:12   ` Jeremy Fitzhardinge
2007-04-04 19:12 ` [patch 20/20] Add apply_to_page_range() which applies a function to a pte range Jeremy Fitzhardinge
2007-04-04 19:12   ` Jeremy Fitzhardinge
2007-04-05  4:41   ` Matt Mackall
2007-04-05  4:41     ` Matt Mackall
2007-04-05  6:52     ` Jeremy Fitzhardinge
2007-04-05  6:52       ` Jeremy Fitzhardinge
2007-04-17 20:56       ` Matt Mackall
2007-04-17 20:56         ` Matt Mackall
2007-04-19 19:44         ` Jeremy Fitzhardinge
2007-04-19 19:59           ` Matt Mackall
2007-04-19 19:59             ` Matt Mackall
2007-04-19 21:37             ` Jeremy Fitzhardinge
2007-04-19 21:37               ` Jeremy Fitzhardinge
2007-04-19 21:30               ` Matt Mackall
2007-04-19 21:30                 ` Matt Mackall
2007-04-19 22:30                 ` Jeremy Fitzhardinge

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=20070404191206.181792507@goop.org \
    --to=jeremy@goop.org \
    --cc=ak@suse.de \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=virtualization@lists.osdl.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.