This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: [RFC][PATCH] Kprobes robust fault handling for i386
- From: Prasanna S Panchamukhi <prasanna at in dot ibm dot com>
- To: "Frank Ch. Eigler" <fche at redhat dot com>
- Cc: systemtap at sources dot redhat dot com
- Date: Wed, 26 Apr 2006 12:17:37 +0530
- Subject: Re: [RFC][PATCH] Kprobes robust fault handling for i386
- References: <20060425082244.GB10088@in.ibm.com> <y0mejzlag7c.fsf@ton.toronto.redhat.com>
- Reply-to: prasanna at in dot ibm dot com
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