mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH][2.6.10-rc1-mm4][3/4] perfctr x86 driver updates
@ 2004-11-11  9:37 Mikael Pettersson
  2004-11-15  1:09 ` Rusty Russell
  0 siblings, 1 reply; 3+ messages in thread
From: Mikael Pettersson @ 2004-11-11  9:37 UTC (permalink / raw)
  To: akpm; +Cc: linux-kernel

Part 3/4 of the perfctr interrupt fixes:
- Add facility for masking perfctr interrupts. To reduce
  overheads, this is done in software via a per-cpu mask
  instead of writing to the local APIC.
- Mask interrupts when interrupt-mode counters are suspended,
  and unmask when they are resumed. Prevents delayed interrupts
  (due to HW quirk) from being delivered to the wrong tasks.
- Suspend path records if any interrupt-mode counters are
  in overflow state. This informs the higher levels that a
  pending interrupt (now masked) must be simulated.

Signed-off-by: Mikael Pettersson <mikpe@csd.uu.se>

 drivers/perfctr/x86.c      |   22 ++++++++++++++++++++++
 include/asm-i386/perfctr.h |    3 +++
 2 files changed, 25 insertions(+)

diff -rupN linux-2.6.10-rc1-mm4/drivers/perfctr/x86.c linux-2.6.10-rc1-mm4.perfctr-x86-driver-update/drivers/perfctr/x86.c
--- linux-2.6.10-rc1-mm4/drivers/perfctr/x86.c	2004-11-10 18:02:56.000000000 +0100
+++ linux-2.6.10-rc1-mm4.perfctr-x86-driver-update/drivers/perfctr/x86.c	2004-11-11 00:26:46.000000000 +0100
@@ -34,6 +34,9 @@ struct per_cpu_cache {	/* roughly a subs
 		unsigned int pebs_enable;
 		unsigned int pebs_matrix_vert;
 	} control;
+#ifdef CONFIG_PERFCTR_INTERRUPT_SUPPORT
+	unsigned int interrupts_masked;
+#endif
 } ____cacheline_aligned;
 static DEFINE_PER_CPU(struct per_cpu_cache, per_cpu_cache);
 #define __get_cpu_cache(cpu) (&per_cpu(per_cpu_cache, cpu))
@@ -155,6 +158,8 @@ asmlinkage void smp_perfctr_interrupt(st
 	   masks interrupts. We're still on the originating CPU. */
 	/* XXX: recursive interrupts? delay the ACK, mask LVTPC, or queue? */
 	ack_APIC_irq();
+	if (get_cpu_cache()->interrupts_masked)
+		return;
 	irq_enter();
 	(*perfctr_ihandler)(instruction_pointer(regs));
 	irq_exit();
@@ -165,6 +170,16 @@ void perfctr_cpu_set_ihandler(perfctr_ih
 	perfctr_ihandler = ihandler ? ihandler : perfctr_default_ihandler;
 }
 
+static inline void perfctr_cpu_mask_interrupts(struct per_cpu_cache *cache)
+{
+	cache->interrupts_masked = 1;
+}
+
+static inline void perfctr_cpu_unmask_interrupts(struct per_cpu_cache *cache)
+{
+	cache->interrupts_masked = 0;
+}
+
 #else
 #define perfctr_cstatus_has_ictrs(cstatus)	0
 #undef cpu_has_apic
@@ -452,10 +467,12 @@ static void p6_like_isuspend(struct perf
 	struct per_cpu_cache *cache;
 	unsigned int cstatus, nrctrs, i;
 	int cpu;
+	unsigned int pending = 0;
 
 	cpu = smp_processor_id();
 	set_isuspend_cpu(state, cpu); /* early to limit cpu's live range */
 	cache = __get_cpu_cache(cpu);
+	perfctr_cpu_mask_interrupts(cache);
 	cstatus = state->cstatus;
 	nrctrs = perfctr_cstatus_nrctrs(cstatus);
 	for(i = perfctr_cstatus_nractrs(cstatus); i < nrctrs; ++i) {
@@ -471,7 +488,10 @@ static void p6_like_isuspend(struct perf
 		rdpmc_low(pmc_raw, now);
 		state->pmc[i].sum += now - state->pmc[i].start;
 		state->pmc[i].start = now;
+		if ((int)now >= 0)
+			++pending;
 	}
+	state->pending_interrupt = pending;
 	/* cache->k1.id is still == state->k1.id */
 }
 
@@ -487,6 +507,7 @@ static void p6_like_iresume(const struct
 
 	cpu = smp_processor_id();
 	cache = __get_cpu_cache(cpu);
+	perfctr_cpu_unmask_interrupts(cache);
 	if (cache->k1.id == state->k1.id) {
 		cache->k1.id = 0; /* force reload of cleared EVNTSELs */
 		if (is_isuspend_cpu(state, cpu))
@@ -979,6 +1000,7 @@ unsigned int perfctr_cpu_identify_overfl
 	pmc = perfctr_cstatus_nractrs(cstatus);
 	nrctrs = perfctr_cstatus_nrctrs(cstatus);
 
+	state->pending_interrupt = 0;
 	for(pmc_mask = 0; pmc < nrctrs; ++pmc) {
 		if ((int)state->pmc[pmc].start >= 0) { /* XXX: ">" ? */
 			/* XXX: "+=" to correct for overshots */
diff -rupN linux-2.6.10-rc1-mm4/include/asm-i386/perfctr.h linux-2.6.10-rc1-mm4.perfctr-x86-driver-update/include/asm-i386/perfctr.h
--- linux-2.6.10-rc1-mm4/include/asm-i386/perfctr.h	2004-11-10 18:03:00.000000000 +0100
+++ linux-2.6.10-rc1-mm4.perfctr-x86-driver-update/include/asm-i386/perfctr.h	2004-11-11 00:26:58.000000000 +0100
@@ -66,6 +66,9 @@ struct perfctr_cpu_state {
 #ifdef __KERNEL__
 	struct perfctr_cpu_control control;
 	unsigned int p4_escr_map[18];
+#ifdef CONFIG_PERFCTR_INTERRUPT_SUPPORT
+	unsigned int pending_interrupt;
+#endif
 #endif
 };
 

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

* Re: [PATCH][2.6.10-rc1-mm4][3/4] perfctr x86 driver updates
  2004-11-11  9:37 [PATCH][2.6.10-rc1-mm4][3/4] perfctr x86 driver updates Mikael Pettersson
@ 2004-11-15  1:09 ` Rusty Russell
  2004-11-15  9:18   ` Mikael Pettersson
  0 siblings, 1 reply; 3+ messages in thread
From: Rusty Russell @ 2004-11-15  1:09 UTC (permalink / raw)
  To: Mikael Pettersson; +Cc: Andrew Morton, lkml - Kernel Mailing List

On Thu, 2004-11-11 at 10:37 +0100, Mikael Pettersson wrote:
> Part 3/4 of the perfctr interrupt fixes:
...
>  	} control;
> +#ifdef CONFIG_PERFCTR_INTERRUPT_SUPPORT
> +	unsigned int interrupts_masked;
> +#endif
>  } ____cacheline_aligned;
>  static DEFINE_PER_CPU(struct per_cpu_cache, per_cpu_cache);

While you're here, does this really have to be cacheline aligned?  I
wouldn't think so, since it's in the per-cpu section anyway.

Rusty.
-- 
A bad analogy is like a leaky screwdriver -- Richard Braakman


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

* Re: [PATCH][2.6.10-rc1-mm4][3/4] perfctr x86 driver updates
  2004-11-15  1:09 ` Rusty Russell
