mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/4] mmiotrace: various fixes and cleaning
@ 2009-04-28 19:17 Stuart Bennett
  2009-04-28 19:17 ` [PATCH] x86 mmiotrace: fix range test Stuart Bennett
  2009-04-29  9:36 ` [PATCH 0/4] mmiotrace: various fixes and cleaning Ingo Molnar
  0 siblings, 2 replies; 11+ messages in thread
From: Stuart Bennett @ 2009-04-28 19:17 UTC (permalink / raw)
  To: Ingo Molnar, Steven Rostedt; +Cc: Pekka Paalanen, linux-kernel

Hi all, this set contains one bug fix, a couple of cleanups, and a better fix
to the mmiotrace+gdb issue

Pekka Paalanen has kindly reviewed and acked all the changes.

It has been tested on 2.6.30-rc3 using a 32 bit processor and tracing the
proprietary Nvidia driver, and also builds cleanly on today's tip/master on
a 64 bit system

Stuart

Stuart Bennett (4):
      x86 mmiotrace: fix range test
      x86 mmiotrace: code consistency/legibility improvement
      x86 mmiotrace: refactor clearing/restore of page presence
      x86 mmiotrace: only register for die notifier when tracer active

 arch/x86/mm/kmmio.c       |  100 ++++++++++++++++++++++++++-------------------
 arch/x86/mm/mmio-mod.c    |    2 +
 include/linux/mmiotrace.h |    2 +
 3 files changed, 62 insertions(+), 42 deletions(-)

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] x86 mmiotrace: fix range test
  2009-04-28 19:17 [PATCH 0/4] mmiotrace: various fixes and cleaning Stuart Bennett
@ 2009-04-28 19:17 ` Stuart Bennett
  2009-04-28 19:17   ` [PATCH] x86 mmiotrace: code consistency/legibility improvement Stuart Bennett
  2009-04-29 11:04   ` [tip:tracing/urgent] tracing: x86, mmiotrace: fix range test tip-bot for Stuart Bennett
  2009-04-29  9:36 ` [PATCH 0/4] mmiotrace: various fixes and cleaning Ingo Molnar
  1 sibling, 2 replies; 11+ messages in thread
From: Stuart Bennett @ 2009-04-28 19:17 UTC (permalink / raw)
  To: Ingo Molnar, Steven Rostedt; +Cc: Pekka Paalanen, linux-kernel, Stuart Bennett

Matching on (addr == (p->addr + p->len)) causes problems when mappings
are adjacent

Signed-off-by: Stuart Bennett <stuart@freedesktop.org>
Acked-by: Pekka Paalanen <pq@iki.fi>
---
 arch/x86/mm/kmmio.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 4f115e0..50dc802 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -87,7 +87,7 @@ static struct kmmio_probe *get_kmmio_probe(unsigned long addr)
 {
 	struct kmmio_probe *p;
 	list_for_each_entry_rcu(p, &kmmio_probes, list) {
-		if (addr >= p->addr && addr <= (p->addr + p->len))
+		if (addr >= p->addr && addr < (p->addr + p->len))
 			return p;
 	}
 	return NULL;
-- 
1.5.4.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] x86 mmiotrace: code consistency/legibility improvement
  2009-04-28 19:17 ` [PATCH] x86 mmiotrace: fix range test Stuart Bennett
@ 2009-04-28 19:17   ` Stuart Bennett
  2009-04-28 19:17     ` [PATCH] x86 mmiotrace: refactor clearing/restore of page presence Stuart Bennett
  2009-04-29 11:04     ` [tip:tracing/core] tracing: x86, mmiotrace: code consistency/legibility improvement tip-bot for Stuart Bennett
  2009-04-29 11:04   ` [tip:tracing/urgent] tracing: x86, mmiotrace: fix range test tip-bot for Stuart Bennett
  1 sibling, 2 replies; 11+ messages in thread
From: Stuart Bennett @ 2009-04-28 19:17 UTC (permalink / raw)
  To: Ingo Molnar, Steven Rostedt; +Cc: Pekka Paalanen, linux-kernel, Stuart Bennett

kmmio_probe being *p and kmmio_fault_page being sometimes *f and
sometimes *p is not helpful

Signed-off-by: Stuart Bennett <stuart@freedesktop.org>
Acked-by: Pekka Paalanen <pq@iki.fi>
---
 arch/x86/mm/kmmio.c |   34 +++++++++++++++++-----------------
 1 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 50dc802..6db840e 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -97,13 +97,13 @@ static struct kmmio_probe *get_kmmio_probe(unsigned long addr)
 static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page)
 {
 	struct list_head *head;
-	struct kmmio_fault_page *p;
+	struct kmmio_fault_page *f;
 
 	page &= PAGE_MASK;
 	head = kmmio_page_list(page);
-	list_for_each_entry_rcu(p, head, list) {
-		if (p->page == page)
-			return p;
+	list_for_each_entry_rcu(f, head, list) {
+		if (f->page == page)
+			return f;
 	}
 	return NULL;
 }
@@ -439,12 +439,12 @@ static void rcu_free_kmmio_fault_pages(struct rcu_head *head)
 						head,
 						struct kmmio_delayed_release,
 						rcu);
-	struct kmmio_fault_page *p = dr->release_list;
-	while (p) {
-		struct kmmio_fault_page *next = p->release_next;
-		BUG_ON(p->count);
-		kfree(p);
-		p = next;
+	struct kmmio_fault_page *f = dr->release_list;
+	while (f) {
+		struct kmmio_fault_page *next = f->release_next;
+		BUG_ON(f->count);
+		kfree(f);
+		f = next;
 	}
 	kfree(dr);
 }
@@ -453,19 +453,19 @@ static void remove_kmmio_fault_pages(struct rcu_head *head)
 {
 	struct kmmio_delayed_release *dr =
 		container_of(head, struct kmmio_delayed_release, rcu);
-	struct kmmio_fault_page *p = dr->release_list;
+	struct kmmio_fault_page *f = dr->release_list;
 	struct kmmio_fault_page **prevp = &dr->release_list;
 	unsigned long flags;
 
 	spin_lock_irqsave(&kmmio_lock, flags);
-	while (p) {
-		if (!p->count) {
-			list_del_rcu(&p->list);
-			prevp = &p->release_next;
+	while (f) {
+		if (!f->count) {
+			list_del_rcu(&f->list);
+			prevp = &f->release_next;
 		} else {
-			*prevp = p->release_next;
+			*prevp = f->release_next;
 		}
-		p = p->release_next;
+		f = f->release_next;
 	}
 	spin_unlock_irqrestore(&kmmio_lock, flags);
 
-- 
1.5.4.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] x86 mmiotrace: refactor clearing/restore of page presence
  2009-04-28 19:17   ` [PATCH] x86 mmiotrace: code consistency/legibility improvement Stuart Bennett
