mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jesse Barnes <jbarnes@engr.sgi.com>
To: Andi Kleen <ak@muc.de>
Cc: "Chen, Kenneth W" <kenneth.w.chen@intel.com>,
	linux-kernel@vger.kernel.org, axboe@suse.de
Subject: Re: Direct io on block device has performance regression on 2.6.x kernel
Date: Wed, 9 Mar 2005 15:52:03 -0800	[thread overview]
Message-ID: <200503091552.04007.jbarnes@engr.sgi.com> (raw)
In-Reply-To: <m1r7iov1ya.fsf@muc.de>

[-- Attachment #1: Type: text/plain, Size: 884 bytes --]

On Wednesday, March 9, 2005 3:23 pm, Andi Kleen wrote:
> "Chen, Kenneth W" <kenneth.w.chen@intel.com> writes:
> > Just to clarify here, these data need to be taken at grain of salt. A
> > high count in _spin_unlock_* functions do not automatically points to
> > lock contention.  It's one of the blind spot syndrome with timer based
> > profile on ia64.  There are some lock contentions in 2.6 kernel that
> > we are staring at.  Please do not misinterpret the number here.
>
> Why don't you use oprofileÂ>? It uses NMIs and can profile "inside"
> interrupt disabled sections.

That was oprofile output, but on ia64, 'NMI's are maskable due to the way irq 
disabling works.  Here's a very hackish patch that changes the kernel to use 
cr.tpr instead of psr.i for interrupt control.  Making oprofile use real ia64 
NMIs is left as an exercise for the reader :)

Jesse

[-- Attachment #2: nmi-enable-5.patch --]
[-- Type: text/plain, Size: 5807 bytes --]

===== arch/ia64/Kconfig.debug 1.2 vs edited =====
--- 1.2/arch/ia64/Kconfig.debug	2005-01-07 16:15:52 -08:00
+++ edited/arch/ia64/Kconfig.debug	2005-02-28 10:07:27 -08:00
@@ -56,6 +56,15 @@
 	  and restore instructions.  It's useful for tracking down spinlock
 	  problems, but slow!  If you're unsure, select N.
 
+config IA64_ALLOW_NMI
+	bool "Allow non-maskable interrupts"
+	help
+	  The normal ia64 irq enable/disable code prevents even non-maskable
+	  interrupts from occuring, which can be a problem for kernel
+	  debuggers, watchdogs, and profilers.  Say Y here if you're interested
+	  in NMIs and don't mind the small performance penalty this option
+	  imposes.
+
 config SYSVIPC_COMPAT
 	bool
 	depends on COMPAT && SYSVIPC
===== arch/ia64/kernel/head.S 1.31 vs edited =====
--- 1.31/arch/ia64/kernel/head.S	2005-01-28 15:50:13 -08:00
+++ edited/arch/ia64/kernel/head.S	2005-03-01 13:17:51 -08:00
@@ -59,6 +59,14 @@
 	.save rp, r0		// terminate unwind chain with a NULL rp
 	.body
 
+#ifdef CONFIG_IA64_ALLOW_NMI	// disable interrupts initially (re-enabled in start_kernel())
+	mov r16=1<<16
+	;;
+	mov cr.tpr=r16
+	;;
+	srlz.d
+	;;
+#endif
 	rsm psr.i | psr.ic
 	;;
 	srlz.i
@@ -129,8 +137,8 @@
 	/*
 	 * Switch into virtual mode:
 	 */
-	movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \
-		  |IA64_PSR_DI)
+	movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_I|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|\
+		  IA64_PSR_BN|IA64_PSR_DI)
 	;;
 	mov cr.ipsr=r16
 	movl r17=1f