@ 2004-11-15  9:18   ` Mikael Pettersson
  0 siblings, 0 replies; 3+ messages in thread
From: Mikael Pettersson @ 2004-11-15  9:18 UTC (permalink / raw)
  To: Rusty Russell; +Cc: Andrew Morton, lkml - Kernel Mailing List

Rusty Russell writes:
 > On Thu, 2004-11-11 at 10:37 +0100, Mikael Pettersson wrote:
 > > Part 3/4 of the perfctr interrupt fixes:
 > ...
 > >  	} control;
 > > +#ifdef CONFIG_PERFCTR_INTERRUPT_SUPPORT
 > > +	unsigned int interrupts_masked;
 > > +#endif
 > >  } ____cacheline_aligned;
 > >  static DEFINE_PER_CPU(struct per_cpu_cache, per_cpu_cache);
 > 
 > While you're here, does this really have to be cacheline aligned?  I
 > wouldn't think so, since it's in the per-cpu section anyway.

The ____cacheline_aligned is a left-over from the [NR_CPUS] days;
it's probably not needed any more. I'll submit a patch to delete
it and also move the interrupts_masked field nearer the head of the
struct (to reduce # of cache lines touched in the common case).

/Mikael

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

end of thread, other threads:[~2004-11-15  9:22 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-11-11  9:37 [PATCH][2.6.10-rc1-mm4][3/4] perfctr x86 driver updates Mikael Pettersson
2004-11-15  1:09 ` Rusty Russell
2004-11-15  9:18   ` Mikael Pettersson

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