@ 2009-04-28 19:17     ` Stuart Bennett
  2009-04-28 19:17       ` [PATCH] x86 mmiotrace: only register for die notifier when tracer active Stuart Bennett
  2009-04-29 11:04       ` [tip:tracing/core] tracing: x86, mmiotrace: refactor clearing/restore of page presence tip-bot for Stuart Bennett
  2009-04-29 11:04     ` [tip:tracing/core] tracing: x86, mmiotrace: code consistency/legibility improvement tip-bot for Stuart Bennett
  1 sibling, 2 replies; 11+ messages in thread
From: Stuart Bennett @ 2009-04-28 19:17 UTC (permalink / raw)
  To: Ingo Molnar, Steven Rostedt; +Cc: Pekka Paalanen, linux-kernel, Stuart Bennett

* change function names to clear_* from set_*: in reality we only clear
  and restore page presence, and never unconditionally set present.
  Using clear_*({true, false}, ...) is therefore more honest than
  set_*({false, true}, ...)

* upgrade presence storage to pteval_t: doing user-space tracing will
  require saving and manipulation of the _PAGE_PROTNONE bit, in addition
  to the existing _PAGE_PRESENT changes, and having multiple bools stored
  and passed around does not seem optimal

Signed-off-by: Stuart Bennett <stuart@freedesktop.org>
Acked-by: Pekka Paalanen <pq@iki.fi>
---
 arch/x86/mm/kmmio.c |   43 ++++++++++++++++++++++---------------------
 1 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 6db840e..422f49e 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -32,7 +32,7 @@ struct kmmio_fault_page {
 	struct list_head list;
 	struct kmmio_fault_page *release_next;
 	unsigned long page; /* location of the fault page */
-	bool old_presence; /* page presence prior to arming */
+	pteval_t old_presence; /* page presence prior to arming */
 	bool armed;
 
 	/*
@@ -108,49 +108,51 @@ static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page)
 	return NULL;
 }
 
-static void set_pmd_presence(pmd_t *pmd, bool present, bool *old)
+static void clear_pmd_presence(pmd_t *pmd, bool clear, pmdval_t *old)
 {
 	pmdval_t v = pmd_val(*pmd);
-	*old = !!(v & _PAGE_PRESENT);
-	v &= ~_PAGE_PRESENT;
-	if (present)
-		v |= _PAGE_PRESENT;
+	if (clear) {
+		*old = v & _PAGE_PRESENT;
+		v &= ~_PAGE_PRESENT;
+	} else	/* presume this has been called with clear==true previously */
+		v |= *old;
 	set_pmd(pmd, __pmd(v));
 }
 
