All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
To: akpm@linux-foundation.org, linux-kernel@vger.kernel.org
Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Subject: [patch 7/8] Immediate Value - PowerPC Optimization
Date: Fri, 13 Jul 2007 21:24:46 -0400	[thread overview]
Message-ID: <20070714012624.842959793@polymtl.ca> (raw)
In-Reply-To: 20070714012439.285079881@polymtl.ca

[-- Attachment #1: immediate-values-powerpc-optimization.patch --]
[-- Type: text/plain, Size: 7359 bytes --]

PowerPC optimization of the immediate values which uses a li instruction,
patched with an immediate value.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
---
 arch/powerpc/kernel/Makefile    |    1 
 arch/powerpc/kernel/immediate.c |   98 ++++++++++++++++++++++++++++++++++++
 include/asm-powerpc/immediate.h |  107 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 205 insertions(+), 1 deletion(-)

Index: linux-2.6-lttng/include/asm-powerpc/immediate.h
===================================================================
--- linux-2.6-lttng.orig/include/asm-powerpc/immediate.h	2007-07-13 19:26:18.000000000 -0400
+++ linux-2.6-lttng/include/asm-powerpc/immediate.h	2007-07-13 19:28:49.000000000 -0400
@@ -1 +1,106 @@
-#include <asm-generic/immediate.h>
+#ifndef _ASM_POWERPC_IMMEDIATE_H
+#define _ASM_POWERPC_IMMEDIATE_H
+
+/*
+ * Immediate values. PowerPC architecture optimizations.
+ *
+ * (C) Copyright 2006 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ *
+ * This file is released under the GPLv2.
+ * See the file COPYING for more details.
+ */
+
+#include <asm/asm-compat.h>
+
+struct module;
+
+struct __immediate {
+	long var;		/* Identifier variable of the immediate value */
+	long immediate;		/*
+				 * Pointer to the memory location that holds
+				 * the immediate value within the load immediate
+				 * instruction.
+				 */
+	long size;		/* Type size. */
+};
+
+/*
+ * Optimized version of the immediate.
+ * Make sure the 2 bytes update will be atomic by aligning the immediate
+ * value.
+ * Use a normal memory read for the 4 bytes immediate because there is no way to
+ * atomically update it without using a seqlock read side, which would cost more
+ * in term of total i-cache and d-cache space than a simple memory read.
+ * Do not use in __init and __exit functions. Use _immediate_read() instead.
+ */
+#define immediate_read(var)						\
+	({								\
+		__typeof__((var)->value) value;				\
+		switch (sizeof(value)) {				\
+		case 1:							\
+			asm (	".section __immediate, \"a\", @progbits;\n\t" \
+					PPC_LONG "%1, ((0f)+3), 1;\n\t"	\
+					".previous;\n\t"		\
+					"0:\n\t"			\
+					"li %0,%2;\n\t"			\
+				: "=r" (value)				\
+				: "i" (&(var)->value),			\
+				  "i" (0));				\
+			break;						\
+		case 2:							\
+			asm (	".section __immediate, \"a\", @progbits;\n\t" \
+					PPC_LONG "%1, ((0f)+2), 2;\n\t"	\
+					".previous;\n\t"		\
+					".align 2\n\t"			\
+					"0:\n\t"			\
+					"li %0,%2;\n\t"			\
+				: "=r" (value)				\
+				: "i" (&(var)->value),			\
+				  "i" (0));				\
+			break;						\
+		default:						\
+			value = (var)->value;				\
+			break;						\
+		};							\
+		value;							\
+	})
+
+/*
+ * Update immediate value, can take module mutex.
+ */
+#define immediate_set(var, i) \
+	(var)->value = (i); \
+	immediate_update(1);
+
+/*
+ * Update immediate value. Module mutex must already be taken.
+ */
+#define _immediate_set(var, i) \
+	(var)->value = (i); \
+	immediate_update(0);
+
+/*
+ * Update immediate value at early boot.
+ */
+#define immediate_set_early(var, i) \
+	(var)->value = (i); \
+	immediate_update_early();
+
+/*
+ * Branch depending on an immediate value. Could eventually be optimized further
+ * by improving gcc to give the ability to patch a jump instruction instead of
+ * the value it depends on.
+ * Do not use in __init and __exit functions. Use _immediate_if() instead.
+ */
+#define immediate_if(var)	if (unlikely(immediate_read(var)))
+
+/*
+ * Used internally.
+ */
+extern void immediate_update(int lock);
+extern void module_immediate_setup(struct module *mod);
+extern void immediate_update_early(void);
+extern int arch_immediate_update(const struct __immediate *immediate);
+extern void arch_immediate_update_early(const struct __immediate *immediate);
+
+#endif /* _ASM_POWERPC_IMMEDIATE_H */
Index: linux-2.6-lttng/arch/powerpc/kernel/Makefile
===================================================================
--- linux-2.6-lttng.orig/arch/powerpc/kernel/Makefile	2007-07-13 19:26:18.000000000 -0400
+++ linux-2.6-lttng/arch/powerpc/kernel/Makefile	2007-07-13 19:28:29.000000000 -0400
@@ -103,3 +103,4 @@
 
 extra-$(CONFIG_PPC_FPU)		+= fpu.o
 extra-$(CONFIG_PPC64)		+= entry_64.o
+obj-$(CONFIG_IMMEDIATE)		+= immediate.o
Index: linux-2.6-lttng/arch/powerpc/kernel/immediate.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6-lttng/arch/powerpc/kernel/immediate.c	2007-07-13 19:28:29.000000000 -0400
@@ -0,0 +1,98 @@
+/*
+ * Powerpc optimized immediate values enabling/disabling.
+ *
+ * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+ */
+
+#include <linux/module.h>
+#include <linux/immediate.h>
+#include <linux/string.h>
+#include <linux/kprobes.h>
+#include <asm/cacheflush.h>
+#include <asm/page.h>
+
+#define LI_OPCODE_LEN	2
+
+/*
+ * The immediate value are aligned.
+ */
+int arch_immediate_update(const struct __immediate *immediate)
+{
+#ifdef CONFIG_KPROBES
+	kprobe_opcode_t *insn;
+	/*
+	 * Fail if a kprobe has been set on this instruction.
+	 * (TODO: we could eventually do better and modify all the (possibly
+	 * nested) kprobes for this site if kprobes had an API for this.
+	 */
+	switch (immediate->size) {
+		case 1:	/* The uint8_t points to the 3rd byte of the
+			 * instruction */
+			insn = (void*)(immediate->immediate - 1 - LI_OPCODE_LEN);
+			break;
+		case 2:	insn = (void*)(immediate->immediate - LI_OPCODE_LEN);
+			break;
+		default:
+		return -EINVAL;
+	}
+
+	if (unlikely(*insn == BREAKPOINT_INSTRUCTION)) {
+		printk(KERN_WARNING "Immediate value in conflict with kprobe. "
+				    "Variable at %p, "
+				    "instruction at %p, size %lu\n",
+				    (void*)immediate->immediate,
+				    (void*)immediate->var, immediate->size);
+		return -EBUSY;
+	}
+#endif
+
+	/*
+	 * If the variable and the instruction have the same value, there is
+	 * nothing to do.
+	 */
+	switch (immediate->size) {
+		case 1:	if (*(uint8_t*)immediate->immediate
+					== *(uint8_t*)immediate->var)
+				return 0;
+			break;
+		case 2:	if (*(uint16_t*)immediate->immediate
+					== *(uint16_t*)immediate->var)
+				return 0;
+			break;
+		default:return -EINVAL;
+	}
+	memcpy((void*)immediate->immediate, (void*)immediate->var,
+			immediate->size);
+	flush_icache_range((unsigned long)immediate->immediate,
+				immediate->size);
+	return 0;
+}
+
+/*
+ * Very early initialization of the in-core immediate values.
+ * We can use flush_icache_range, since the cpu identification has been done in
+ * the early_init stage.
+ */
+void __init arch_immediate_update_early(const struct __immediate *immediate)
+{
+	/*
+	 * If the variable and the instruction have the same value, there is
+	 * nothing to do.
+	 */
+	switch (immediate->size) {
+		case 1:	if (*(uint8_t*)immediate->immediate
+					== *(uint8_t*)immediate->var)
+				return;
+			break;
+		case 2:	if (*(uint16_t*)immediate->immediate
+					== *(uint16_t*)immediate->var)
+				return;
+			break;
+		default:return;
+	}
+	memcpy((void*)immediate->immediate, (void*)immediate->var,
+			immediate->size);
+	flush_icache_range((unsigned long)immediate->immediate,
+				immediate->size);
+}
+

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68

  parent reply	other threads:[~2007-07-14  1:30 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-07-14  1:24 [patch 0/8] Immediates Values (real variables) Mathieu Desnoyers
2007-07-14  1:24 ` [patch 1/8] Immediate values - Global modules list and module mutex Mathieu Desnoyers
2007-07-14  1:24 ` [patch 2/8] Immediate Value - Architecture Independent Code Mathieu Desnoyers
2007-07-14 16:24   ` Christoph Hellwig
2007-07-14 22:59   ` [PATCH] Immediate Values - Architecture Independent Code - Fixes following HCH comments Mathieu Desnoyers
2007-07-15  1:36     ` [PATCH] Immediate Values - Architecture Independent Code - kerneldoc Mathieu Desnoyers
2007-07-15 23:40       ` [PATCH] Immediate Values - Architecture Independent Code - kerneldoc for implementation Mathieu Desnoyers
2007-07-14 23:52   ` [PATCH] Immediate Value - Architecture Independent Code Deferred Sync Mathieu Desnoyers
2007-07-15  1:32     ` Mathieu Desnoyers
2007-07-14  1:24 ` [patch 3/8] Immediate Values - Non Optimized Architectures Mathieu Desnoyers
2007-07-14 23:01   ` Mathieu Desnoyers
2007-07-14  1:24 ` [patch 4/8] Immediate Value - Add kconfig menus Mathieu Desnoyers
2007-07-14  7:28   ` Alexey Dobriyan
2007-07-14 15:27     ` Mathieu Desnoyers
2007-07-16  0:33       ` Andi Kleen
2007-07-16  0:41         ` Mathieu Desnoyers
2007-07-16  0:32   ` Mathieu Desnoyers
2007-07-16  0:34   ` [PATCH] Immediate Value - Kconfig menu in EMBEDDED Mathieu Desnoyers
2007-07-14  1:24 ` [patch 5/8] Immediate Values - kprobe header fix Mathieu Desnoyers
2007-07-14 16:26   ` Christoph Hellwig
2007-07-14 23:01   ` Mathieu Desnoyers
2007-07-14 23:04   ` [PATCH] Immediate Values - Move Kprobes i386 restore_interrupt to kdebug.h Mathieu Desnoyers
2007-07-14  1:24 ` [patch 6/8] Immediate Value - i386 Optimization Mathieu Desnoyers
2007-07-14 23:08   ` [PATCH] Immediate Values - Pre Fix " Mathieu Desnoyers
2007-07-15  1:37   ` [PATCH] Immediate Values - i386 Optimization - kerneldoc Mathieu Desnoyers
2007-07-15 23:41     ` [PATCH] Immediate Values - i386 Optimization - kerneldoc for implementation Mathieu Desnoyers
2007-07-14  1:24 ` Mathieu Desnoyers [this message]
2007-07-14 23:09   ` [PATCH] Immediate Values - Pre fix powerpc Optimization Mathieu Desnoyers
2007-07-15  1:38   ` [PATCH] Immediate Values - PowerPC Optimization - kerneldoc Mathieu Desnoyers
2007-07-15 23:42     ` [PATCH] Immediate Values - PowerPC Optimization - kerneldoc for implementation Mathieu Desnoyers
2007-07-14  1:24 ` [patch 8/8] Immediate Value - Documentation Mathieu Desnoyers

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=20070714012624.842959793@polymtl.ca \
    --to=mathieu.desnoyers@polymtl.ca \
    --cc=akpm@linux-foundation.org \
    --cc=linux-kernel@vger.kernel.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.