This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC][PATCH] Kprobes robust fault handling for i386


On Tue, Apr 25, 2006 at 10:21:43AM -0400, Frank Ch. Eigler wrote:
>
> Prasanna S Panchamukhi <prasanna@in.ibm.com> writes:
>
> > Please find the patch for robust fault handling of kprobes for i386
> > architecture. [...]
>
> This patch puts the setjmp into the kprobes layer, around the
> invocation of the probe handler.  A longjmp due to a systemtap probe
> problem would skip all the cleanup code (locking, error tracking,
> context cleanup) that the probe handler boilerplate includes.  I had
> previously imagined letting a probe handler include the setjmp
> explicitly, so it can have its own cleanup code in systemtap-emitted
> code.

IIUC you are planning on setjmp/longjmp() in systemtap generated
handlers themselves ?

This can be achieved even without the robust fault handling code.

>
> This scheme would mean that the subject processor will not be able to
> run any further systemtap probes, and probes on other processors will
> timeout acquiring locks on any shared variables.  This would cause the
> systemtap session to come to a prompt close due to MAXSKIPPED.
>
> There are problems associated with overall session shutdown.  The
> module removal code blocks until all running probe handler finish.
> But if it has no way of knowing that one was "stuck", it could wait a
> mighty long time.  This would likely have to be solved for the
> proposed scheme to be acceptable.
>

All that is required for systemtap pre/post handler is to allocate
a systemtap jump buffer and do a setjump() before accessing user
address space.

systemtap_jmp_buffer[]; <percpu data>

systemtap_prehandler(.....)
{
	.........
	if ((setjmp(systemtap_jmp_buffer)) != 0) {
		/* came here because of longjmp() */
		<cleanup code>
	}
	copy_from_user_inatomic(.....);
}

If such a access to user address space generates a page_fault, then
the kprobes_fault_handler() will execute the registered
systemtap_faulthandler(). The systemtap_faulthandler() is required to
change the instruction pointer to a routine that does the longjmp()
(systemtap_fault_trampoline() for example as shown below) and return
one from the systemtap_faulthandler(). The kprobes_fault_handler() just
returns without doing anything.

systemtap_faulthandler(....)
{
	regs->eip = (unsigned long) systemtap_fault_trampoline;
	return 1; /*kprobe handler need not do anything else */
}

Since the instruction pointer is changed, the system page_fault handler
will return to the systemtap longjmp() code(i.e.
systemtap_fault_trampoline()). The systemtap longjmp() will jump back
to the systemtap pre/post handler, since now systemtap knows
that fault has happened during the pre/post handler, it can do the
recovery or cleanup. After the recovery or cleanup is done, the
systemtap_prehandler() just returns.

systemtap_fault_trampoline(void)
{
	/* goto systemtap-prehandler() */
	longjmp(systemtap_jmp_buffer);
	return;
}

The robust fault handling patch will be helpful if the kprobe
user pre/post handlers or systemtap handlers does not do the
setjmp/longjmp() explicitly (non-systemtap kprobe users).

Thanks
Prasanna
-- 
Prasanna S Panchamukhi
Linux Technology Center
India Software Labs, IBM Bangalore
Email: prasanna@in.ibm.com
Ph: 91-80-51776329


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]