-static void set_pte_presence(pte_t *pte, bool present, bool *old)
+static void clear_pte_presence(pte_t *pte, bool clear, pteval_t *old)
 {
 	pteval_t v = pte_val(*pte);
-	*old = !!(v & _PAGE_PRESENT);
-	v &= ~_PAGE_PRESENT;
-	if (present)
-		v |= _PAGE_PRESENT;
+	if (clear) {
+		*old = v & _PAGE_PRESENT;
+		v &= ~_PAGE_PRESENT;
+	} else	/* presume this has been called with clear==true previously */
+		v |= *old;
 	set_pte_atomic(pte, __pte(v));
 }
 
-static int set_page_presence(unsigned long addr, bool present, bool *old)
+static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
 {
 	unsigned int level;
-	pte_t *pte = lookup_address(addr, &level);
+	pte_t *pte = lookup_address(f->page, &level);
 
 	if (!pte) {
-		pr_err("kmmio: no pte for page 0x%08lx\n", addr);
+		pr_err("kmmio: no pte for page 0x%08lx\n", f->page);
 		return -1;
 	}
 
 	switch (level) {
 	case PG_LEVEL_2M:
-		set_pmd_presence((pmd_t *)pte, present, old);
+		clear_pmd_presence((pmd_t *)pte, clear, &f->old_presence);
 		break;
 	case PG_LEVEL_4K:
-		set_pte_presence(pte, present, old);
+		clear_pte_presence(pte, clear, &f->old_presence);
 		break;
 	default:
 		pr_err("kmmio: unexpected page level 0x%x.\n", level);
 		return -1;
 	}
 
-	__flush_tlb_one(addr);
+	__flush_tlb_one(f->page);
 	return 0;
 }
 
@@ -171,9 +173,9 @@ static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
 	WARN_ONCE(f->armed, KERN_ERR "kmmio page already armed.\n");
 	if (f->armed) {
 		pr_warning("kmmio double-arm: page 0x%08lx, ref %d, old %d\n",
-					f->page, f->count, f->old_presence);
+					f->page, f->count, !!f->old_presence);
 	}
-	ret = set_page_presence(f->page, false, &f->old_presence);
+	ret = clear_page_presence(f, true);
 	WARN_ONCE(ret < 0, KERN_ERR "kmmio arming 0x%08lx failed.\n", f->page);
 	f->armed = true;
 	return ret;
@@ -182,8 +184,7 @@ static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
 /** Restore the given page to saved presence state. */
 static void disarm_kmmio_fault_page(struct kmmio_fault_page *f)
 {
-	bool tmp;
-	int ret = set_page_presence(f->page, f->old_presence, &tmp);
+	int ret = clear_page_presence(f, false);
 	WARN_ONCE(ret < 0,
 			KERN_ERR "kmmio disarming 0x%08lx failed.\n", f->page);
 	f->armed = false;
-- 
1.5.4.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH] x86 mmiotrace: only register for die notifier when tracer active
  2009-04-28 19:17     ` [PATCH] x86 mmiotrace: refactor clearing/restore of page presence Stuart Bennett
@ 2009-04-28 19:17       ` Stuart Bennett
  2009-04-29  9:39         ` Ingo Molnar
  2009-04-29 11:05         ` [tip:tracing/core] tracing: x86, " tip-bot for Stuart Bennett
  2009-04-29 11:04       ` [tip:tracing/core] tracing: x86, mmiotrace: refactor clearing/restore of page presence tip-bot for Stuart Bennett
  1 sibling, 2 replies; 11+ messages in thread
From: Stuart Bennett @ 2009-04-28 19:17 UTC (permalink / raw)
  To: Ingo Molnar, Steven Rostedt; +Cc: Pekka Paalanen, linux-kernel, Stuart Bennett

Follow up to afcfe024aebd74b0984a41af9a34e009cf5badaf in Linus' tree
("x86: mmiotrace: quieten spurious warning message")

Signed-off-by: Stuart Bennett <stuart@freedesktop.org>
Acked-by: Pekka Paalanen <pq@iki.fi>
---
 arch/x86/mm/kmmio.c       |   21 ++++++++++++++++++---
 arch/x86/mm/mmio-mod.c    |    2 ++
 include/linux/mmiotrace.h |    2 ++
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 422f49e..bdbbf0d 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -311,7 +311,12 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
 	struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx);
 
 	if (!ctx->active) {
-		pr_debug("kmmio: spurious debug trap on CPU %d.\n",
+		/*
+		 * debug traps without an active context are due to either
+		 * something external causing them (f.e. using a debugger while
+		 * mmio tracing enabled), or erroneous behaviour
+		 */
+		pr_warning("kmmio: unexpected debug trap on CPU %d.\n",
 							smp_processor_id());
 		goto out;
 	}
@@ -545,11 +550,21 @@ static struct notifier_block nb_die = {
 	.notifier_call = kmmio_die_notifier
 };
 
-static int __init init_kmmio(void)
+int kmmio_init(void)
 {
 	int i;
 	for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++)
 		INIT_LIST_HEAD(&kmmio_page_table[i]);
 	return register_die_notifier(&nb_die);
 }
-fs_initcall(init_kmmio); /* should be before device_initcall() */
+
+void kmmio_cleanup(void)
+{
+	int i;
+
+	unregister_die_notifier(&nb_die);
+	for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++)
+		WARN_ONCE(!list_empty(&kmmio_page_table[i]),
+			  KERN_ERR "kmmio_page_table not empty at cleanup, "
+				   "any further tracing will leak memory\n");
+}
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index c9342ed..132772a 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -451,6 +451,7 @@ void enable_mmiotrace(void)
 
 	if (nommiotrace)
 		pr_info(NAME "MMIO tracing disabled.\n");
+	kmmio_init();
 	enter_uniprocessor();
 	spin_lock_irq(&trace_lock);
 	atomic_inc(&mmiotrace_enabled);
@@ -473,6 +474,7 @@ void disable_mmiotrace(void)
 
 	clear_trace_list(); /* guarantees: no more kmmio callbacks */
 	leave_uniprocessor();
+	kmmio_cleanup();
 	pr_info(NAME "disabled.\n");
 out:
 	mutex_unlock(&mmiotrace_mutex);
diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h
index 3d1b7bd..97491f7 100644
--- a/include/linux/mmiotrace.h
+++ b/include/linux/mmiotrace.h
@@ -30,6 +30,8 @@ extern unsigned int kmmio_count;
 
 extern int register_kmmio_probe(struct kmmio_probe *p);
 extern void unregister_kmmio_probe(struct kmmio_probe *p);
+extern int kmmio_init(void);
+extern void kmmio_cleanup(void);
 
 #ifdef CONFIG_MMIOTRACE
 /* kmmio is active by some kmmio_probes? */
-- 
1.5.4.4


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 0/4] mmiotrace: various fixes and cleaning
  2009-04-28 19:17 [PATCH 0/4] mmiotrace: various fixes and cleaning Stuart Bennett
  2009-04-28 19:17 ` [PATCH] x86 mmiotrace: fix range test Stuart Bennett