===== arch/ia64/kernel/irq_ia64.c 1.25 vs edited =====
--- 1.25/arch/ia64/kernel/irq_ia64.c	2005-01-22 15:54:49 -08:00
+++ edited/arch/ia64/kernel/irq_ia64.c	2005-03-01 12:50:18 -08:00
@@ -103,8 +103,6 @@
 void
 ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
 {
-	unsigned long saved_tpr;
-
 #if IRQ_DEBUG
 	{
 		unsigned long bsp, sp;
@@ -135,17 +133,9 @@
 	}
 #endif /* IRQ_DEBUG */
 
-	/*
-	 * Always set TPR to limit maximum interrupt nesting depth to
-	 * 16 (without this, it would be ~240, which could easily lead
-	 * to kernel stack overflows).
-	 */
 	irq_enter();
-	saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
-	ia64_srlz_d();
 	while (vector != IA64_SPURIOUS_INT_VECTOR) {
 		if (!IS_RESCHEDULE(vector)) {
-			ia64_setreg(_IA64_REG_CR_TPR, vector);
 			ia64_srlz_d();
 
 			__do_IRQ(local_vector_to_irq(vector), regs);
@@ -154,7 +144,6 @@
 			 * Disable interrupts and send EOI:
 			 */
 			local_irq_disable();
-			ia64_setreg(_IA64_REG_CR_TPR, saved_tpr);
 		}
 		ia64_eoi();
 		vector = ia64_get_ivr();
@@ -165,6 +154,7 @@
 	 * come through until ia64_eoi() has been done.
 	 */
 	irq_exit();
+	local_irq_enable();
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
===== include/asm-ia64/hw_irq.h 1.15 vs edited =====
--- 1.15/include/asm-ia64/hw_irq.h	2005-01-22 15:54:52 -08:00
+++ edited/include/asm-ia64/hw_irq.h	2005-03-01 13:01:03 -08:00
@@ -36,6 +36,10 @@
 
 #define AUTO_ASSIGN			-1
 
+#define IA64_NMI_VECTOR			0x02	/* NMI (note that this can be
+						   masked if psr.i or psr.ic
+						   are cleared) */
+
 #define IA64_SPURIOUS_INT_VECTOR	0x0f
 
 /*
===== include/asm-ia64/system.h 1.48 vs edited =====
--- 1.48/include/asm-ia64/system.h	2005-01-04 18:48:18 -08:00
+++ edited/include/asm-ia64/system.h	2005-03-01 15:28:23 -08:00
@@ -107,12 +107,61 @@
 
 #define safe_halt()         ia64_pal_halt_light()    /* PAL_HALT_LIGHT */
 
+/* For spinlocks etc */
+#ifdef CONFIG_IA64_ALLOW_NMI
+
+#define IA64_TPR_MMI_BIT (1<<16)
+
+#define __local_irq_save(x)			\
+do {						\
+	(x) = ia64_getreg(_IA64_REG_CR_TPR);	\
+	ia64_stop();				\
+	ia64_setreg(_IA64_REG_CR_TPR, IA64_TPR_MMI_BIT);	\
+	ia64_stop();				\
+	ia64_srlz_d();				\
+} while (0)
+
+static inline void __local_irq_disable(void)
+{
+	u64 __tpr;
+
+	__tpr = ia64_getreg(_IA64_REG_CR_TPR);
+	ia64_stop();
+	ia64_setreg(_IA64_REG_CR_TPR, IA64_TPR_MMI_BIT);
+	ia64_stop();
+	ia64_srlz_d();
+}
+
+static inline void __local_irq_restore(unsigned long flags)
+{
+	ia64_setreg(_IA64_REG_CR_TPR, flags);
+	ia64_stop();
+	ia64_srlz_d();
+}
+
+static inline void local_irq_enable(void)
+{
+	ia64_setreg(_IA64_REG_CR_TPR, 0);
+ 	ia64_srlz_d();
+	ia64_ssm(IA64_PSR_I); ia64_srlz_d();
+}
+
+#define local_save_flags(flags)	((flags) = ia64_getreg(_IA64_REG_CR_TPR))
+
+static inline int irqs_disabled(void)
+{
+	unsigned long __ia64_id_flags;
+	local_save_flags(__ia64_id_flags);
+	return __ia64_id_flags & IA64_TPR_MMI_BIT;
+}
+
+#else /* !CONFIG_IA64_ALLOW_NMI */
+
 /*
  * The group barrier in front of the rsm & ssm are necessary to ensure
  * that none of the previous instructions in the same group are
  * affected by the rsm/ssm.
  */
-/* For spinlocks etc */
 
 /*
  * - clearing psr.i is implicitly serialized (visible by next insn)
@@ -137,6 +186,19 @@
 
 #define __local_irq_restore(x)	ia64_intrin_local_irq_restore((x) & IA64_PSR_I)
 
+#define local_irq_enable()	({ ia64_ssm(IA64_PSR_I); ia64_srlz_d(); })
+#define local_save_flags(flags)	((flags) = ia64_getreg(_IA64_REG_PSR))
+
+#define irqs_disabled()				\
+({						\
+	unsigned long __ia64_id_flags;		\
+	local_save_flags(__ia64_id_flags);	\
+	(__ia64_id_flags & IA64_PSR_I) == 0;	\
+})
+
+#endif /* CONFIG_IA64_ALLOW_NMI */
+
+/* FIXME: need to change for ALLOW_NMI */
 #ifdef CONFIG_IA64_DEBUG_IRQ
 
   extern unsigned long last_cli_ip;
@@ -170,16 +232,6 @@
 # define local_irq_disable()	__local_irq_disable()
 # define local_irq_restore(x)	__local_irq_restore(x)
 #endif /* !CONFIG_IA64_DEBUG_IRQ */
-
-#define local_irq_enable()	({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); })
-#define local_save_flags(flags)	({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); })
-
-#define irqs_disabled()				\
-({						\
-	unsigned long __ia64_id_flags;		\
-	local_save_flags(__ia64_id_flags);	\
-	(__ia64_id_flags & IA64_PSR_I) == 0;	\
-})
 
 #ifdef __KERNEL__
 

  reply	other threads:[~2005-03-10  4:39 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-03-09 22:18 Chen, Kenneth W
2005-03-09 23:23 ` Andi Kleen
2005-03-09 23:52   ` Jesse Barnes [this message]
2005-03-09 23:52   ` Jesse Barnes
2005-03-10  1:00     ` Chen, Kenneth W
2005-03-10  0:57   ` Chen, Kenneth W
  -- strict thread matches above, loose matches on Subject: below --
2005-03-10  2:04 Chen, Kenneth W
2005-03-10  1:24 Chen, Kenneth W
2005-03-09  1:53 Chen, Kenneth W
2005-03-09  1:39 Chen, Kenneth W
2005-03-09  6:27 ` Andrew Morton
2005-03-09 17:21   ` Chen, Kenneth W
2005-03-09 20:04     ` Andrew Morton
2005-03-09 21:59       ` Chen, Kenneth W
2005-03-09 22:44         ` Andrew Morton
2005-03-10  1:11           ` Chen, Kenneth W
2005-03-10  1:33             ` Andrew Morton
2005-03-10  1:44               ` Chen, Kenneth W
2005-03-10  2:25     ` Andrew Morton
2005-03-10  3:47       ` Chen, Kenneth W
2005-03-10  4:04         ` David Lang
2005-03-10  4:10           ` Andrew Morton
2005-03-10  4:09         ` Andrew Morton
2005-03-10 18:31           ` Chen, Kenneth W
2005-03-10 20:30             ` Andrew Morton
2005-03-10 21:42               ` Chen, Kenneth W
2005-03-10 22:01                 ` Andrew Morton
2005-03-10  4:28         ` Andrew Vasquez

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=200503091552.04007.jbarnes@engr.sgi.com \
    --to=jbarnes@engr.sgi.com \
    --cc=ak@muc.de \
    --cc=axboe@suse.de \
    --cc=kenneth.w.chen@intel.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®