login
Header Space

 
 

Re: [RFC] mmiotrace full patch, preview 1

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: Jonathan Corbet <corbet@...>
Cc: Ingo Molnar <mingo@...>, Christoph Hellwig <hch@...>, Arjan van de Ven <arjan@...>, Pavel Roskin <proski@...>, Steven Rostedt <rostedt@...>, Peter Zijlstra <a.p.zijlstra@...>, <linux-kernel@...>, Andrew Morton <akpm@...>, <pq@...>
Date: Wednesday, February 27, 2008 - 4:28 pm

On Tue, 26 Feb 2008 10:20:08 -0700
corbet@lwn.net (Jonathan Corbet) wrote:


The last thing in kmmio.c is:

static int kmmio_die_notifier(struct notifier_block *nb, unsigned long val,
								void *args)
{
	struct die_args *arg = args;

	if (val == DIE_DEBUG)
		if (post_kmmio_handler(arg->err, arg->regs) == 1)
			return NOTIFY_STOP;

	return NOTIFY_DONE;
}

so post_kmmio_handler() is not the die_notifier callback, and the handler
is limited to debug calls, which I assume can only come from
single-stepping. The variable 'condition' is something that on x86_64 comes
from get_debugreg(condition, 6); in arch/x86/kernel/traps_64.c do_debug().
I don't know what 'condition' is and kmmio is not using it.


True. I am assuming ioremap*() cannot return regions that overlap in
their kernel virtual addresses. Clearly this does not hold for the ISA
region, but tracing the ISA region has triggered hard freezes, so we
specifically exclude that.

Even if ioremap*() would return overlapping areas, I don't think it would
break things. It just means there are two probes on the same area. If an
MMIO access hits that area, the "first" probe gets selected and executed.
The only thing lost is which probe was actually hit, but then there's no
way to know that, anyway.

kmmio_fault_page objects are shared and reference-counted, so they should
not be a problem, either.


Yes, good catch. Then again, maybe I would not even need the failure case
at all. I think I'll keep it there, though, maybe it catches something
stupid I will do.


I have thought of something like this, how could it happen. My current
understanding is the following.

kmmio_handler(), where-ever it was triggered, executes with interrupts
disabled. It modifies the saved CPU state: disable interrupts and
enable single-stepping (what's the correct term?). After disarming
the page, it returns. The faulted instruction is single-stepped,
all the time the interrupts are disabled. It hits the debug trap and
we end up in post_kmmio_handler(), still interrupts disabled. The
post handler does its thing, restores the CPU state changed in
kmmio_handler(), and returns.

Therefore, on this CPU, no interrupt except NMI may occur during the
handling of a probe hit. Of course, I am assuming the execution
flow will stay on this CPU, but there's no chance it could jump to
a different CPU, is there?

Which leads to the question, is preempt_disable() in kmmio_handler()
and the respective preempt_enable_no_resched() in post_kmmio_handler()
required, or does disabling interrupts guarantee that?

And also, the following code is probably useless in post_kmmio_handler()
because of the interrupts being disabled all the time:

	faultpage = get_kmmio_fault_page(ctx->addr);
	probe = get_kmmio_probe(ctx->addr);
	if (faultpage != ctx->fpage || probe != ctx->probe) {
		/*
		 * The trace setup changed after kmmio_handler() and before
		 * running this respective post handler. User does not want
		 * the result anymore.
		 */
		ctx->probe = NULL;
		ctx->fpage = NULL;
	}

For the if to trigger, the probe list or the kmmio_fault_page list
would have to change during a probe hit or the single-stepping. The
lists are protected by RCU, so this is impossible. Hmm, no, wait.
The lists could be modified, but the pointers would still stay valid
because RCU has not had a chance run the freeing function. OTOH,
rcu_read_lock() is not held over single-stepping.

Maybe I should replace the preempt_disable() with rcu_read_lock()
that would be held over single-stepping?

Are there any locks or anything I should *not* hold over the single-
stepping, i.e., lock in kmmio_handler() and unlock only in
post_kmmio_handler()?

Is there any way post_kmmio_handler() would not get called after
kmmio_handler() was called?

You might get the impression that I don't know what I'm doing. You
would be correct! ;-)


Thanks, I appreciate all feedback.

-- 
Pekka Paalanen
http://www.iki.fi/pq/
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[RFC] mmiotrace full patch, preview 1, Pekka Paalanen, (Sun Feb 24, 1:03 pm)
Re: [RFC] mmiotrace full patch, preview 1 , Jonathan Corbet, (Tue Feb 26, 1:20 pm)
Re: [RFC] mmiotrace full patch, preview 1, Pekka Paalanen, (Wed Feb 27, 4:28 pm)
Re: [RFC] mmiotrace full patch, preview 1, Andrew Morton, (Mon Feb 25, 6:49 pm)
Re: [RFC] mmiotrace full patch, preview 1, Pekka Paalanen, (Tue Feb 26, 4:02 pm)
Re: [RFC] mmiotrace full patch, preview 1, Christoph Hellwig, (Mon Feb 25, 7:34 pm)
Re: [RFC] mmiotrace full patch, preview 1, Andy Whitcroft, (Tue Feb 26, 6:21 am)
Re: [RFC] mmiotrace full patch, preview 1, Ingo Molnar, (Tue Feb 26, 6:49 am)
Re: [RFC] mmiotrace full patch, preview 1, Andy Whitcroft, (Tue Feb 26, 11:20 am)
Re: [RFC] mmiotrace full patch, preview 1, Pavel Roskin, (Mon Feb 25, 10:42 pm)
Re: [RFC] mmiotrace full patch, preview 1, Christoph Hellwig, (Tue Feb 26, 1:10 pm)
Re: [RFC] mmiotrace full patch, preview 1, Andy Whitcroft, (Tue Feb 26, 4:57 am)
Re: [RFC] mmiotrace full patch, preview 1, Sam Ravnborg, (Sun Feb 24, 1:59 pm)
speck-geostationary