@ 2009-04-29  9:36 ` Ingo Molnar
  1 sibling, 0 replies; 11+ messages in thread
From: Ingo Molnar @ 2009-04-29  9:36 UTC (permalink / raw)
  To: Stuart Bennett; +Cc: Steven Rostedt, Pekka Paalanen, linux-kernel


* Stuart Bennett <stuart@freedesktop.org> wrote:

> Hi all, this set contains one bug fix, a couple of cleanups, and a better fix
> to the mmiotrace+gdb issue
> 
> Pekka Paalanen has kindly reviewed and acked all the changes.
> 
> It has been tested on 2.6.30-rc3 using a 32 bit processor and tracing the
> proprietary Nvidia driver, and also builds cleanly on today's tip/master on
> a 64 bit system
> 
> Stuart
> 
> Stuart Bennett (4):
>       x86 mmiotrace: fix range test
>       x86 mmiotrace: code consistency/legibility improvement
>       x86 mmiotrace: refactor clearing/restore of page presence
>       x86 mmiotrace: only register for die notifier when tracer active
> 
>  arch/x86/mm/kmmio.c       |  100 ++++++++++++++++++++++++++-------------------
>  arch/x86/mm/mmio-mod.c    |    2 +
>  include/linux/mmiotrace.h |    2 +
>  3 files changed, 62 insertions(+), 42 deletions(-)

I've applied:

  33015c8: tracing: x86, mmiotrace: fix range test

to tip:tracing/urgent for v2.6.30, and have applied the other 3 
patches to tip:tracing/mmiotrace, for v2.6.31:

  0f9a623: tracing: x86, mmiotrace: only register for die notifier when tracer active
  46e91d0: tracing: x86, mmiotrace: refactor clearing/restore of page presence
  0492e1b: tracing: x86, mmiotrace: code consistency/legibility improvement

Thanks Stuart!

	Ingo

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH] x86 mmiotrace: only register for die notifier when tracer active
  2009-04-28 19:17       ` [PATCH] x86 mmiotrace: only register for die notifier when tracer active Stuart Bennett
@ 2009-04-29  9:39         ` Ingo Molnar
  2009-04-29 11:05         ` [tip:tracing/core] tracing: x86, " tip-bot for Stuart Bennett
  1 sibling, 0 replies; 11+ messages in thread
From: Ingo Molnar @ 2009-04-29  9:39 UTC (permalink / raw)
  To: Stuart Bennett; +Cc: Steven Rostedt, Pekka Paalanen, linux-kernel


* Stuart Bennett <stuart@freedesktop.org> wrote:

> Follow up to afcfe024aebd74b0984a41af9a34e009cf5badaf in Linus' tree
> ("x86: mmiotrace: quieten spurious warning message")
> 
> Signed-off-by: Stuart Bennett <stuart@freedesktop.org>
> Acked-by: Pekka Paalanen <pq@iki.fi>
> ---
>  arch/x86/mm/kmmio.c       |   21 ++++++++++++++++++---
>  arch/x86/mm/mmio-mod.c    |    2 ++
>  include/linux/mmiotrace.h |    2 ++
>  3 files changed, 22 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
> index 422f49e..bdbbf0d 100644
> --- a/arch/x86/mm/kmmio.c
> +++ b/arch/x86/mm/kmmio.c
> @@ -311,7 +311,12 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
>  	struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx);
>  
>  	if (!ctx->active) {
> -		pr_debug("kmmio: spurious debug trap on CPU %d.\n",
> +		/*
> +		 * debug traps without an active context are due to either
> +		 * something external causing them (f.e. using a debugger while
> +		 * mmio tracing enabled), or erroneous behaviour
> +		 */
> +		pr_warning("kmmio: unexpected debug trap on CPU %d.\n",
>  							smp_processor_id());
>  		goto out;
>  	}
> @@ -545,11 +550,21 @@ static struct notifier_block nb_die = {
>  	.notifier_call = kmmio_die_notifier
>  };
>  
> -static int __init init_kmmio(void)
> +int kmmio_init(void)
>  {
>  	int i;
>  	for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++)
>  		INIT_LIST_HEAD(&kmmio_page_table[i]);
>  	return register_die_notifier(&nb_die);
>  }
> -fs_initcall(init_kmmio); /* should be before device_initcall() */
> +
> +void kmmio_cleanup(void)
> +{
> +	int i;
> +
> +	unregister_die_notifier(&nb_die);
> +	for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++)
> +		WARN_ONCE(!list_empty(&kmmio_page_table[i]),
> +			  KERN_ERR "kmmio_page_table not empty at cleanup, "
> +				   "any further tracing will leak memory\n");
> +}

Note, i cleaned this up a bit in the commit i applied - we rather 
let strings become over-long than break them in the middle

	Ingo

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [tip:tracing/urgent] tracing: x86, mmiotrace: fix range test
  2009-04-28 19:17 ` [PATCH] x86 mmiotrace: fix range test Stuart Bennett
  2009-04-28 19:17   ` [PATCH] x86 mmiotrace: code consistency/legibility improvement Stuart Bennett
@ 2009-04-29 11:04   ` tip-bot for Stuart Bennett
  1 sibling, 0 replies; 11+ messages in thread
From: tip-bot for Stuart Bennett @ 2009-04-29 11:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rostedt, pq, stuart, tglx, mingo

Commit-ID:  33015c85995716d03f6293346cf05a1908b0fb9a
Gitweb:     http://git.kernel.org/tip/33015c85995716d03f6293346cf05a1908b0fb9a
Author:     Stuart Bennett <stuart@freedesktop.org>
AuthorDate: Tue, 28 Apr 2009 20:17:48 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 29 Apr 2009 11:32:22 +0200

tracing: x86, mmiotrace: fix range test

Matching on (addr == (p->addr + p->len)) causes problems when mappings
are adjacent.

[ Impact: fix mmiotrace confusion on adjacent iomaps ]

Signed-off-by: Stuart Bennett <stuart@freedesktop.org>
Acked-by: Pekka Paalanen <pq@iki.fi>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1240946271-7083-2-git-send-email-stuart@freedesktop.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>


---
 arch/x86/mm/kmmio.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 4f115e0..50dc802 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -87,7 +87,7 @@ static struct kmmio_probe *get_kmmio_probe(unsigned long addr)
 {
 	struct kmmio_probe *p;
 	list_for_each_entry_rcu(p, &kmmio_probes, list) {
-		if (addr >= p->addr && addr <= (p->addr + p->len))
+		if (addr >= p->addr && addr < (p->addr + p->len))
 			return p;
 	}
 	return NULL;

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [tip:tracing/core] tracing: x86, mmiotrace: code consistency/legibility improvement
  2009-04-28 19:17   ` [PATCH] x86 mmiotrace: code consistency/legibility improvement Stuart Bennett
  2009-04-28 19:17     ` [PATCH] x86 mmiotrace: refactor clearing/restore of page presence Stuart Bennett
@ 2009-04-29 11:04     ` tip-bot for Stuart Bennett
  1 sibling, 0 replies; 11+ messages in thread
From: tip-bot for Stuart Bennett @ 2009-04-29 11:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rostedt, pq, stuart, tglx, mingo

Commit-ID:  0492e1bb8fe7d122901c9f3af75e537d4129712e
Gitweb:     http://git.kernel.org/tip/0492e1bb8fe7d122901c9f3af75e537d4129712e
Author:     Stuart Bennett <stuart@freedesktop.org>
AuthorDate: Tue, 28 Apr 2009 20:17:49 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 29 Apr 2009 11:33:33 +0200

tracing: x86, mmiotrace: code consistency/legibility improvement

kmmio_probe being *p and kmmio_fault_page being sometimes *f and
sometimes *p is not helpful.

[ Impact: cleanup ]

Signed-off-by: Stuart Bennett <stuart@freedesktop.org>
Acked-by: Pekka Paalanen <pq@iki.fi>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1240946271-7083-3-git-send-email-stuart@freedesktop.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>


---
 arch/x86/mm/kmmio.c |   34 +++++++++++++++++-----------------
 1 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 4f115e0..869181a 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -97,13 +97,13 @@ static struct kmmio_probe *get_kmmio_probe(unsigned long addr)
 static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page)
 {
 	struct list_head *head;
-	struct kmmio_fault_page *p;
+	struct kmmio_fault_page *f;
 
 	page &= PAGE_MASK;
 	head = kmmio_page_list(page);
-	list_for_each_entry_rcu(p, head, list) {
-		if (p->page == page)
-			return p;
+	list_for_each_entry_rcu(f, head, list) {
+		if (f->page == page)
+			return f;
 	}
 	return NULL;
 }
@@ -439,12 +439,12 @@ static void rcu_free_kmmio_fault_pages(struct rcu_head *head)
 						head,
 						struct kmmio_delayed_release,
 						rcu);
-	struct kmmio_fault_page *p = dr->release_list;
-	while (p) {
-		struct kmmio_fault_page *next = p->release_next;
-		BUG_ON(p->count);
-		kfree(p);
-		p = next;
+	struct kmmio_fault_page *f = dr->release_list;
+	while (f) {
+		struct kmmio_fault_page *next = f->release_next;
+		BUG_ON(f->count);
+		kfree(f);
+		f = next;
 	}
 	kfree(dr);
 }
@@ -453,19 +453,19 @@ static void remove_kmmio_fault_pages(struct rcu_head *head)
 {
 	struct kmmio_delayed_release *dr =
 		container_of(head, struct kmmio_delayed_release, rcu);
-	struct kmmio_fault_page *p = dr->release_list;
+	struct kmmio_fault_page *f = dr->release_list;
 	struct kmmio_fault_page **prevp = &dr->release_list;
 	unsigned long flags;
 
 	spin_lock_irqsave(&kmmio_lock, flags);
-	while (p) {
-		if (!p->count) {
-			list_del_rcu(&p->list);
-			prevp = &p->release_next;
+	while (f) {
+		if (!f->count) {
+			list_del_rcu(&f->list);
+			prevp = &f->release_next;
 		} else {
-			*prevp = p->release_next;
+			*prevp = f->release_next;
 		}
-		p = p->release_next;
+		f = f->release_next;
 	}
 	spin_unlock_irqrestore(&kmmio_lock, flags);
 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [tip:tracing/core] tracing: x86, mmiotrace: refactor clearing/restore of page presence
  2009-04-28 19:17     ` [PATCH] x86 mmiotrace: refactor clearing/restore of page presence Stuart Bennett
  2009-04-28 19:17       ` [PATCH] x86 mmiotrace: only register for die notifier when tracer active Stuart Bennett
@ 2009-04-29 11:04       ` tip-bot for Stuart Bennett
  1 sibling, 0 replies; 11+ messages in thread
From: tip-bot for Stuart Bennett @ 2009-04-29 11:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rostedt, pq, stuart, tglx, mingo

Commit-ID:  46e91d00b1165b14b484aa33800e1bba0794ae1a
Gitweb:     http://git.kernel.org/tip/46e91d00b1165b14b484aa33800e1bba0794ae1a
Author:     Stuart Bennett <stuart@freedesktop.org>
AuthorDate: Tue, 28 Apr 2009 20:17:50 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 29 Apr 2009 11:33:33 +0200

tracing: x86, mmiotrace: refactor clearing/restore of page presence

* change function names to clear_* from set_*: in reality we only clear
  and restore page presence, and never unconditionally set present.
  Using clear_*({true, false}, ...) is therefore more honest than
  set_*({false, true}, ...)

* upgrade presence storage to pteval_t: doing user-space tracing will
  require saving and manipulation of the _PAGE_PROTNONE bit, in addition
  to the existing _PAGE_PRESENT changes, and having multiple bools stored
  and passed around does not seem optimal

[ Impact: refactor, clean up mmiotrace code ]

Signed-off-by: Stuart Bennett <stuart@freedesktop.org>
Acked-by: Pekka Paalanen <pq@iki.fi>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1240946271-7083-4-git-send-email-stuart@freedesktop.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>


---
 arch/x86/mm/kmmio.c |   43 ++++++++++++++++++++++---------------------
 1 files changed, 22 insertions(+), 21 deletions(-)

diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index 869181a..a769d1a 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -32,7 +32,7 @@ struct kmmio_fault_page {
 	struct list_head list;
 	struct kmmio_fault_page *release_next;
 	unsigned long page; /* location of the fault page */
-	bool old_presence; /* page presence prior to arming */
+	pteval_t old_presence; /* page presence prior to arming */
 	bool armed;
 
 	/*
@@ -108,49 +108,51 @@ static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page)
 	return NULL;
 }
 
-static void set_pmd_presence(pmd_t *pmd, bool present, bool *old)
+static void clear_pmd_presence(pmd_t *pmd, bool clear, pmdval_t *old)
 {
 	pmdval_t v = pmd_val(*pmd);
-	*old = !!(v & _PAGE_PRESENT);
-	v &= ~_PAGE_PRESENT;
-	if (present)
-		v |= _PAGE_PRESENT;
+	if (clear) {
+		*old = v & _PAGE_PRESENT;
+		v &= ~_PAGE_PRESENT;
+	} else	/* presume this has been called with clear==true previously */
+		v |= *old;
 	set_pmd(pmd, __pmd(v));
 }
 
-static void set_pte_presence(pte_t *pte, bool present, bool *old)
+static void clear_pte_presence(pte_t *pte, bool clear, pteval_t *old)
 {
 	pteval_t v = pte_val(*pte);
-	*old = !!(v & _PAGE_PRESENT);
-	v &= ~_PAGE_PRESENT;
-	if (present)
-		v |= _PAGE_PRESENT;
+	if (clear) {
+		*old = v & _PAGE_PRESENT;
+		v &= ~_PAGE_PRESENT;
+	} else	/* presume this has been called with clear==true previously */
+		v |= *old;
 	set_pte_atomic(pte, __pte(v));
 }
 
-static int set_page_presence(unsigned long addr, bool present, bool *old)
+static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
 {
 	unsigned int level;
-	pte_t *pte = lookup_address(addr, &level);
+	pte_t *pte = lookup_address(f->page, &level);
 
 	if (!pte) {
-		pr_err("kmmio: no pte for page 0x%08lx\n", addr);
+		pr_err("kmmio: no pte for page 0x%08lx\n", f->page);
 		return -1;
 	}
 
 	switch (level) {
 	case PG_LEVEL_2M:
-		set_pmd_presence((pmd_t *)pte, present, old);
+		clear_pmd_presence((pmd_t *)pte, clear, &f->old_presence);
 		break;
 	case PG_LEVEL_4K:
-		set_pte_presence(pte, present, old);
+		clear_pte_presence(pte, clear, &f->old_presence);
 		break;
 	default:
 		pr_err("kmmio: unexpected page level 0x%x.\n", level);
 		return -1;
 	}
 
-	__flush_tlb_one(addr);
+	__flush_tlb_one(f->page);
 	return 0;
 }
 
@@ -171,9 +173,9 @@ static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
 	WARN_ONCE(f->armed, KERN_ERR "kmmio page already armed.\n");
 	if (f->armed) {
 		pr_warning("kmmio double-arm: page 0x%08lx, ref %d, old %d\n",
-					f->page, f->count, f->old_presence);
+					f->page, f->count, !!f->old_presence);
 	}
-	ret = set_page_presence(f->page, false, &f->old_presence);
+	ret = clear_page_presence(f, true);
 	WARN_ONCE(ret < 0, KERN_ERR "kmmio arming 0x%08lx failed.\n", f->page);
 	f->armed = true;
 	return ret;
@@ -182,8 +184,7 @@ static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
 /** Restore the given page to saved presence state. */
 static void disarm_kmmio_fault_page(struct kmmio_fault_page *f)
 {
-	bool tmp;
-	int ret = set_page_presence(f->page, f->old_presence, &tmp);
+	int ret = clear_page_presence(f, false);
 	WARN_ONCE(ret < 0,
 			KERN_ERR "kmmio disarming 0x%08lx failed.\n", f->page);
 	f->armed = false;

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [tip:tracing/core] tracing: x86, mmiotrace: only register for die notifier when tracer active
  2009-04-28 19:17       ` [PATCH] x86 mmiotrace: only register for die notifier when tracer active Stuart Bennett
  2009-04-29  9:39         ` Ingo Molnar
@ 2009-04-29 11:05         ` tip-bot for Stuart Bennett
  1 sibling, 0 replies; 11+ messages in thread
From: tip-bot for Stuart Bennett @ 2009-04-29 11:05 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, hpa, mingo, rostedt, pq, stuart, tglx, mingo

Commit-ID:  0f9a623dd6c9b5b4dd00c232f29525bfc7a8ecf2
Gitweb:     http://git.kernel.org/tip/0f9a623dd6c9b5b4dd00c232f29525bfc7a8ecf2
Author:     Stuart Bennett <stuart@freedesktop.org>
AuthorDate: Tue, 28 Apr 2009 20:17:51 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Wed, 29 Apr 2009 11:33:34 +0200

tracing: x86, mmiotrace: only register for die notifier when tracer active

Follow up to afcfe024aebd74b0984a41af9a34e009cf5badaf in Linus' tree
("x86: mmiotrace: quieten spurious warning message")

Signed-off-by: Stuart Bennett <stuart@freedesktop.org>
Acked-by: Pekka Paalanen <pq@iki.fi>
Cc: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <1240946271-7083-5-git-send-email-stuart@freedesktop.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>


---
 arch/x86/mm/kmmio.c       |   27 ++++++++++++++++++++++-----
 arch/x86/mm/mmio-mod.c    |    2 ++
 include/linux/mmiotrace.h |    2 ++
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c
index a769d1a..256ce64 100644
--- a/arch/x86/mm/kmmio.c
+++ b/arch/x86/mm/kmmio.c
@@ -311,7 +311,12 @@ static int post_kmmio_handler(unsigned long condition, struct pt_regs *regs)
 	struct kmmio_context *ctx = &get_cpu_var(kmmio_ctx);
 
 	if (!ctx->active) {
-		pr_debug("kmmio: spurious debug trap on CPU %d.\n",
+		/*
+		 * debug traps without an active context are due to either
+		 * something external causing them (f.e. using a debugger while
+		 * mmio tracing enabled), or erroneous behaviour
+		 */
+		pr_warning("kmmio: unexpected debug trap on CPU %d.\n",
 							smp_processor_id());
 		goto out;
 	}
@@ -529,8 +534,8 @@ void unregister_kmmio_probe(struct kmmio_probe *p)
 }
 EXPORT_SYMBOL(unregister_kmmio_probe);
 
-static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val,
-								void *args)
+static int
+kmmio_die_notifier(struct notifier_block *nb, unsigned long val, void *args)
 {
 	struct die_args *arg = args;
 
@@ -545,11 +550,23 @@ static struct notifier_block nb_die = {
 	.notifier_call = kmmio_die_notifier
 };
 
-static int __init init_kmmio(void)
+int kmmio_init(void)
 {
 	int i;
+
 	for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++)
 		INIT_LIST_HEAD(&kmmio_page_table[i]);
+
 	return register_die_notifier(&nb_die);
 }
-fs_initcall(init_kmmio); /* should be before device_initcall() */
+
+void kmmio_cleanup(void)
+{
+	int i;
+
+	unregister_die_notifier(&nb_die);
+	for (i = 0; i < KMMIO_PAGE_TABLE_SIZE; i++) {
+		WARN_ONCE(!list_empty(&kmmio_page_table[i]),
+			KERN_ERR "kmmio_page_table not empty at cleanup, any further tracing will leak memory.\n");
+	}
+}
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index c9342ed..132772a 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -451,6 +451,7 @@ void enable_mmiotrace(void)
 
 	if (nommiotrace)
 		pr_info(NAME "MMIO tracing disabled.\n");
+	kmmio_init();
 	enter_uniprocessor();
 	spin_lock_irq(&trace_lock);
 	atomic_inc(&mmiotrace_enabled);
@@ -473,6 +474,7 @@ void disable_mmiotrace(void)
 
 	clear_trace_list(); /* guarantees: no more kmmio callbacks */
 	leave_uniprocessor();
+	kmmio_cleanup();
 	pr_info(NAME "disabled.\n");
 out:
 	mutex_unlock(&mmiotrace_mutex);
diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h
index 3d1b7bd..97491f7 100644
--- a/include/linux/mmiotrace.h
+++ b/include/linux/mmiotrace.h
@@ -30,6 +30,8 @@ extern unsigned int kmmio_count;
 
 extern int register_kmmio_probe(struct kmmio_probe *p);
 extern void unregister_kmmio_probe(struct kmmio_probe *p);
+extern int kmmio_init(void);
+extern void kmmio_cleanup(void);
 
 #ifdef CONFIG_MMIOTRACE
 /* kmmio is active by some kmmio_probes? */

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2009-04-29 11:06 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-28 19:17 [PATCH 0/4] mmiotrace: various fixes and cleaning Stuart Bennett
2009-04-28 19:17 ` [PATCH] x86 mmiotrace: fix range test Stuart Bennett
2009-04-28 19:17   ` [PATCH] x86 mmiotrace: code consistency/legibility improvement Stuart Bennett
2009-04-28 19:17     ` [PATCH] x86 mmiotrace: refactor clearing/restore of page presence Stuart Bennett
2009-04-28 19:17       ` [PATCH] x86 mmiotrace: only register for die notifier when tracer active Stuart Bennett
2009-04-29  9:39         ` Ingo Molnar
2009-04-29 11:05         ` [tip:tracing/core] tracing: x86, " tip-bot for Stuart Bennett
2009-04-29 11:04       ` [tip:tracing/core] tracing: x86, mmiotrace: refactor clearing/restore of page presence tip-bot for Stuart Bennett
2009-04-29 11:04     ` [tip:tracing/core] tracing: x86, mmiotrace: code consistency/legibility improvement tip-bot for Stuart Bennett
2009-04-29 11:04   ` [tip:tracing/urgent] tracing: x86, mmiotrace: fix range test tip-bot for Stuart Bennett
2009-04-29  9:36 ` [PATCH 0/4] mmiotrace: various fixes and cleaning Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome